From: Larry Clapp
Subject: Factory methods: putting an :around on make-instance, or not?
Date: 
Message-ID: <slrncpcq20.krm.larry@theclapp.ddts.net>
Factory methods: define an :around on make-instance, or define a
make-foo?

  (defclass foo () ())
  (defclass foo-a (foo) ())
  (defclass foo-b (foo) ())

  (defmethod make-instance :around ((class (eql (find-class 'foo))) 
			    &rest initargs &key arg &allow-other-keys)
    (declare (ignore initargs))
    (case arg
      (a (make-instance 'foo-a))
      (b (make-instance 'foo-b))))

  (make-instance 'foo :arg 'a)
  (make-instance 'foo :arg 'b)

Usage:

  CL-USER> (make-instance 'foo :arg 'a)
  #<FOO-A {5871042D}>

  CL-USER> (make-instance 'foo :arg 'b)
  #<FOO-B {58731465}>

Whatcha think?

-- Larry

From: Rahul Jain
Subject: Re: Factory methods: putting an :around on make-instance, or not?
Date: 
Message-ID: <87wtwppcii.fsf@nyct.net>
Larry Clapp <·····@theclapp.org> writes:

>   CL-USER> (make-instance 'foo :arg 'a)
>   #<FOO-A {5871042D}>
>
>   CL-USER> (make-instance 'foo :arg 'b)
>   #<FOO-B {58731465}>

You already have the "factory pattern": MAKE-INSTANCE.

(make-instance 'foo-a)

or (make-instance (get-foo-class-for 'a))

-- 
Rahul Jain
·····@nyct.net
Professional Software Developer, Amateur Quantum Mechanicist
From: Larry Clapp
Subject: Re: Factory methods: putting an :around on make-instance, or not?
Date: 
Message-ID: <slrncpeps9.js8.larry@theclapp.ddts.net>
In article <··············@nyct.net>, Rahul Jain wrote:
> Larry Clapp <·····@theclapp.org> writes:
>>   CL-USER> (make-instance 'foo :arg 'a)
>>   #<FOO-A {5871042D}>
>>
>>   CL-USER> (make-instance 'foo :arg 'b)
>>   #<FOO-B {58731465}>
> 
> You already have the "factory pattern": MAKE-INSTANCE.
> 
> (make-instance 'foo-a)
> 
> or (make-instance (get-foo-class-for 'a))

Well, the former doesn't return a subclass of FOO based on the
initialization parameters.  The latter could ... but it seems like it
could easily baloon into

  (make-instance (get-foo-class-for :various 'other :arguments 'and :so 'on)
    :various 'other :arguments 'and :so 'on)

which looks so icky that I'd want to build a function around it, and
then, viola, I have a factory method anyway.  :)

-- Larry
From: Pascal Bourguignon
Subject: Re: Factory methods: putting an :around on make-instance, or not?
Date: 
Message-ID: <87is88pkbc.fsf@thalassa.informatimago.com>
Larry Clapp <·····@theclapp.org> writes:
> which looks so icky that I'd want to build a function around it, and
> then, viola, I have a factory method anyway.  :)
        raped?

-- 
__Pascal Bourguignon__                     http://www.informatimago.com/
The world will now reboot; don't bother saving your artefacts.
From: Larry Clapp
Subject: Re: Factory methods: putting an :around on make-instance, or not?
Date: 
Message-ID: <slrncpf493.js8.larry@theclapp.ddts.net>
In article <··············@thalassa.informatimago.com>, Pascal
Bourguignon wrote:
> Larry Clapp <·····@theclapp.org> writes:
>> which looks so icky that I'd want to build a function around it, and
>> then, viola, I have a factory method anyway.  :)
>        raped?

:)  Sorry, typo.  "Voila".

From m-w.com:
  Main Entry: voi�l� 
  Variant(s): or voi�la  /vw�-'l�/
  Function: interjection
  Etymology: French, literally, see there
  -- used to call attention, to express satisfaction or approval, or
  to suggest an appearance as if by magic
From: Thomas Schilling
Subject: Re: Factory methods: putting an :around on make-instance, or not?
Date: 
Message-ID: <opshg9yqts1gy3cn@news.cis.dfn.de>
Am 14 Nov 2004 15:38:31 +0100 schrieb Pascal Bourguignon  
<····@mouse-potato.com>:

> Larry Clapp <·····@theclapp.org> writes:
>> which looks so icky that I'd want to build a function around it, and
>> then, viola, I have a factory method anyway.  :)
>         raped?

For those wondering:  
http://groups.google.de/groups?hl=de&lr=&selm=873c4dc7u8.fsf%40thalassa.informatimago.com
From: Larry Clapp
Subject: Re: Factory methods: putting an :around on make-instance, or not?
Date: 
Message-ID: <slrncpd6tv.js8.larry@theclapp.ddts.net>
In article <····················@theclapp.ddts.net>, I wrote:
> Factory methods: define an :around on make-instance, or define a
> make-foo?
> 
>   (defclass foo () ())
>   (defclass foo-a (foo) ())
>   (defclass foo-b (foo) ())
> 
>   (defmethod make-instance :around ((class (eql (find-class 'foo))) 
> 			    &rest initargs &key arg &allow-other-keys)
>     (declare (ignore initargs))
>     (case arg
>       (a (make-instance 'foo-a))
>       (b (make-instance 'foo-b))))
> 
>   (make-instance 'foo :arg 'a)
>   (make-instance 'foo :arg 'b)

Okay, so I Googled some more, and found a thread starting here[1]
which argued that this is illegal: "Defining a method for a
standardized generic function which is applicable when all of the
arguments are direct instances of standardized classes [is prohibited
in 11.1.2.1.2]."

So, I could make FOO something other than a standard class[2], but I
wonder if I really have to.  11.1.2.1.2 starts out with "Except where
explicitly allowed ...".  7.1 says "In addition, make-instance is
itself a generic function and thus also can be customized", and 7.1.7
says "Customizing at the Programmer Interface level includes [...]
defining methods for make-instance, allocate-instance, and
initialize-instance. [...] The meta-object level supports additional
customization."

7.1 and 7.1.7 both appear to explicitly allow defining methods on
make-instance.

On the third hand, the glossary entry for "direct instance" has an
example usage:  "The function make-instance always returns a direct
instance of the class which is (or is named by) its first argument",
which seems to at least frown on using MAKE-INSTANCE as a factory
method (in this way).

What do you think?  A tempest in a tea-put?  Just use MAKE-FOO?

-- Larry

[1] ··························································@newsreader2.netcologne.de

[2] I could say

  (defclass has-factory (standard-class) ())
  (defmacro defclass-with-factory (&rest rest)
    `(defclass ,@rest (:metaclass has-factory)))
  (defclass-with-factory foo () ())
  (defclass-with-factory foo-a (foo) ())
  (defclass-with-factory foo-b (foo) ())

but then (in CMUCL, at least) I have to define a method on the MOP
generic-function PCL:VALIDATE-SUPERCLASS to allow me to actually
instantiate a FOO:

  (defmethod pcl:validate-superclass ((class has-factory)
				      (superclass standard-class))
    t)

  (make-instance 'foo :arg 'a)
  => #<FOO-A {58917655}>
From: Tim Bradshaw
Subject: Re: Factory methods: putting an :around on make-instance, or not?
Date: 
Message-ID: <1100519594.555948.162520@f14g2000cwb.googlegroups.com>
Larry Clapp wrote:
> Factory methods: define an :around on make-instance, or define a
> make-foo?
>

(make-instance 'foo) should return an instance of FOO I think:

(eq (class-of (make-instance 'foo)) (find-class 'foo))

should be T.  I don't know if the spec says this (probably not), but
not doing it is, well, horrible.  So, yes, define a different
function.  I often call mine either MAKE-x-FOR or FIND-x-FOR, where x
is the conceptual kind of thing I'm thinking of, and the difference is
that the FIND function may not return a fresh x.

--tim