From: Axel Schairer
Subject: Interning symbols in macro expanders
Date: 
Message-ID: <ydjwwaxgvfp.fsf@dfki.de>
A call to defstruct, say (defstruct a ...), defines a function with
the name make-a in the current package (at the time the defstruct form
is read). Is this right so far?

A macro of mine, call it m, does something similar:  It defines a
function (structure, whatever) with the name of its first argument and 
some prefix.  So 

	(m a ...) 

expands into something like

	(defun prefix-a ...)

Now, Graham (On Lisp, pp. 136-7) tells me, that 

	(defmacro m (name ...)
	  `(defun ,(intern (format nil "PREFIX-~A" 'name)) ...))

is not OK because the package of PREFIX-A will depend on the current
package when the call to m is *expanded* in contrast to when the call
is read.  I think I understand the problem if I assume that expansion
does not necessarily take place in the same package in which the form
was read.

However, on page 266 Graham givs an example of a similar macro.  Its
definition can be put in the following way (to resemble the example
from above).

	(defmacro m (name ...)
	  (let ((f (intern (concatenate 'string
	                                "PREFIX-"
	                                (symbol-name name)))))
	    `(defun ,f ...)))

To me it seems as if this was the same problem.  

Do I miss something important?  How should one do this kind of thing?

Axel

From: Rainer Joswig
Subject: Re: Interning symbols in macro expanders
Date: 
Message-ID: <90nclsai.fsf@lise.lavielle.com>
Axel Schairer <········@dfki.de> writes:

