Subject: Confused by #() in clisp

From: Dave Pearson <[email-masked]>
Date: Fri, 20 Nov 1998 07:49:55 +0000

First off I'll say that the following may simply be down to my lack of
understanding of lisp, I dabble, that's all.

I wonder if someone can explain why the following doesn't work with clisp?
Correct me if I'm wrong but it is possible to "hard code" an array by doing
something along the lines of:

  (setq a #(1 2 3 4))

and, if I do this in ACL or Corman Lisp it works fine. However, in clisp I
get:

> (setq a #(1 2 3 4))

*** - EVAL: illegal form #(1 2 3 4)
1. Break> 

Is there are simple reason for this or am I missing something obvious? The
version of clisp I'm running is:

> (lisp-implementation-version )
"1998-09-09 (September 1998)"

-- 
Take a look in Hagbard's World: |   w3ng - The WWW Norton Guide reader.
http://www.acemake.com/hagbard/ |     eg - Norton Guide reader for Linux.
http://www.hagbard.demon.co.uk/ |    weg - Norton Guide reader for Windows.
Free software, including........| dgscan - DGROUP scanner for Clipper.

---

From: "Jim Arvo" <[email-masked]>
Date: Fri, 20 Nov 1998 04:32:59 -0800

> *** - EVAL: illegal form #(1 2 3 4)

Does this really work in ACL?  It shouldn't!  Let me explain.  What do you
think would happen if you typed in (setq x (a b c)) ?

Lisp would complain, right?  The problem is that it's trying to evaluate
the thing on the right.  Even though it's a perfectly fine representation of
a list, this causes an error.  Same with

(setq a #(1 2 3 4))

The thing on the right is a perfectly fine representation of a "vector",
but SETQ is trying to *evaluate* it.  You see, "#(" is a signal to the
Lisp *reader* that what follows are elements of a vector.  By the time
SETQ sees it, it's already assembled, and SETQ tries to evaluate it.  Error.
If you try typing in

(setq a '#(1 2 3 4))

you'll see that it works.  Your confusion probably stems for the similarity
with the notation #'foo, which is a shorthand for (function foo), which is
something that indeed needs to be *evaluated*!

-- Jim

---

From: Rodrigo Ventura <[email-masked]>
Date: Fri, 20 Nov 1998 13:00:32 GMT

Your explanation is quite illustrative, but I'm afraid it
misses the point completely. For instance, following you line of
reasoning, the correct way to add 1 with 2 would be (+ '1 '2). But in
fact, 1 and 2 are considered by the _reader_ as self-evaluating
constants!

        Recall that 'foobar means (quote foobar). The ' notation is
just a reader macro, expanding to the quote form. Strings are another
example of self-evaluating constants. The question is, why on the
earth are arrays any different? For instance (from CLtL2) #o33 and
#.(* 3 3 3) both evaluate to 27, and they are both readmacros.

        What is going on? I guess it is necessary to distinguish
between the _reader_ and the _evaluator_. The reader reads numbers and
vectors ok, the question is what shall the evaluator do with them. At
page 70 of the CLtL2, Steele states: "All numbers, characters,
strings, and bit-vectors are self-evaluating forms.[...] The empty
list (), [...] is also a self-evaluating form. [...] Keywords ([...])
also evaluate to themselves" This is very clear to me, although I
still do not understand why Steele does not mention arrays and vectors
in that list. Did he forgot them? 8-)

        May I attempt an explanation? The list enumerated by Steele
comprises only "small" objects, or objects that need no memory
allocation, that can be stored in a machine word. Arrays, as well as
vectors, need memory allocation, and therefore require an explicit
quote. Maybe this is important to the compiler, to know how to deal
with constants and inline constants. But this explanation fall far
from the beauty of the abstract language.

        Best Regards,

-- 
--

*** Rodrigo Martins de Matos Ventura, alias <Yoda>
***  [email-masked], http://www.isr.ist.utl.pt/~yoda
***   Teaching Assistant and MSc. Student at ISR:
***    Instituto de Sistemas e Robotica, Polo de Lisboa
***     Instituto Superior Tecnico, Lisboa, Portugal
***      PGP Public Key available on my homepage
*** Key fingerprint = 0C 0A 25 58 46 CF 14 99  CF 9C AF 9E 10 02 BB 2A

---

From: Rainer Joswig <[email-masked]>
Date: Fri, 20 Nov 1998 14:01:53 +0100

>something that indeed needs to be *evaluated*!

Hmm, some external representations can be read back.
#(...) is such a thing.

If you want to evaluate a vector, well, the result is the vector.
It is a Self-Evaluating Object.
See in the ANSI HyperSpec:
  3.1.2.1.3.1 Examples of Self-Evaluating Objects

So, (setq a #(1 2 3 4)) is perfectly legal in ANSI CL.

Rainer Joswig, Lavielle EDV Systemberatung GmbH & Co, Lotharstrasse 2b, D22041
Hamburg, Tel: +49 40 658088, Fax: +49 40 65808-202,
Email: [email-masked] , WWW: http://www.lavielle.com/~joswig/

---

From: Vassili Bykov <[email-masked]>
Date: Fri, 20 Nov 1998 08:38:54 -0500

> in that list. Did he forgot them? 8-)

This is why the Elders gave us the HyperSpec (section 3.1.2.1.3):

<<A form that is neither a symbol nor a cons is defined to be a
self-evaluating object. Evaluating such an object yields the same
object as a result. 

Certain specific symbols and conses might also happen to be
``self-evaluating'' but only as a special case of a more general set of
rules for the evaluation of symbols and conses; such objects are not
considered to be self-evaluating objects. 

The consequences are undefined if literal objects (including self-evaluating
objects) are destructively modified.">>

> from the beauty of the abstract language.

HyperSpec 3.2.4:

<<The functions eval and compile are required to ensure that literal objects
referenced within the resulting interpreted or compiled code objects are the
same as the corresponding objects in the source code. compile-file, on the
other hand, must produce a compiled file that, when loaded with load,
constructs the objects defined by the source code and produces references to
them. 

In the case of compile-file, objects constructed by load of the compiled
file cannot be spoken of as being the same as the objects constructed at
compile time, because the compiled file may be loaded into a different Lisp
image than the one in which it was compiled. This section defines the
concept of similarity which relates objects in the evaluation environment to
the corresponding objects in the run-time environment. ...>>

(followed by a few sections defining the similarity).

-- 
Vassili Bykov      [email-masked]
The Object People  http://www.objectpeople.com
+1(613)225-8812
  "Any sufficiently complicated C or Fortran program contains
  an ad hoc informally-specified bug-ridden slow implementation
  of half of Common Lisp."
  -- Greenspun's Tenth Rule of Programming

---

From: Rodrigo Ventura <[email-masked]>
Date: Fri, 20 Nov 1998 14:25:23 GMT

>>>>> "Vassili" == Vassili Bykov <[email-masked]> writes:

    >> in that list. Did he forgot them? 8-)

    Vassili> This is why the Elders gave us the HyperSpec (section 3.1.2.1.3):

    Vassili> <<A form that is neither a symbol nor a cons is defined to be a
    Vassili> self-evaluating object. Evaluating such an object yields the same
    Vassili> object as a result. 

        So we have a contradiction in hands, don'te we? Not quite: in
the same page, it can be read: "X3J13 voted in October 1988 <72> to
specify that all standard Common Lisp data objects other than symbols
and lists (including defstruct structures defined without the :type
option) are self-evaluating." This is very clear. You are _right_,
CLISP should be corrected in this detail (I don't know how it works
with the brand new CLISP version).

        CLISP's implementation notes say nothing about the CLtL2
section 5.1, which defines this issue.

        I wonder what Bruno thinks about this...

        Best Regards,

-- 
--

---

From: Sam Steingold <[email-masked]>
Date: 20 Nov 1998 09:37:34 -0500

Others answered in depth.  My answer has the only advantage - brevity.

>>>> In message <[email-masked]>
>>>> On the subject of "Confused by #() in clisp"
>>>> Sent on Fri, 20 Nov 1998 00:13:45 -0800 (PST)
>>>> Honorable Dave Pearson <[email-masked]> writes:
 >> 

In ANSI CL #(...) is self-evaluating, but not in CLtL1.
To get strict ANSI compliance, run clisp with "-a" command line switch.
Then you will get (setq a #(1 2)) working.

-- 
Sam Steingold (http://www.goems.com/~sds) running RedHat5.1 GNU/Linux
Micros**t is not the answer.  Micros**t is a question, and the answer is Linux,
(http://www.linux.org) the choice of the GNU (http://www.gnu.org) generation.
Two wrongs don't make a right, but three rights make a left.

---

From: Bruno Haible <[email-masked]>
Date: Fri, 20 Nov 1998 16:36:36 +0100 (MET)

> In ANSI CL #(...) is self-evaluating, but not in CLtL1.

Yes.

> Then you will get (setq a #(1 2)) working.

The command line switch "-a" only exists in recent development snapshots.
In released CLISP, you can achieve the same effect through the option

                        -p CL-USER

which puts you in package COMMON-LISP-USER, a package with better ANSI CL
compliance than the default USER package.

                           Bruno

---

From: Dave Pearson <[email-masked]>
Date: Fri, 20 Nov 1998 14:42:33 +0000

> So, (setq a #(1 2 3 4)) is perfectly legal in ANSI CL.

[Sorry to carry this on] So does this mean that there is a "problem" with
clisp in respect to the above?

---

From: Dave Pearson <[email-masked]>
Date: Fri, 20 Nov 1998 14:39:46 +0000

On Fri, Nov 20, 1998 at 04:18:32AM -0800, Jim Arvo wrote:

> Does this really work in ACL?  It shouldn't!  

Sure does:

 USER(1): (setq foo #(1 2 3))
 #(1 2 3)
 USER(2): (aref foo 0)
 1

> Let me explain.  What do you think would happen if you typed in (setq x (a
> b c)) ?
> 
> Lisp would complain, right?  

It would complain if (please excuse my terminology) no function was bound to
the symbol A (and nothing was bound to the symbols B and C). Otherwise the
result of (a b c) would be bound to x. However, I thought the use of # made
this work a little different?

> Your confusion probably stems for the similarity with the notation #'foo,
> which is a shorthand for (function foo), which is something that indeed
> needs to be *evaluated*!

Perhaps. What further confuses me is that it does work in other lisps and
also that in clisp you can do things like:

 > (setq foo #c(1 2))
 #C(1 2)

without the need to "escape" the #. I guess the point here is that it isn't
a "problem" with clisp but is instead a problem with my understanding of
reader macros?

---

From: Dave Pearson <[email-masked]>
Date: Fri, 20 Nov 1998 15:44:44 +0000

On Fri, Nov 20, 1998 at 06:36:51AM -0800, Sam Steingold wrote:

> In ANSI CL #(...) is self-evaluating, but not in CLtL1.  To get strict
> ANSI compliance, run clisp with "-a" command line switch.  Then you will
> get (setq a #(1 2)) working.

Is this a feature of some unannounced version?

davep@hagbard:~$ clisp -a
clisp: invalid command-line option, try `clisp --help'

davep@hagbard:~$ clisp -q -x "(lisp-implementation-version)"
"1998-09-09 (September 1998)"

---

From: Gilbert Baumann <[email-masked]>
Date: 23 Nov 1998 10:23:23 +0100

> > which is a shorthand for (function foo), which is something that indeed

  Well, I personally see #'foo more as a constant than as something to
  be truly evaluated, which is perhaps not the true story. Actually
  (FUNCTION ..) is a shift in evaluation rules from evaluating values
  to evaluating (not! invoke) functions.

> a "problem" with clisp but is instead a problem with my understanding of

  You seem to be a bit confused about external and internal
  representation. You do not escape the `#' by the quote character (')
  but the real object.
  
  The reader is separated from the interpreter or compiler. The reader
  simply turns the stream of characters it is faced to into some
  internal representation. There is syntax for a lot of different
  types of things (lists, symbol, numbers etc.) Amoung these are
  vectors ("#(...)") and complex numbers ("#c(..)"). The interpreter
  or compiler has absolutely no knowledge about the particular syntax
  involved. The code it trys to compile or evaluate must not even
  originate from parsing but could as well been constructed by another
  Lisp function.
  
  The interpreter has its rules how to evaluate some objects it is
  faced to. Symbols act like variables, lists stand for function
  invokation most of time, some object evaluate to itself (e.g.
  numbers). Then you have the quote thingie to prohibit actual
  evaluation of some object. The syntax (e.g '(a b) ) is yet only a
  convention the reader knowns about; internally it is e.g. 
  (QUOTE (A B)), which is what the interpreter sees.
  
  Now, there are also some objects, which are neither self-evaluating
  nor have any other particular evaluation rule defined for them. E.g.
  vectors! You name it. So to have some expression, which evaluates to
  a vector, you have to quote it. When you type '#(a b) the reader
  turns it into (QUOTE #(A B)) -- A list of two elements, the first is
  the symbol QUOTE, the seconds is a vector. The interpreter sees
  QUOTE as the first element of a list and thinks "Ah, the user wants
  to quote something; Give him simply the second element of this
  list." You could quote anything and the interpreter simply returns
  it verbatim.

  Whether the need to quote vectors is a good thing, is something I do
  not care about. I got used to it. And if it works without quote in
  some implementation it is IHMO no excuse to leave it out, because of
  portability reasons -- You never know, which arcane implementation
  of CL you might want to get in touch with your code.

  Apologies, if this is a bit long, but I am too tired to express my
  ideas any shorter, since it is virtually late.

  Gilbert.

-- 
;;; You know you have hacked Lisp too much, when you m-c-x in a C buffer.

---

From: Rainer Joswig <[email-masked]>
Date: Mon, 23 Nov 1998 11:31:12 +0100

>  of CL you might want to get in touch with your code.

This has been changed in ANSI CL.

---

From: Gilbert Baumann <[email-masked]>
Date: 23 Nov 1998 13:25:55 +0100

Moin Moin,

> This has been changed in ANSI CL.

  Sure, but I was talking about portability across CL implementations;
  not every impl. is ANSI CL. It perhaps depends; if you say "Hey, I
  only code according to the ANSI CL standard" everything looks
  promising. If you want to keep a back door open to use some not so
  hot CL like say GCL, you learn to stay away from ANSI CL features
  not really needed.

Gilbert.