From: Rolf Wester
Subject: Are there "constructors" in CLOS?
Date: 
Message-ID: <3A2E75AD.AD48E13A@ilt.fhg.de>
Hi,

I'm just beginning to learn LISP and I want to write a little program
using
CLOS. Is there anything comparable to constructors in languages like
Java or C++?

I have a class optmat and a derived class lens. I want to initialize
A,B,C and D when
creating a lens object. My proposed solution is:

(defclass optmat ()
    ((A :reader getA :writer setA :initarg :A :initform 1.0)
     (B :reader getB :writer setB :initarg :B :initform 0.0)
     (C :reader getC :writer setC :initarg :C :initform 0.0)
     (D :reader getD :writer setD :initarg :D :initform 1.0)))

(defclass lens (optmat)
    ((F :reader getF :writer setF :initarg :F :initform 1.0e10)
     (O :reader getO :writer setO :initarg :O :initform 1.0)))

(defun make-lens (f &optional (O 1.0))
  (let ((mat (make-instance 'lens :F f :O O)))
 (setA 1.0 mat)
 (setB 0.0 mat)
 (setC (/ -1.0 f) mat)
 (setD 1.0 mat)
 (values mat)))

Is it possible to use (make-instance 'lens ...) directly and have the
slot-values of optmat
initialized?

Thanks.

--Rolf

From: Tim Bradshaw
Subject: Re: Are there "constructors" in CLOS?
Date: 
Message-ID: <nkjn1e94fsn.fsf@tfeb.org>
Rolf Wester <······@ilt.fhg.de> writes:

> 
> Is it possible to use (make-instance 'lens ...) directly and have the
> slot-values of optmat
> initialized?
> 

defining an AFTER method on INITIALIZE-INSTANCE is the CLOS equivalent
of a constructor:

(defmethod initialize-instance :after ((l lens) &key)
 ...)

--tim
From: Christopher J. Vogt
Subject: Re: Are there "constructors" in CLOS?
Date: 
Message-ID: <3A2E7ED5.D80F7328@computer.org>
Rolf Wester wrote:
> 
> Hi,
> 
> I'm just beginning to learn LISP and I want to write a little program
> using
> CLOS. Is there anything comparable to constructors in languages like
> Java or C++?
> 
> I have a class optmat and a derived class lens. I want to initialize
> A,B,C and D when
> creating a lens object. My proposed solution is:
> 
> (defclass optmat ()
>     ((A :reader getA :writer setA :initarg :A :initform 1.0)
>      (B :reader getB :writer setB :initarg :B :initform 0.0)
>      (C :reader getC :writer setC :initarg :C :initform 0.0)
>      (D :reader getD :writer setD :initarg :D :initform 1.0)))
> 
> (defclass lens (optmat)
>     ((F :reader getF :writer setF :initarg :F :initform 1.0e10)
>      (O :reader getO :writer setO :initarg :O :initform 1.0)))
> 
> (defun make-lens (f &optional (O 1.0))
>   (let ((mat (make-instance 'lens :F f :O O)))
>  (setA 1.0 mat)
>  (setB 0.0 mat)
>  (setC (/ -1.0 f) mat)
>  (setD 1.0 mat)
>  (values mat)))

(make-instance 'lens) will initialize all the slots to the values specified by :initform.  Similarly, since you have used :initarg,  you can initialize them to
something different like this: (make-instance 'lens :a -1 :b -2 :o 3)
From: Kent M Pitman
Subject: Re: Are there "constructors" in CLOS?
Date: 
Message-ID: <sfwn1e9s6j3.fsf@world.std.com>
"Christopher J. Vogt" <····@computer.org> writes:

> Rolf Wester wrote:

> > I'm just beginning to learn LISP and I want to write a little
> > program using CLOS. Is there anything comparable to constructors
> > in languages like Java or C++?

Not exactly.  In particular, contrasting it with Java, Java leaves it up
to you to call SUPER, and if you don't you end up not calling it, you can
lose badly.  Using before and after methods on INITIALIZE-INSTANCE, you
can basically assure that added setup is never not called.  (You probably
should read about method combination to understand this.)

> > I have a class optmat and a derived class lens. I want to initialize
> > A,B,C and D when creating a lens object. My proposed solution is:
> > 
> > (defclass optmat ()
> >     ((A :reader getA :writer setA :initarg :A :initform 1.0)
> >      (B :reader getB :writer setB :initarg :B :initform 0.0)
> >      (C :reader getC :writer setC :initarg :C :initform 0.0)
> >      (D :reader getD :writer setD :initarg :D :initform 1.0)))
> > 
> > (defclass lens (optmat)
> >     ((F :reader getF :writer setF :initarg :F :initform 1.0e10)
> >      (O :reader getO :writer setO :initarg :O :initform 1.0)))
> > 
> > (defun make-lens (f &optional (O 1.0))
> >   (let ((mat (make-instance 'lens :F f :O O)))
> >  (setA 1.0 mat)
> >  (setB 0.0 mat)
> >  (setC (/ -1.0 f) mat)
> >  (setD 1.0 mat)
> >  (values mat)))
> 
> (make-instance 'lens) will initialize all the slots to the values
> specified by :initform.  Similarly, since you have used :initarg,  
> you can initialize them to something different like this:
> (make-instance 'lens :a -1 :b -2 :o 3)

Only computed values can't be done this way.

Here are my proposed changes:
 
 1. Eliminate the readers and writers, in preference of :accessor,
    which allows you to read and set them more naturally.  That is,
       (setf (getA thing) val)
    rather than
       (setA val thing)

    Or pick better names that getA. e.g, the-a or a-value or even just
    a itself.  e.g.,  if it's an opacity, an accessor name like opacity
    is rather nice.

 2. Let A and B initialize themselves.  The setup in make-lens isn't helping.
    Use an after method on INITIALIZE-INSTANCE to notice values that need
    initialization and fix things.  You could either leave F unbound and
    then use SLOT-BOUNDP, or you could (as I usually do) just initialize
    it to NIL and let the after method test its falsity instead.

 3. Don't use VALUES unless you either plan to return multiple values,
    including zero values, as in (VALUES) or (VALUES x y), or else you
    want to mask out multiple values. e.g., (VALUES (FOO)) returns only
    (FOO)'s first value even if it returns more than one.  You have
    (VALUES MAT) in your code, but there is no difference between that and
    just MAT, since variables return only one value anyway.  The presence
    of the (VALUES ...) around MAT doesn't hurt things but is unnecessary
    and visually confusing.

I think this will work, though I didn't test it:

(defclass optmat ()
  ((A :accessor the-a :initarg :a :initform 1.0)
   (B :accessor the-b :initarg :b :initform 0.0)
   (C :accessor the-c :initarg :c :initform 0.0)
   (D :accessor the-d :initarg :d :initform 1.0)))

(defclass lens ()
  ((f :accessor the-f :initarg :f :initform nil)
   (o :accessor the-o :initarg :o :intiform 1.0)))

(defmethod instance-instance :after ((lens lens) &key)
  (unless f (setf (the-f lens) (/ -1.0 f))))

(defun make-lens (f &optional (o 1.0))
  (make-instance 'lens :f f :o o))

In some cases it makes sense to use constructors like this, but often
for such trivial constructors you ought to just let the caller use
MAKE-INSTANCE directly.  MAKE-LENS is mostly just getting in the way
of passing all the options to initialize LENS that you might want.
From: Marco Antoniotti
Subject: Re: Are there "constructors" in CLOS?
Date: 
Message-ID: <y6c8zpt3vq8.fsf@octagon.mrl.nyu.edu>
Kent M Pitman <······@world.std.com> writes:

> "Christopher J. Vogt" <····@computer.org> writes:
> 
> > Rolf Wester wrote:
> 
> > > I'm just beginning to learn LISP and I want to write a little
> > > program using CLOS. Is there anything comparable to constructors
> > > in languages like Java or C++?
> 
> Not exactly.  In particular, contrasting it with Java, Java leaves it up
> to you to call SUPER, and if you don't you end up not calling it, you can
> lose badly.  Using before and after methods on INITIALIZE-INSTANCE, you
> can basically assure that added setup is never not called.  (You probably
> should read about method combination to understand this.)
> 
> > > I have a class optmat and a derived class lens. I want to initialize
> > > A,B,C and D when creating a lens object. My proposed solution is:
> > > 
> > > (defclass optmat ()
> > >     ((A :reader getA :writer setA :initarg :A :initform 1.0)
> > >      (B :reader getB :writer setB :initarg :B :initform 0.0)
> > >      (C :reader getC :writer setC :initarg :C :initform 0.0)
> > >      (D :reader getD :writer setD :initarg :D :initform 1.0)))
> > > 
> > > (defclass lens (optmat)
> > >     ((F :reader getF :writer setF :initarg :F :initform 1.0e10)
> > >      (O :reader getO :writer setO :initarg :O :initform 1.0)))
> > > 
> > > (defun make-lens (f &optional (O 1.0))
> > >   (let ((mat (make-instance 'lens :F f :O O)))
> > >  (setA 1.0 mat)
> > >  (setB 0.0 mat)
> > >  (setC (/ -1.0 f) mat)
> > >  (setD 1.0 mat)
> > >  (values mat)))
> > 
> > (make-instance 'lens) will initialize all the slots to the values
> > specified by :initform.  Similarly, since you have used :initarg,  
> > you can initialize them to something different like this:
> > (make-instance 'lens :a -1 :b -2 :o 3)
> 
> Only computed values can't be done this way.
> 
> Here are my proposed changes:
>  
>  1. Eliminate the readers and writers, in preference of :accessor,
>     which allows you to read and set them more naturally.  That is,
>        (setf (getA thing) val)
>     rather than
>        (setA val thing)
> 
>     Or pick better names that getA. e.g, the-a or a-value or even just
>     a itself.  e.g.,  if it's an opacity, an accessor name like opacity
>     is rather nice.
> 
>  2. Let A and B initialize themselves.  The setup in make-lens isn't helping.
>     Use an after method on INITIALIZE-INSTANCE to notice values that need
>     initialization and fix things.  You could either leave F unbound and
>     then use SLOT-BOUNDP, or you could (as I usually do) just initialize
>     it to NIL and let the after method test its falsity instead.
> 
>  3. Don't use VALUES unless you either plan to return multiple values,
>     including zero values, as in (VALUES) or (VALUES x y), or else you
>     want to mask out multiple values. e.g., (VALUES (FOO)) returns only
>     (FOO)'s first value even if it returns more than one.  You have
>     (VALUES MAT) in your code, but there is no difference between that and
>     just MAT, since variables return only one value anyway.  The presence
>     of the (VALUES ...) around MAT doesn't hurt things but is unnecessary
>     and visually confusing.
> 
> I think this will work, though I didn't test it:
> 
> (defclass optmat ()
>   ((A :accessor the-a :initarg :a :initform 1.0)
>    (B :accessor the-b :initarg :b :initform 0.0)
>    (C :accessor the-c :initarg :c :initform 0.0)
>    (D :accessor the-d :initarg :d :initform 1.0)))
> 
> (defclass lens ()
>   ((f :accessor the-f :initarg :f :initform nil)
>    (o :accessor the-o :initarg :o :intiform 1.0)))

Just to confuse a little bit more the original poster... I'd propose
the following :)

 (defclass optmat ()
   ((A :accessor the-a :initarg :a)
    (B :accessor the-b :initarg :b)
    (C :accessor the-c :initarg :c)
    (D :accessor the-d :initarg :d))
   (:default-initargs :a 1.0 :b 0.0 :c 0.0 :d 1.0))
 
 (defclass lens ()
   ((f :accessor the-f :initarg :f)
    (o :accessor the-o :initarg :o))
   (:default-initargs :f nil :o 1.0))


The :after method on INITIALIZE-INSTANCE and the constructor stay the
same.

Cheers

-- 
Marco Antoniotti =============================================================
NYU Bioinformatics Group			 tel. +1 - 212 - 998 3488
719 Broadway 12th Floor                          fax  +1 - 212 - 995 4122
New York, NY 10003, USA				 http://galt.mrl.nyu.edu/valis
             Like DNA, such a language [Lisp] does not go out of style.
			      Paul Graham, ANSI Common Lisp
From: Jason Trenouth
Subject: Re: Are there "constructors" in CLOS?
Date: 
Message-ID: <i9qu2t08crc5mk8b1ef6p9c5d9dbvs7ojr@4ax.com>
On Wed, 6 Dec 2000 19:18:08 GMT, Kent M Pitman <······@world.std.com> wrote:

> "Christopher J. Vogt" <····@computer.org> writes:
> 
> > Rolf Wester wrote:
> 
> > > I'm just beginning to learn LISP and I want to write a little
> > > program using CLOS. Is there anything comparable to constructors
> > > in languages like Java or C++?
> 
> Not exactly.  In particular, contrasting it with Java, Java leaves it up
> to you to call SUPER, and if you don't you end up not calling it, you can
> lose badly. 

Not true. Java inserts super() for you in constructors if you don't put in some
kind of call to super yourself. Of course, its true that Java constructors can
cause significant personal lossage, but not because super doesn't get called.

__Jason
From: Kent M Pitman
Subject: Re: Are there "constructors" in CLOS?
Date: 
Message-ID: <sfwlmtsw3rf.fsf@world.std.com>
Jason Trenouth <·····@harlequin.com> writes:

> On Wed, 6 Dec 2000 19:18:08 GMT, Kent M Pitman <······@world.std.com> wrote:
> 
> > "Christopher J. Vogt" <····@computer.org> writes:
> > 
> > > Rolf Wester wrote:
> > 
> > > > I'm just beginning to learn LISP and I want to write a little
> > > > program using CLOS. Is there anything comparable to constructors
> > > > in languages like Java or C++?
> > 
> > Not exactly.  In particular, contrasting it with Java, Java leaves it up
> > to you to call SUPER, and if you don't you end up not calling it, you can
> > lose badly. 
> 
> Not true. Java inserts super() for you in constructors if you don't
> put in some kind of call to super yourself. Of course, its true that
> Java constructors can cause significant personal lossage, but not
> because super doesn't get called.

And, of course, you can only pout the super() in one place, rather than
anywhere in the method, as one can do with call-next-method in Lisp.

But what you said is only part right.  There's still a screw case.
It gets detected statically eventually, but it strikes me all the time.
If you have a class Foo with constructors Foo() and Foo(String s),
and you make a subclass, you MUST write the constructors Bar() and
Bar(String s).  Java irritatingly enough does not default them to
merely call super with the same args.  This makes a lot of code look
extrardinarily inelegant, which is what I was complaining about.  Yes,
you can say that's not really lossage becuase Java will slap your hand
at compile time if you write an actual call to new that needs that,
but you can still manage to publish an API with missing methods and not
realize you've screwed up.  That's the lossage I was referring to.
From: Keke Abe
Subject: Re: Are there "constructors" in CLOS?
Date: 
Message-ID: <keke-0912000030550001@solg4.keke.org>
In article <···············@world.std.com>,
Kent M Pitman <······@world.std.com> wrote:

>  2. Let A and B initialize themselves.  The setup in make-lens isn't helping.
>     Use an after method on INITIALIZE-INSTANCE to notice values that need
>     initialization and fix things.  You could either leave F unbound and
>     then use SLOT-BOUNDP, or you could (as I usually do) just initialize
>     it to NIL and let the after method test its falsity instead.

In the similar situation, I sometimes use an around method:

(defmethod initialize-instance :around ((lens lens) &rest rest
                                        &key foo (f (+ foo 1)))
  (apply #'call-next-method
         lens
         :foo foo
         :f f
         rest))


Is there anything that makes the after method preferable to this?

Thanks in advance,
abe
From: Eugene Zaikonnikov
Subject: Re: Are there "constructors" in CLOS?
Date: 
Message-ID: <6yr93itoqd.fsf@localhost.localdomain>
* "Keke" == Keke Abe <····@mac.com> writes:

[...]

Keke>  In the similar situation, I sometimes use an around method:

[...]

Keke>  Is there anything that makes the after method preferable to
Keke>  this?

Around method gets called twice.

-- 
  Eugene
From: Keke Abe
Subject: Re: Are there "constructors" in CLOS?
Date: 
Message-ID: <keke-0912001607280001@solg4.keke.org>
In article <··············@localhost.localdomain>,
Eugene Zaikonnikov <······@cit.org.by> wrote:
>
> Around method gets called twice.
>

I don't understand how that's possible. Could you elaborate?

regards,
abe
From: Rob Warnock
Subject: Re: Are there "constructors" in CLOS?
Date: 
Message-ID: <90stsc$8lqvq$1@fido.engr.sgi.com>
Eugene Zaikonnikov  <······@cit.org.by> wrote:
+---------------
| * "Keke" == Keke Abe <····@mac.com> writes:
| Keke>  In the similar situation, I sometimes use an around method:
| Keke>  Is there anything that makes the after method preferable to this?
| 
| Around method gets called twice.
+---------------

Surely not in general?!?  Is this something peculiar to INITIALIZE-INSTANCE?


-Rob

-----
Rob Warnock, 31-2-510		····@sgi.com
Network Engineering		http://reality.sgi.com/rpw3/
Silicon Graphics, Inc.		Phone: 650-933-1673
1600 Amphitheatre Pkwy.		PP-ASEL-IA
Mountain View, CA  94043
From: Eugene Zaikonnikov
Subject: Re: Are there "constructors" in CLOS?
Date: 
Message-ID: <6yg0jv9qnt.fsf@localhost.localdomain>
* "Rob" == Rob Warnock <····@rigden.engr.sgi.com> writes:

Rob>  Eugene Zaikonnikov <······@cit.org.by> wrote:

Rob>  | Around method gets called twice

Rob>  Surely not in general?!?  Is this something peculiar to
Rob>  INITIALIZE-INSTANCE?

No Rob, it is something peculiar about me: too many BS posts these
nights. I'd better take vacation and play some Christmas carols on
harmonica.

Regards,
   Eugene.
From: Kent M Pitman
Subject: Re: Are there "constructors" in CLOS?
Date: 
Message-ID: <sfwn1e5y5s3.fsf@world.std.com>
····@mac.com (Keke Abe) writes:

> In article <···············@world.std.com>,
> Kent M Pitman <······@world.std.com> wrote:
> 
> >  2. Let A and B initialize themselves.  The setup in make-lens isn't helping.
> >     Use an after method on INITIALIZE-INSTANCE to notice values that need
> >     initialization and fix things.  You could either leave F unbound and
> >     then use SLOT-BOUNDP, or you could (as I usually do) just initialize
> >     it to NIL and let the after method test its falsity instead.
> 
> In the similar situation, I sometimes use an around method:
> 
> (defmethod initialize-instance :around ((lens lens) &rest rest
>                                         &key foo (f (+ foo 1)))
>   (apply #'call-next-method
>          lens
>          :foo foo
>          :f f
>          rest))
> 
> 
> Is there anything that makes the after method preferable to this?

Yes.  The fact that the actions you want to do are all "after" the
main method.  That's not to say you have to do it that way.  But I
personally subscribe to a style rule that says "use before if all the
activity happens before, use after if all the activity happens after,
and use around only when you have to span both in order to get the 
job done".

To me, using "after" signals a binding context or other
coordinated action that must span from start to end.  You're using around
in a position here that you hope will be a tail call but that, strictly,
might not be.  That's just a style thing.

Further, there's a computational difference between attaching these
things to the args going in and initializing things later, and that has
to do with which other methods will see the value.  It may be desirable
to do what you're doing or it may not.  In my personal rule of style,
you're saying "I know there is a value somewhere in the initialization
that cares about this and I'm working hard to get it to that point".
However, for someone who enjoys an opposite style rule thinking this
is normal, my use of :after might say "I know there is someone who will
be confused by premature setup of this, and I've tried to avoid that."

This is why it's useful to know people's style rules (at minimuum) and
to program systems with consistent style rules (sometimes).  e.g., one
might call "caller saves" vs "callee saves" register cleanliness
conventions a style rule.  Certainly there is nothing forcing either
behavior, a priori.  But once someone makes an arbitrary choice, the
world works best when everyone uses the same arbitrary choice.

LET and LET* are milder forms of this.  When there is no interoperation
between names among the bindings, it doesn't matter which one you use.
But some people are cued by the presence of LET* that something odd is
going on, so some of us say you should prefer LET in the case of a 
tie.  Nevertheless, we've had dicussions in other threads about the fact
that some have the opposite  rule (prefer LET* unless  you have a special
reason for LET).

At least in the case of LET/LET*, your personal style rules don't affect
other programmers.  In the case of :around and :after, they do.

Btw, there's a big war between some people as to whether :around and
:after and :before are needed at all.  Some people would have just
omitted the :around in the example you gave, making it a primary method.
I *think* that also works, but don't have time this morning to
research it.  I'll leave that to someone else.  And yes, there's a subtle
distinction between with and without :around, since obviously each is
susceptible to different redefinition rules, as well as you can REALLY
confuse yourself with BOTH a :around and a regular method, especially if
one is a bug fix for the other but fails to clobber the other.
From: Patrick A. O'Donnell
Subject: Re: Are there "constructors" in CLOS?
Date: 
Message-ID: <rtg0jukikn.fsf@ascent.com>
Kent M Pitman <······@world.std.com> writes:
> ····@mac.com (Keke Abe) writes:
> > In the similar situation, I sometimes use an around method: ...
> > Is there anything that makes the after method preferable to this?
> 
> Yes.  The fact that the actions you want to do are all "after" the
> main method.  That's not to say you have to do it that way.  ...
>
> To me, using "after" signals a binding context or other
> coordinated action that must span from start to end.  You're using around
> in a position here that you hope will be a tail call but that, strictly,
> might not be.  That's just a style thing.
> 
> Btw, there's a big war between some people as to whether :around and
> :after and :before are needed at all.  Some people would have just
> omitted the :around in the example you gave, making it a primary method.

Often, it becomes more than just a style issue.  The order of actions
taken is, of course, affected by the method combination, and the
ordering of the primary, after, and around methods can be affected by
that.  I've been bitten by this more times than I'd like, and it's
true that if your code depends critically on the method combination
order, that's more likely than not symptomatic of a design flaw.  I've
more than once had to use an around method where an after would do,
simply because I had to have the action taken after some other after
method, and I couldn't change the precedence order of the
superclasses.

> And yes, there's a subtle distinction between with and without
> :around, since obviously each is susceptible to different
> redefinition rules, as well as you can REALLY confuse yourself with
> BOTH a :around and a regular method, especially if one is a bug fix
> for the other but fails to clobber the other.

Been there.  Done that.  Bought the T-shirt.

		- Pat
From: Janis Dzerins
Subject: Re: Are there "constructors" in CLOS?
Date: 
Message-ID: <87ofyo1uln.fsf@asaka.latnet.lv>
Rolf Wester <······@ilt.fhg.de> writes:

> Hi,
> 
> I'm just beginning to learn LISP and I want to write a little program
> using
> CLOS. Is there anything comparable to constructors in languages like
> Java or C++?
> 
> I have a class optmat and a derived class lens. I want to initialize
> A,B,C and D when
> creating a lens object. My proposed solution is:
> 
> (defclass optmat ()
>     ((A :reader getA :writer setA :initarg :A :initform 1.0)
>      (B :reader getB :writer setB :initarg :B :initform 0.0)
>      (C :reader getC :writer setC :initarg :C :initform 0.0)
>      (D :reader getD :writer setD :initarg :D :initform 1.0)))
> 
> (defclass lens (optmat)
>     ((F :reader getF :writer setF :initarg :F :initform 1.0e10)
>      (O :reader getO :writer setO :initarg :O :initform 1.0)))

As others already suggested you should use some more descriptive names
for slot accessors. And Common Lisp is (by default, you can change it)
case insensitive so writing mixed-case symbols in Common Lisp does not
usually make sense. (Looks like you're trying to write C++ or Java
code in Common Lisp -- that's not the best way to use the
language. Common Lisp allows one to put hyphens (not underscores) in
symbols, and that's what others are doing. In your case you could
freely name your readers and writers as get-a and get-o which look
more Lisp-like, at least to me.)

BTW, reader GETF and writer SETF for LENS are symbols in COMMON-LISP
package so your compiler should signal an error (unless you're using
ACL 6.0 in "modern" mode).

Janis Dzerins
-- 
  If million people say a stupid thing it's still a stupid thing.
From: Erik Naggum
Subject: Re: Are there "constructors" in CLOS?
Date: 
Message-ID: <3185182937784233@naggum.net>
* Janis Dzerins <·····@latnet.lv>
| Common Lisp allows one to put hyphens (not underscores) in symbols,
| and that's what others are doing.

  Actually, underscores are OK, too.  Any character is allowed with a
  backslash before it or with the whole symbol quoted with ||, but you
  don't need that unless the character is a terminating macro character
  in the current readtable.  Avoid '";,() and you're pretty much safe,
  unless you try to use # at the beginning of a symbol -- that would
  mean something else.  This wide-open freedom to name symbols anything
  is not abused as much as the freedom to abuse case distinctions is.

| BTW, reader GETF and writer SETF for LENS are symbols in COMMON-LISP
| package so your compiler should signal an error (unless you're using
| ACL 6.0 in "modern" mode).

  Good catch, and a case of abuse of case distinctions if you ask me.

#:Erik
-- 
  "When you are having a bad day and it seems like everybody is trying
   to piss you off, remember that it takes 42 muscles to produce a
   frown, but only 4 muscles to work the trigger of a good sniper rifle."
								-- Unknown
From: Janis Dzerins
Subject: Re: Are there "constructors" in CLOS?
Date: 
Message-ID: <87k89c1f0t.fsf@asaka.latnet.lv>
Erik Naggum <····@naggum.net> writes:

> * Janis Dzerins <·····@latnet.lv>
> | Common Lisp allows one to put hyphens (not underscores) in symbols,
> | and that's what others are doing.
> 
>   Actually, underscores are OK, too.  Any character is allowed with a
>   backslash before it or with the whole symbol quoted with ||, but you
>   don't need that unless the character is a terminating macro character
>   in the current readtable.

Yeah, I know that. I re-read my post, after sending, and noticed that
my wording is not right. Another lesson for me.

> | BTW, reader GETF and writer SETF for LENS are symbols in COMMON-LISP
> | package so your compiler should signal an error (unless you're using
> | ACL 6.0 in "modern" mode).
> 
>   Good catch, and a case of abuse of case distinctions if you ask me.

Actually it was not meant like that -- I just knew the code should not
work and tried it on ACL 6.0, but it worked! So I put a note (which I
could avoid doing but since the poster has not mentioned which Lisp
he's using I assumed his code works and that he might be using ACL 6.0
after all).

Janis Dzerins
-- 
  If million people say a stupid thing it's still a stupid thing.
From: Rolf Wester
Subject: Re: Are there "constructors" in CLOS?
Date: 
Message-ID: <3A2F5E66.F763F610@ilt.fhg.de>
Hi,

I want to thank all who replied to my answer. Your replies have been very
instructive.

I'm much more experienced in programming in C++, Java or Python. LISP is
a
"little bit" different but I find it very interesting. I don't know yet
wether programming
in LISP could be advantageous for me. I'm mostly concerned with numerical
simulation
of physical processes and with the analysis of measurement data. Besides
the question
what programming language is the best one for a special purpose there are
also other
points that have to be considered. For example the availability of
libraries, what
programming languages the colleagues I'm collaborating with know and what

CLisp systems are available. At present I use CLISP. I'm considering to
purchase
Allegro but this is quite expensive. We are a research institute so
Visual C++ costs
almost nothing, Java JBuilder and Python (IDE, WinPython) are free. CLisp
should
really promise a much higher productivity compared to the alternatives
before I would
consider to more heavily use CLisp. In order to be able to make up my
mind concerning
the benefit of CLips for me I have to better learn LISP programming. And
thats what
I'm going to to now.

Thanks again for yor help.

--Rolf
From: Johan Kullstam
Subject: Re: Are there "constructors" in CLOS?
Date: 
Message-ID: <m3n1e846x7.fsf@sysengr.res.ray.com>
Rolf Wester <······@ilt.fhg.de> writes:

> Hi,
> 
> I want to thank all who replied to my answer. Your replies have been very
> instructive.
> 
> I'm much more experienced in programming in C++, Java or Python. LISP is
> a
> "little bit" different but I find it very interesting. I don't know yet
> wether programming
> in LISP could be advantageous for me. I'm mostly concerned with numerical
> simulation
> of physical processes and with the analysis of measurement data. Besides
> the question
> what programming language is the best one for a special purpose there are
> also other
> points that have to be considered. For example the availability of
> libraries, what
> programming languages the colleagues I'm collaborating with know and what
> 
> CLisp systems are available. At present I use CLISP. I'm considering to
> purchase
> Allegro but this is quite expensive.

you may want to give cmucl (CMU common-lisp) a try.  it's free.  it
does rather well with number crunching.  it's only available for
unix-like systems such as ia32 linux or freebsd.  be
forewarned, cmucl's CLOS implementation is slow and crufty.

you may want to check out the the matlisp package.  it is an interface
to fortran's lapack and extremely useful.

-- 
J o h a n  K u l l s t a m
[········@ne.mediaone.net]
sysengr
From: Hannah Schroeter
Subject: Re: Are there "constructors" in CLOS?
Date: 
Message-ID: <90of0j$pat$1@c3po.schlund.de>
Hello!

In article <··············@sysengr.res.ray.com>,
Johan Kullstam  <········@ne.mediaone.net> wrote:
>[...]

>you may want to give cmucl (CMU common-lisp) a try.  it's free.  it
>does rather well with number crunching.  it's only available for
>unix-like systems such as ia32 linux or freebsd.  be
>forewarned, cmucl's CLOS implementation is slow and crufty.

For me, cmucl is still losing, as I run ia32 OpenBSD. Neither
the FreeBSD nor the Linux binaries run fine in "binary emulation".
There are sbcl (a cmucl derivative) binaries for OpenBSD, however,
it seems difficult to impossible to bootstrap cmucl with sbcl.

Kind regards, Hannah.
From: Pierre R. Mai
Subject: Re: Are there "constructors" in CLOS?
Date: 
Message-ID: <87r93i3fwa.fsf@orion.bln.pmsf.de>
Raymond Wiker <·············@fast.no> writes:

> vsync <·····@quadium.net> writes:
> 
> > > >forewarned, cmucl's CLOS implementation is slow and crufty.
> > 
> > How slow and crufty?  Like, if I'm used to CLISP, will I be satisfied
> > with the performance of CMUCL's CLOS?
> 
>         It has been said here, a good few times, that CMUCLs CLOS is
> slow and not fully conformant. It has also been said that CMUCLs CLOS
> performance is *not* a problem, and the non-conformance is restricted
> to one or two minor areas.

I'm one of those that have been countering the claim that CMU CL's
CLOS is slow and crufty for a couple of years now.  It seems to me
that this claim in its generality has long outlived its usefulness.
While it is true that CMU CL's CLOS is not quite as polished as the
rest of CMU CL, or some of the commercial CLOS implementations out
there, and that it probably doesn't take as much advantage of CMU CL's
excellent compiler as it probably could, we have found the current
state of CMU CL's CLOS to be quite good enough.  Also there are
currently some moves underway to integrate CMU CL's CLOS more tightly
with the rest of CMU CL, so that some of the edges will be going away.

To give a perspective on this view: One of our major applications is a
manufacturing/logistics simulation toolkit, where simulations often use
more than 70 MB of in-core data (sans code and runtime data structures)
in over 80.000 CLOS instances, and have run-times in the area of 1-2
hours per 30 days of simulation time.  Discrete-event simulations of
this sort don't profit hugely from CMU CL's numerical optimisations,
since most numerical operations are simple and few and far between.
OTOH CLOS operations like method dispatch and slot-accesses are very
frequent.  Still we have found that on this particular application CMU
CL slightly outperforms all the alternative implementations we tried
(the nearest implementation did run about 15% slower the last time we
tested).

For this application we didn't even consider CLISP, since at the time
it was far to quirky in its ANSI compliance to make a port feasible.
This has changed somewhat in the mean-time, especially with CLISP's
ANSI mode, but CLISP is to the best of my knowledge still missing a
couple of important things (like change-class or method combinations
other than standard method-combination), which makes it difficult to
port to CLISP.  For those reasons I can't give you comparative figures
on CLISP's performance on this application.

At the time we also conducted some micro-benchmarks on the different
CLOS implementations and found that CMU CL's performance to be within
a small factor of the commercial CLOS' versions we tested for many
operations, a bit faster for a few, and significantly slower only for
one or two areas (mostly instance creation time for constant classes,
though CMU CL's CLOS offers a specific optimisation here, for the
cases where this really matters).  On the benchmarks that were
runnable on CLISP, CMU CL more or less consistently performed better
by a factor of between 2 to 20, with the following exceptions:

 - Calls to methods specialised on a large (5-10) number of arguments:
   CLISP wins by nearly a factor of 3.
 - Calls to SLOT-VALUE outside of method:
   CLISP wins by a factor of 1.5.
 - Calls to SLOT-VALUE for a class-allocated slot outside of method:
   CLISP wins by a factor of 3.
 - MAKE-INSTANCE on variable classes (by name or class object):
   CLISP wins by a factor between 2.5 - 4
 - SLOT-UNBOUND trapping (all scenarios):
   CLISP wins by a factor of > 20, because SLOT-UNBOUND traps are very
   expensive on CMU CL (up to 75 µsec on an AMD K6-2/550).

Now these numbers should all be taken with a large grain of salt,
since it is entirely likely that with some implementation-specific
tuning, newer versions or some other set of operations, other
implementations will significantly out-perform CMU CL.  Also note that
commercial implementations are generally much more polished across the
board than free implementations like CMU CL or CLISP.  So you'll
probably like to do your own benchmarking (if you really have to care
about small constant performance-factors) and evaluation, and decide
on your own which implementation will fulfil your needs.  Don't just
trust me or anyone else telling you CMU CL's CLOS is fast or slow,
nice-enough or crufty, etc.

Regs, Pierre.

-- 
Pierre R. Mai <····@acm.org>                    http://www.pmsf.de/pmai/
 The most likely way for the world to be destroyed, most experts agree,
 is by accident. That's where we come in; we're computer professionals.
 We cause accidents.                           -- Nathaniel Borenstein
From: Hannah Schroeter
Subject: Re: Are there "constructors" in CLOS?
Date: 
Message-ID: <91lb25$543$1@c3po.schlund.de>
Hello!

In article <··············@piro.quadium.net>, vsync  <·····@quadium.net> wrote:
>······@schlund.de (Hannah Schroeter) writes:

>> >forewarned, cmucl's CLOS implementation is slow and crufty.

That's not by me.

>How slow and crufty?  Like, if I'm used to CLISP, will I be satisfied
>with the performance of CMUCL's CLOS?

-> Ask the author of those words.

>> There are sbcl (a cmucl derivative) binaries for OpenBSD, however,
>> it seems difficult to impossible to bootstrap cmucl with sbcl.

>But why not just run SBCL itself?  Are there incompatibilities?  How
>does SBCL compare to normal CMUCL, just in general?

CLX, Hemlock, Sockets, ...

Kind regards,

Hannah.
From: vsync
Subject: Re: Are there "constructors" in CLOS?
Date: 
Message-ID: <86itody76b.fsf@piro.quadium.net>
······@schlund.de (Hannah Schroeter) writes:

> In article <··············@piro.quadium.net>, vsync  <·····@quadium.net> wrote:
> >······@schlund.de (Hannah Schroeter) writes:
> 
> >> >forewarned, cmucl's CLOS implementation is slow and crufty.
> 
> That's not by me.

I didn't say it was.  Learn to count the quote marks.

> >How slow and crufty?  Like, if I'm used to CLISP, will I be satisfied
> >with the performance of CMUCL's CLOS?
> 
> -> Ask the author of those words.

I was asking the forum in general, actually.  Luckily a number of
people provided me with some very useful and well-presented
information.

> >But why not just run SBCL itself?  Are there incompatibilities?  How
> >does SBCL compare to normal CMUCL, just in general?
> 
> CLX, Hemlock, Sockets, ...

Thank you for the information.  In my case, the incompatibility that
makes the difference is sockets.

-- 
vsync
http://quadium.net/ - last updated Tue Dec 19 20:37:35 PST 2000
(cons (cons (car (cons 'c 'r)) (cdr (cons 'a 'o))) ; Orjner
      (cons (cons (car (cons 'n 'c)) (cdr (cons nil 's))) nil))
From: Paolo Amoroso
Subject: Re: Are there "constructors" in CLOS?
Date: 
Message-ID: <0LkvOp2z0chQwe6Uf0Bi9OzK3Kgf@4ax.com>
On Thu, 07 Dec 2000 10:54:46 +0100, Rolf Wester <······@ilt.fhg.de> wrote:

> in LISP could be advantageous for me. I'm mostly concerned with numerical
> simulation
> of physical processes and with the analysis of measurement data. Besides

You might want to check the following paper:

  Fast Floating-Point Processing in Common Lisp
  ftp://peoplesparc.berkeley.edu/pub/papers/lispfloat.ps


> points that have to be considered. For example the availability of
> libraries, what

A couple of useful resources:

  CLiki
  http://ww.telent.net/cliki/

  CLOCC (Common Lisp Open Code Collection)
  http://clocc.sourceforge.net/


Paolo
-- 
EncyCMUCLopedia * Extensive collection of CMU Common Lisp documentation
http://cvs2.cons.org:8000/cmucl/doc/EncyCMUCLopedia/
From: Paolo Amoroso
Subject: Re: Are there "constructors" in CLOS?
Date: 
Message-ID: <Y14zOmuZFjmYR9OKCMkKMzjQAceX@4ax.com>
On Thu, 07 Dec 2000 17:25:48 +0100, Paolo Amoroso <·······@mclink.it>
wrote:

>   Fast Floating-Point Processing in Common Lisp

The most up to date URL is:

  http://www.cs.berkeley.edu/~fateman/papers/lispfloat.ps


Paolo
-- 
EncyCMUCLopedia * Extensive collection of CMU Common Lisp documentation
http://cvs2.cons.org:8000/cmucl/doc/EncyCMUCLopedia/