> Now, Graham (On Lisp, pp. 136-7) tells me, that 
> 
> 	(defmacro m (name ...)
> 	  `(defun ,(intern (format nil "PREFIX-~A" 'name)) ...))

There is a quote before name?

Well, actually I would intern the new symbol (prefix + name)
into the same package as the symbol name is. Just a guess.
INTERN takes as the second parameter the package to use.

(intern (concatenate 'string "PREFIX-" (symbol-name name))
        (symbol-package name))
From: Kent M Pitman
Subject: Re: Interning symbols in macro expanders
Date: 
Message-ID: <sfwhg21fb9n.fsf@world.std.com>
Rainer Joswig <······@lise.lavielle.com> writes:

> Axel Schairer <········@dfki.de> writes:
> 
> > Now, Graham (On Lisp, pp. 136-7) tells me, that 
> > 
> > 	(defmacro m (name ...)
> > 	  `(defun ,(intern (format nil "PREFIX-~A" 'name)) ...))
> 
> There is a quote before name?
> 
> Well, actually I would intern the new symbol (prefix + name)
> into the same package as the symbol name is. Just a guess.
> INTERN takes as the second parameter the package to use.
> 
> (intern (concatenate 'string "PREFIX-" (symbol-name name))
>         (symbol-package name))
> 

Actually, the reason one doesn't do this latter thing which Rainer
suggests is because of inherited symbols.  Things can end up in the
inherited package where they may not belong.  Consider:

 (defmacro define-frob (x)
   (let ((getter (format nil "GET-~A" name) (symbol-package name))
	 (setter (format nil "SET-~A" name) (symbol-package name)))
     `(progn (defun ,x ....)
             (defun ,setter ...)
	     ',x)))

 (define-frob car) ;defines GET-CAR and SET-CAR in package CL!

This sets GET-CAR and SET-CAR as an INTERNAL symbol of CL, but who's
to say there isn't a SET-CAR already there? Perhaps secretly
implementing (SETF CAR).  It's a bad idea to be clobbering someone
else's internals.

The Lisp Machine's dialect, Zetalisp, created the concept of a "locked
package" (this package is "ready" and should not be further modified")
and it automatically locked any package that was "used" by another to
avoid strange effects.  This isn't conforming, but it is what I thought
was a great idea.  But it tended to stop things like the above and 
we as a community eventually learned not to do the 
 (intern (f name) (symbol-package name))
thing.

Remember, I'm not thinking these things up on the fly--they are hard
to anticipate if you've never seen them but they are memory exercises
to me.  And bad memories, say the cognitive scientists, are easier to
remember because adrenaline enhances long-term memory storage. :-)

Anyway, her's another case that's similar to the above that modifies
external symbols and is just subtle enough that you don't always
see it coming:

 (define-frob difference) ;defines GET-DIFFERENCE and SET-DIFFERENCE

SET-DIFFERENCE is already an external.

Anyway, so the ONE-arg call to INTERN, done at read-time is considered 
preferable albeit a bit surprising because new symbols are leaping to
life that you can't always remember are there.  

HOWEVER... CLOS did really the right thing in making the textually
verbose but all-in-all stylistically subtle change of moving away from
"conc-names" and what was sometimes called "symbolconc'ing" (pronounced
"symbol-konk-ing" like "conc" from "concatenate" not "consing", btw).
Instead of all that, CLOS said "look, if you want me to auto-define
a symbol, fine--just tell me its name and i'll do it".  This was simple
and elegant and gets around a lot of problems.  So now I mostly write
macros that just do

 (define-frob (x &key getter setter)
   `(progn ,(when getter `(defun ,getter ...))
           ,(when setter `(defun ,setter ...))
           ',x))

And besides everything else, I think this new theory of style tends to
generate fewer definitions that will end up never being used.
From: Rainer Joswig
Subject: Re: Interning symbols in macro expanders
Date: 
Message-ID: <7m2wlnxc.fsf@lise.lavielle.com>
Kent M Pitman <······@world.std.com> writes:

> Anyway, her's another case that's similar to the above that modifies
> external symbols and is just subtle enough that you don't always
> see it coming:
> 
>  (define-frob difference) ;defines GET-DIFFERENCE and SET-DIFFERENCE
> 
> SET-DIFFERENCE is already an external.
> 
> Anyway, so the ONE-arg call to INTERN, done at read-time is considered 
> preferable albeit a bit surprising because new symbols are leaping to
> life that you can't always remember are there.  
> 
> HOWEVER... CLOS did really the right thing in making the textually
> verbose but all-in-all stylistically subtle change of moving away from
> "conc-names" and what was sometimes called "symbolconc'ing" (pronounced
> "symbol-konk-ing" like "conc" from "concatenate" not "consing", btw).
> Instead of all that, CLOS said "look, if you want me to auto-define
> a symbol, fine--just tell me its name and i'll do it".  This was simple
> and elegant and gets around a lot of problems.  So now I mostly write
> macros that just do
> 
>  (define-frob (x &key getter setter)
>    `(progn ,(when getter `(defun ,getter ...))
>            ,(when setter `(defun ,setter ...))
>            ',x))
> 
> And besides everything else, I think this new theory of style tends to
> generate fewer definitions that will end up never being used.

How about another question:

(defclass set ()
  ((gadget-items :accessor set-gadget-items ...)))

(defclass set-gadget ()
  ((items :accessor set-gadget-items ...)))

There seams to be a style to take the name
of a class and append the name of the slot.
I always found this puzzling. I would
prefer either a convention taking a different
character as a separator like set=gadget-items and
set-gadget=items.

I still don't like code like this:

  (money-euro-value (person-income (set-gadget-value persons-gadget)))


Actually  persons-gadget.value.income.euro-value   is not that bad.
From: Kent M Pitman
Subject: Re: Interning symbols in macro expanders
Date: 
Message-ID: <sfwra15umso.fsf@world.std.com>
Rainer Joswig <······@lise.lavielle.com> writes:

> How about another question:
> 
> (defclass set ()
>   ((gadget-items :accessor set-gadget-items ...)))
> 
> (defclass set-gadget ()
>   ((items :accessor set-gadget-items ...)))
> 
> There seams to be a style to take the name
> of a class and append the name of the slot.
> I always found this puzzling. I would
> prefer either a convention taking a different
> character as a separator like set=gadget-items and
> set-gadget=items.
> 
> I still don't like code like this:
> 
>   (money-euro-value (person-income (set-gadget-value persons-gadget)))
> 
> Actually  persons-gadget.value.income.euro-value   is not that bad.

Hey, I just started learning some German last week and noticed that you
just jam all your compounds together with no indicaation of a break, so 
I'm inclined to say that I'm just surprised you're not used to it.  Then
again, maybe it's from that experience that you've learned it doesn't work.
;-)

The practice in Lisp is pretty much the same.  Tradition weighs more
heavily than common sense sometimes.  I think your remark clearly right
and it has come up from time to time, but... in the end, no one could
figure out what char they'd give up to be the standard separator, so
we just ended up overloading "-".
From: Rainer Joswig
Subject: Re: Interning symbols in macro expanders
Date: 
Message-ID: <67igljpe.fsf@lise.lavielle.com>
Kent M Pitman <······@world.std.com> writes:

> Hey, I just started learning some German last week and noticed that you
> just jam all your compounds together with no indicaation of a break, so 
> I'm inclined to say that I'm just surprised you're not used to it.  Then
> again, maybe it's from that experience that you've learned it doesn't work.
> ;-)

Hmm, I always thought the German version makes more sense. ;-)

car dealer vs. cardealer  ;-)

Auto Haendler  vs.   Autohaendler

It's one object, so it should be one word. ;-)

Hmm, mabe I should switch to german language while programming.

(kond (*abbild-cl-http-name*
       (schleife fuer (schluessel nachricht vorgabe) in *cl-http-optionen-daten*
	     tue
	     (wenn (gleich (idr (assoz schluessel *cl-http-optionen*)) :frage)
	       (setze *cl-http-optionen*

...
From: Georg Bauer
Subject: Re: Interning symbols in macro expanders
Date: 
Message-ID: <gb-0606981256080001@hugo.westfalen.de>
In article <············@lise.lavielle.com>, Rainer Joswig
<······@lise.lavielle.com> wrote:

>(kond (*abbild-cl-http-name*
>       (schleife fuer (schluessel nachricht vorgabe) in
*cl-http-optionen-daten*
>             tue
>             (wenn (gleich (idr (assoz schluessel *cl-http-optionen*)) :frage)
>               (setze *cl-http-optionen*

Disgusting. :-)

bye, Georg

-- 
"Sicher ist, das nichts sicher ist. Aber selbst das nicht."
 - Ringelnatz
From: Tim Bradshaw
Subject: Re: Interning symbols in macro expanders
Date: 
Message-ID: <ey3g1hggmm6.fsf@todday.aiai.ed.ac.uk>
* Rainer Joswig wrote:
> Kent M Pitman <······@world.std.com> writes:
>> Hey, I just started learning some German last week and noticed that you
>> just jam all your compounds together with no indicaation of a break, so 
>> I'm inclined to say that I'm just surprised you're not used to it.  Then
>> again, maybe it's from that experience that you've learned it doesn't work.
>> ;-)

> Hmm, I always thought the German version makes more sense. ;-)

> car dealer vs. cardealer  ;-)

> Auto Haendler  vs.   Autohaendler

> It's one object, so it should be one word. ;-)

Completely off-topic (but at least it's yet another lisp is
slower/faster/better/worse than C++ thread):

I've always suspected that the reason compounding in German can work
reasonably is that people have very fast recognition of real words, so
the compounds can be discompounded (?) very efficiently.  After all
you have to do this for the *spoken* language anyway -- `cardealer' is
not pronounced differently than `car dealer'.

But in a programming language the components of a compound are often
made-up words themselves so the discompounding needs some help?

It would be an interesting experiment to see if German (or other
freely-compounding-language) speakers do better at programming
languages that compound freely, like Lisp (does C++ compound the same
way?).  There do seem to be a lot of good German Lisp programmers...

--tim
From: Kent M Pitman
Subject: Re: Interning symbols in macro expanders
Date: 
Message-ID: <sfw67icxbab.fsf@world.std.com>
Tim Bradshaw <···@aiai.ed.ac.uk> writes:

> Completely off-topic (but at least it's yet another lisp is
> slower/faster/better/worse than C++ thread):

I never personally consider any discussion of what increases/decreases
the cognitive overhead of users of a language to be off-topic in a
discussion of the language.  It's one of the things that I think
separates Lisp from some other languages; I am pretty sure some other
languages have decided that the cognitive overhead of learning and
using them on a day-to-day basis is irrelevant.

Anyway, anyone who find the thread irrelevant can, as always, ignore it.

> I've always suspected that the reason compounding in German can work
> reasonably is that people have very fast recognition of real words

I don't think this is really the issue because Lisp indicates with hyphens
the boundaries of "real words".  That is, if you see a program that
says glocko-frobettes, you dn't have to know whether "glocko" and
"frobettes" are real words (they aren't intended to be for this example),
you know where the hyphen is so you know the chunking.

The problem being complained about at the top of this thread is the
associativity problem.  For example:

   fastest-bird-speed

The problem here is not knowing that all of these are words.  Rather,
the question is, does this refer to the speed of the fastest bird
(perhaps just an average speed) or the fastest-speed of a bird
(perhaps a record speed).  Or consider

   set-element-car

Does this set the car of an element, or does it the get car of a 
set-element (mathematical sets, like "set-difference").  Or

   automatic-dishwasher-builder

Does this automatically build diswashers or build automatic
diswashers?  Of course, if I said

   automatic-dishwasher-tax

the knowledge of natural language might help you know I meant
automatic-dishwasher tax since automatic certainly wouldn't apply
to any kind of tax.  (Taxes are always automatic.)

I don't think it's the ability to recognize proper subwords that makes
it possible to pick long compounds apart better than Lisp--that mostly
just llows them to deal without hyphens and brings things back up to a
level playing field.  If indeed they do better than Lisp programmers
at the associativity problem, I'd guess it's either more (a)
meticulous word order, (b) declentions, or (c) the willingness not to
compound in places where it would be confusing that gets them through.

Item (c) is not to be overlooked in its power, and is yet another reason
why having the human specify a name to use rather than automatically
having the name generated can be a big win.
From: Tim Bradshaw
Subject: Re: Interning symbols in macro expanders
Date: 
Message-ID: <ey3solbgb3x.fsf@todday.aiai.ed.ac.uk>
* Kent M Pitman wrote:

[I wrote]
>> I've always suspected that the reason compounding in German can work
>> reasonably is that people have very fast recognition of real words

> I don't think this is really the issue because Lisp indicates with hyphens
> the boundaries of "real words".  That is, if you see a program that
> says glocko-frobettes, you dn't have to know whether "glocko" and
> "frobettes" are real words (they aren't intended to be for this example),
> you know where the hyphen is so you know the chunking.

I think it might still turn out to be the case that the `real-word'
issue is more important than hyphens for natural languages.  In
*spoken* German (and English, really) you can't hear the hyphens, and
yet people can still decompound rapidly.  Of course Lisp and other
programming languages are pretty thoroughly primarily-written
languages so this point doesn't really count for much.  It would be
interesting to look at programming languages which could work
reasonably well when spoken, although I think you'd be crippled by the
fact that most of what you do in a programming language is something
you'd need to write down to understand in any case (like maths).  This
is a bit like the trick of reading Lisp code using the layout
rather than the parens, except you can't see layout in spoken language
either...

> The problem being complained about at the top of this thread is the
> associativity problem.  For example:

>    fastest-bird-speed

I'd missed the root of the thread I think.  I can see this is a real
problem though! 

> I don't think it's the ability to recognize proper subwords that makes
> it possible to pick long compounds apart better than Lisp--that mostly
> just llows them to deal without hyphens and brings things back up to a
> level playing field.  If indeed they do better than Lisp programmers
> at the associativity problem, I'd guess it's either more (a)
> meticulous word order, (b) declentions, or (c) the willingness not to
> compound in places where it would be confusing that gets them
> through.

> Item (c) is not to be overlooked in its power, and is yet another reason
> why having the human specify a name to use rather than automatically
> having the name generated can be a big win.

I think this is right. Another reason would be that people can do a
lot from context -- if you know that you're dealing with objects
called FASTEST-BIRDs in your program then a lot of the ambiguity above
is resolved for you.  You get similar things in natural languages
where (machine) parsers find a lot of ambiguity which can actually be
resolved by contextual information.

--tim
From: Rainer Joswig
Subject: Re: Interning symbols in macro expanders
Date: 
Message-ID: <90n7zlnj.fsf@lise.lavielle.com>
Tim Bradshaw <···@aiai.ed.ac.uk> writes:

> Completely off-topic (but at least it's yet another lisp is
> slower/faster/better/worse than C++ thread):
;-)

> I've always suspected that the reason compounding in German can work
> reasonably is that people have very fast recognition of real words, so
> the compounds can be discompounded (?) very efficiently.  After all
> you have to do this for the *spoken* language anyway -- `cardealer' is
> not pronounced differently than `car dealer'.
> 
> But in a programming language the components of a compound are often
> made-up words themselves so the discompounding needs some help?
>
> It would be an interesting experiment to see if German (or other
> freely-compounding-language) speakers do better at programming
> languages that compound freely, like Lisp (does C++ compound the same
> way?).

Well, since the Pascal/Modula/Oberon development is coming
out of the German speaking area (Wirth at ETH Zuerich) - you can
see the influence there. Most code in these languages I saw were using
uppercasing the first letter of each compound ("CarDealer", "TCarDealer"
for a type, ...). I never have seen this style in Lisp code, though.

Are people using any those naming conventions in larger Lisp projects?
Like making it clear which words name a class, a function, a macro, ...?
From: Howard R. Stearns
Subject: Re: Interning symbols in macro expanders
Date: 
Message-ID: <357C697E.D67@elwood.com>
Rainer Joswig wrote:
> 
> Tim Bradshaw <···@aiai.ed.ac.uk> writes:
> 
> > Completely off-topic (but at least it's yet another lisp is
> > slower/faster/better/worse than C++ thread):
> ;-)
> 
> > I've always suspected that the reason compounding in German can work
> > reasonably is that people have very fast recognition of real words, so
> > the compounds can be discompounded (?) very efficiently.  After all
> > you have to do this for the *spoken* language anyway -- `cardealer' is
> > not pronounced differently than `car dealer'.
> >
> > But in a programming language the components of a compound are often
> > made-up words themselves so the discompounding needs some help?
> >
> > It would be an interesting experiment to see if German (or other
> > freely-compounding-language) speakers do better at programming
> > languages that compound freely, like Lisp (does C++ compound the same
> > way?).
> 
> Well, since the Pascal/Modula/Oberon development is coming
> out of the German speaking area (Wirth at ETH Zuerich) - you can
> see the influence there. Most code in these languages I saw were using
> uppercasing the first letter of each compound ("CarDealer", "TCarDealer"
> for a type, ...). I never have seen this style in Lisp code, though.
> 
> Are people using any those naming conventions in larger Lisp projects?
> Like making it clear which words name a class, a function, a macro, ...?

In Eclipse, we faced a number of problems in translating Lisp to
READABLE C:

 - Lisp has separate namespaces for functions, special variables, named
blocks, and go tags.  C's identifier namespace is more limited.

 - Function names can be defined in lisp using lists as well as
symbols.  (setf foo) is standard, and some implementations, including
Eclipse, generate extended function names for methods that use a list
form.

 - Functions can't be lexically defined in C (though some C compilers
such as gcc do allow this in at least a second class way).  In order to
have each Lisp function generate a corresponding C function, nested Lisp
functions need a C name that reflects their lineage.

 - Lisp symbols allow lots of character that are not allowed in C, so
there needs to be a mapping of, for example, punctuation characters to
identifier substrings.  These substrings must not be confused with Lisp
symbol names consisting of the same letters.

 - There is no package system in C.

 - There is no LET in C, where a variable can be initialized using a
variable with the same name in an enclosing scope.  Instead, variables
of similar names need to be renamed.  A similar problem occurs with
nested function definitions and anonymous functions (lambdas), and with
uninterned symbols that must be considered unique.

All of this had to be dealt with while following standard C practice,
and keeping things readable.

Details of how this is handled is given at
http://www.elwood.com/eclipse/names.htm, but the basic idea is to
concatenate names using specialized cases for different meanings.  Here
are some highlights:

+ In general, Lisp function names get captialized and hyphens removed. 
FOO-BAR => FooBar.  Lisp symbols act like "constant" variables, and are
in all capitals, with hypens replaced by underscores.  FOO-BAR =>
FOO_BAR.  Local variables appear in lower case, with hypens replaced by
underscores.  This is standard C practice.

+ Identifiers that have global or file scope are package qualified using
an assigned name for the package as a prefix.  (The default is the
shortest package name or nickname.)  Package prefixes appear in all
lower case, which doesn't normally happen for the unqualified part of an
identifer.

+ Nested function names use a list-form extended name syntax internally,
where the list forms a chain from outermost to innermost function name.

+ When renaming is required, a numbered suffix is appended.  The suffix
contains '__R', or '__r', which would nor normally appear in identifiers
of the given type.

+ Extended function names use various concatenation techniques, but all
involve finding a case that would not normally appear.  For example,
x:foo-bar => xFooBar, while (setf x:foo-bar) => xSETF_FooBar

+ Symbols that would normally require escaping because of non-standard
case, have the escape characters as part of their C "name".  This name
then has all non-alphanumeric characters replaced by the "character
name", using a contrasting case.
From: Kelly Murray
Subject: Re: Interning symbols in macro expanders
Date: 
Message-ID: <nmra15q9dk.fsf@charlotte.i-have-a-misconfigured-system-so-shoot-me>
> HOWEVER... CLOS did really the right thing in making the textually
> verbose but all-in-all stylistically subtle change of moving away from
> "conc-names" and what was sometimes called "symbolconc'ing" (pronounced

This does avoid the problem of which package to intern the created
symbol in, which also relates to whether it is exported as well.
However it makes class definitions very verbose and "low-level"
specifications, which I find inappropriate for a high-level scripting language.

For the SilkScript HTML scripting language used in the Charlotte web server,
I've adopted implicit generation of slot accessors using "." as
the character which seperates the class name from the slot name, e.g.

(class item ()
 (cart  :initform nil)
 (price :initform 0)
 )

Generates the accessors #'item.cart and #'item.price.
This behavior can be overridden by suppling an :accessor value,
(class item ()
 (cart :accessor item-is-in-cart))
Or by giving nil as the accessor, it simply surpresses the default
accessor generation.

Moreover, I don't define accessors as generic functions.
In my implementation of CLOS, these are straight functions, that are
in fact declared inline which compile into slot-value calls that
further compile into very fast and direct slot-value accessor
machine instructions.
This generates slot access that is a FACTOR OF 4 FASTER
than ANSI CLOS. 

-Kelly Murray  ···@franz.com
 
From: Marco Antoniotti
Subject: Re: Interning symbols in macro expanders
Date: 
Message-ID: <lwpvgotj4q.fsf@galvani.parades.rm.cnr.it>
Kelly Murray <···@franz.com> writes:

	...

> In my implementation of CLOS, these are straight functions, that are
> in fact declared inline which compile into slot-value calls that
> further compile into very fast and direct slot-value accessor
> machine instructions.
> This generates slot access that is a FACTOR OF 4 FASTER
> than ANSI CLOS. 

Then how do you deal with 

(defclass x () ((a :accessor a :initform 33)))

(defclass y (x) ((b :accessor b :initform 33)))

(defmethod a :after ((an-x x)) (format t "Just got the A slot of an X~%"))

?

I am just curious. You must do something about dispatching. Unless you
forgo ANSI CLOS.

-- 
Marco Antoniotti ===========================================
PARADES, Via San Pantaleo 66, I-00186 Rome, ITALY
tel. +39 - (0)6 - 68 80 79 23, fax. +39 - (0)6 - 68 80 79 26
http://www.parades.rm.cnr.it
From: Tim Bradshaw
Subject: Re: Interning symbols in macro expanders
Date: 
Message-ID: <ey3emx4nl6g.fsf@dubh.aiai.ed.ac.uk>
* Marco Antoniotti wrote:
[About inlined slot accesses & so forth]

> Then how do you deal with 

> (defclass x () ((a :accessor a :initform 33)))

> (defclass y (x) ((b :accessor b :initform 33)))

> (defmethod a :after ((an-x x)) (format t "Just got the A slot of an X~%"))

What another implementation (Genera) does seems to be something like
this, on calling an accessor:

	check (very quickly) if there are any aux methods defined on
	the accessor.

	If there are then punt to something which does the full CLOS
	dispatch.

	If there are not, then do something that is very fast.

All of this code is inlined (except the call to the full dispatch),
and is very quick.  I don't know how much the checking for aux methods
depends on having machine-level support -- I don't think it needs to
have since it should be possible to have a flag somewhere in the GF
object which is simply set if aux methods are defined.

The good part of this is that accessors are very quick -- from memory
they are fairly comparable with structure accessors, and faster than
function call.

The bad part is that, if there *are* aux methods, you lose badly and
everything gets much slower than function call (and it conses).  This
can be worked around by declaring the accessor notinline, which
prevents any of this optimisation happening in the first place, so you
just get normal CLOS dispatch.

All this may be wrong, or a simplification -- it's just what I deduced
by disassembling things, when trying to understand why defining aux
methods on accessors had such bad performance effects, and how I could
get around it.

If anyone still knows this, it would be quite interesting to know how
much of the Symbolics CLOS implementation depended in important ways
on the HW, and how much was just smart implementation, because it does
perform really quite well, by the standards of the machine.

--tim
From: Kelly Murray
Subject: Re: Interning symbols in macro expanders
Date: 
Message-ID: <nmaf7pqcr4.fsf@charlotte.i-have-a-misconfigured-system-so-shoot-me>
> > In my implementation of CLOS, these are straight functions, that are
> > in fact declared inline which compile into slot-value calls that
> > This generates slot access that is a FACTOR OF 4 FASTER

> Then how do you deal with 
> (defclass x () ((a :accessor a :initform 33)))
> (defclass y (x) ((b :accessor b :initform 33)))
> (defmethod a :after ((an-x x)) (format t "Just got the A slot of an X~%"))

Since slot accessors are not methods, the above would not work.
In my experience, 99% of the time slot accessors are not used as
general methods. In ANSI CLOS, you pay a big price to get behavior
that is only used 1% of the time.  A poor design decision.

If you need full method support, it is rather easy to get it:

(defclass x () ((a :accessor fast-a :initform 33)))
(defclass y (x) ((b :accessor fast-b :initform 33)))
(defmethod a ((an-x x)) (fast-a an-x))
(defmethod a :after ((an-x x)) (format t "Just got the A slot of an X~%"))

Let me also add that in my implementation, I support a static
single-inheritance "base-class" declaration, (Dlan calls primary class)
which allows fixed offset indexing of slots along the single
inheritance chain of base-classes
and furthermore eliminates non-bound checking
which makes object slot access as fast as defstruct, rendering
defstruct obsolete.  To clarify:

(defclass bottom ()
 ((slot0 :accessor bottom.slot0 :initform nil)
  (slot1 :accessor bottom.slot1 :initform nil))
 (:base-class t))

The slot accessor bottom.slot0 compiles into essentially (svref obj 0).
Multiple inheritance still works, but only single inheritance for
base-classes is allowed.

-Kelly Murray     ···@franz.com
From: Rainer Joswig
Subject: Re: Interning symbols in macro expanders
Date: 
Message-ID: <solgqwhn.fsf@lise.lavielle.com>
Kelly Murray <···@franz.com> writes:


> Let me also add that in my implementation, I support a static
> single-inheritance "base-class" declaration, (Dlan calls primary class)
> which allows fixed offset indexing of slots along the single
> inheritance chain of base-classes
> and furthermore eliminates non-bound checking
> which makes object slot access as fast as defstruct, rendering
> defstruct obsolete.  To clarify:
> 
> (defclass bottom ()
>  ((slot0 :accessor bottom.slot0 :initform nil)
>   (slot1 :accessor bottom.slot1 :initform nil))
>  (:base-class t))
> 
> The slot accessor bottom.slot0 compiles into essentially (svref obj 0).
> Multiple inheritance still works, but only single inheritance for
> base-classes is allowed.

Digitool calls this "Primary Class" for MCL. Maybe a good
opportunity to find a common name across all the
implementations.
From: Sashank Varma
Subject: Re: Interning symbols in macro expanders
Date: 
Message-ID: <varmas-0806981018290001@129.59.192.40>
In article <···············@world.std.com>, Kent M Pitman
<······@world.std.com> wrote:

> Remember, I'm not thinking these things up on the fly--they are hard
> to anticipate if you've never seen them but they are memory exercises
> to me.  And bad memories, say the cognitive scientists, are easier to
> remember because adrenaline enhances long-term memory storage. :-)

I don't know about the effects of adrenaline, but there certainly is a
lot of evidence from cognitive psychology that novices laboriously
compute solutions to difficult problems (when they can solve them at
all!) whereas experts have seen it all before, and can simply retrieve
them from long-term memory.

(I'm thinking of work by Chase & Simon, Ericsson, Logan, and Bransford,
for those who care.)

Sashank
From: Kent M Pitman
Subject: Re: Interning symbols in macro expanders
Date: 
Message-ID: <sfw4sxvdffi.fsf@world.std.com>
······@ctrvax.vanderbilt.edu (Sashank Varma) writes:

> I don't know about the effects of adrenaline, but there certainly is a
> lot of evidence from cognitive psychology that novices laboriously
> compute solutions to difficult problems (when they can solve them at
> all!) whereas experts have seen it all before, and can simply retrieve
> them from long-term memory.

Yeah, I saw a special on PBS hosted by Alan Alda called "Pieces of
Mind" -- a wonderful piece, by the way; if you get a chance to see it
on tv or to rent it, you should.  Some VERY interesting brain
experiments, not just the one described below.

They did some interesting experiments with throwing rats into water
with steep walls and only one hidden plastic platform that would save
them from drowning.  It took lots of time and effort to find the
platform, during which they were obviously panicked. But even several
weeks after, they remembered EXACTLY where the hidden platform was and
swam right toward it the second time the experiment was repeated.
They repeated the same experiment with the adrenaline release
chemically suppressed and the rat just swam about randomly the second
time, as if the memory of the platform's location had not been fixed
into long term memory.  (A very nicely constructed experiment if you
don't mind scaring a little furry thing half to death.)

The moral is supposed to be that there's value not only in outrunning
the lion but in remembering where he was standing, and that adrenaline
apparently eases short->long term memory promotion.

I make the further assumption that if one is passionate about what one
learns, one remembers better.  Keep that in mind the next time someone
tells you you're taking things too seriously...

Anyway, those of us who've been around the Lisp community a long time
bringing you the good and bad of what Lisp has to offer do care a lot
and do have very intense memories of each success and failure along
the way. So there you go--anecdotal evidence at its very best. :-)
From: Axel Schairer
Subject: Re: Interning symbols in macro expanders
Date: 
Message-ID: <ydjra14c9pt.fsf@dfki.de>
Rainer Joswig <······@lise.lavielle.com> writes:

> Axel Schairer <········@dfki.de> writes:
> 
> > Now, Graham (On Lisp, pp. 136-7) tells me, that 
> > 
> > 	(defmacro m (name ...)
> > 	  `(defun ,(intern (format nil "PREFIX-~A" 'name)) ...))
> 
> There is a quote before name?

I am sorry.  No there shouldn't be one, you are perfectly right.  But
the issue was something different, as you noticed.  Thanks for your
advise.

Just to be fair, the example from Graham literally reads (Paul Graham,
On Lisp, p. 136):

<cite>
This concise but rather pathological example,

(defmacro string-call (opstring &rest args)          ; wrong
  `(,(intern opstring) ,@args))

defines a macro which [snip] 

The expansion will thus depend on the package at the time the
expansion is generated.
</cite>

And still I am puzzled why on p.267, Graham essentially uses this
approach without commenting.  What have I've been overlooking?

Axel