I had a question I was hoping someone could help me with. I'm writing
a program where I need to parse this list, but it makes things a lot
easier if I pass it the list in reverse order and some NILs appended to
either side. Since the lists I'm dealing with are quite long, I wanted
to try to make the code as efficient as possible. What I tried to do
was this:
(defun fixlist (alst)
(nreverse (nconc '(NIL)
'(NIL)
'(NIL)
'(NIL)
(copy-list alst)
'(NIL)
'(NIL)
'(NIL))))
This code works neither in clisp nor in openmcl. Or rather, it works
the first time after I load it and then hangs when I try to call it
again. Changing it to
(defun fixlist (alst)
(nreverse (append '(NIL)
'(NIL)
'(NIL)
'(NIL)
(copy-list alst)
'(NIL)
'(NIL)
'(NIL))))
seems to make it work perfectly in clisp, but in openmcl I get results
like this:
? (fixlist '(1 2 3))
(NIL NIL NIL 3 2 1 NIL NIL NIL NIL)
? (fixlist '(a b c))
(NIL NIL NIL NIL 1 2 3 NIL NIL NIL NIL NIL C B A NIL NIL NIL NIL)
Changing it to
(defun fixlist (alst)
(reverse (append '(NIL)
'(NIL)
'(NIL)
'(NIL)
(copy-list alst)
'(NIL)
'(NIL)
'(NIL))))
and not using any destructive functions at all makes it work in openmcl
as well.
I was wondering if anyone could please exlpain to what problems the
destructive functions are causing. As far as I can tell I'm only
modifying cons structures I've just created so I thought it would be
okay to use the destructive functions to save time. Thanks!
······@gmail.com wrote:
> I had a question I was hoping someone could help me with. I'm writing
> a program where I need to parse this list, but it makes things a lot
> easier if I pass it the list in reverse order and some NILs appended to
> either side. Since the lists I'm dealing with are quite long, I wanted
> to try to make the code as efficient as possible. What I tried to do
> was this:
>
> (defun fixlist (alst)
> (nreverse (nconc '(NIL)
> '(NIL)
> '(NIL)
> '(NIL)
> (copy-list alst)
> '(NIL)
> '(NIL)
> '(NIL))))
[...]
> I was wondering if anyone could please exlpain to what problems the
> destructive functions are causing. As far as I can tell I'm only
> modifying cons structures I've just created [...]
No, you're not. Quoted lists like '(1 2 3) or (quote (nil)) are literal
data, just like literal strings ("Hello, World!") or numbers (42), etc.
A compiler is allowed to create them at compile time and insert them as
constants in the code. Especially, a compiler is also allowed to have
multiple literals share the same data, so it can be that in some
implementations all your '(nil) are one and the same.
You should say (nconc (list nil) (list nil) ...), or (nconc (list nil
nil nil) ...) instead. (list ...) is guaranteed to create a fresh list
at runtime.
Pascal
--
My website: http://p-cos.net
Closer to MOP & ContextL:
http://common-lisp.net/project/closer/
·······@gmail.com" <······@gmail.com> writes:
> Thank you very much. That explains everything.
I'd write it more concisely as:
(defun fix-list (list)
(nreverse (append (make-list 4 nil) list (make-list 4 nil))))
Since list is not the last argument of append, it gets copied automatically,
as well as the first list of NIL, but for 4 conses, I prefer the above to:
(nreverse (nconc (make-list 4 nil) (append list (make-list 4 nil))))
Another alternative would be:
(nconc (make-list 4 nil) (reverse (nconc (make-list 4 nil) list)))
or:
(list* nil nil nil nil (reverse (list* nil nil nil nil list)))
letting REVERSE do the copying of LIST.
--
__Pascal Bourguignon__ http://www.informatimago.com/
"Our users will know fear and cower before our software! Ship it!
Ship it and let them flee like the dogs they are!"
On Fri, 23 Dec 2005 08:36:53 +0100, Pascal Costanza wrote:
> No, you're not. Quoted lists like '(1 2 3) or (quote (nil)) are
> literal data, just like literal strings ("Hello, World!") or numbers
> (42), etc. A compiler is allowed to create them at compile time and
"Allowed to" is too weak: it's /required/ to (and it doesn't create
them at compile time, it creates them at read time -- QUOTE returns
the very value inside the QUOTE form!)
> insert them as constants in the code. Especially, a compiler is also
> allowed to have multiple literals share the same data, so it can be
The file-compiler can do that; the in-core compiler (COMPILE function)
can't.
--
Quid enim est stultius quam incerta pro certis habere, falsa pro veris?
-- Cicero
(setq reply-to
(concatenate 'string "Paul Foley " "<mycroft" '(··@) "actrix.gen.nz>"))
Paul Foley <···@below.invalid> (http://public.xdi.org/=pf) writes:
> On Fri, 23 Dec 2005 08:36:53 +0100, Pascal Costanza wrote:
>
> > No, you're not. Quoted lists like '(1 2 3) or (quote (nil)) are
> > literal data, just like literal strings ("Hello, World!") or numbers
> > (42), etc. A compiler is allowed to create them at compile time and
>
> "Allowed to" is too weak: it's /required/ to (and it doesn't create
> them at compile time, it creates them at read time -- QUOTE returns
> the very value inside the QUOTE form!)
>
> > insert them as constants in the code. Especially, a compiler is also
> > allowed to have multiple literals share the same data, so it can be
>
> The file-compiler can do that; the in-core compiler (COMPILE function)
> can't.
I believe you are thinking of coalescing here. Literals (objects) in
COMPILEd code are required to reference (as in eql) the literals
(objects) in the source code. So, if a literal in the source is
already "coalesced", say by the reader, then the COMPILEd code will
refer to only one such object for that literal. So, the thrust of
what Pascal is saying here still stands.
/Jon
--
'j' - a n t h o n y at romeo/charley/november com
In article <··············@rigel.goldenthreadtech.com>,
jayessay <······@foo.com> wrote:
> Paul Foley <···@below.invalid> (http://public.xdi.org/=pf) writes:
>
> > On Fri, 23 Dec 2005 08:36:53 +0100, Pascal Costanza wrote:
> >
> > > No, you're not. Quoted lists like '(1 2 3) or (quote (nil)) are
> > > literal data, just like literal strings ("Hello, World!") or numbers
> > > (42), etc. A compiler is allowed to create them at compile time and
> >
> > "Allowed to" is too weak: it's /required/ to (and it doesn't create
> > them at compile time, it creates them at read time -- QUOTE returns
> > the very value inside the QUOTE form!)
> >
> > > insert them as constants in the code. Especially, a compiler is also
> > > allowed to have multiple literals share the same data, so it can be
> >
> > The file-compiler can do that; the in-core compiler (COMPILE function)
> > can't.
>
> I believe you are thinking of coalescing here. Literals (objects) in
> COMPILEd code are required to reference (as in eql) the literals
> (objects) in the source code. So, if a literal in the source is
> already "coalesced", say by the reader, then the COMPILEd code will
> refer to only one such object for that literal. So, the thrust of
> what Pascal is saying here still stands.
The reader is not allowed to coalesce constants, AFAIK. Only the
file-compiler can. I think the justification for this is that it's
difficult to come up with a precise specification of the isomorphism
between literals across different implementations and execution
environment, so we allow maximum implementation flexibility and tell
programmers not to depend on any particular mechanism. But when
everything is staying within the same runtime environment, the basic
rules for how the reader works can apply.
Maybe this wasn't a good idea. We worked hard to eliminate the
differences that some earlier Lisp dialects had between the compiler and
interpreter. Having this difference between the file-compiler and
in-core compiler seems like a wart. As a result, it's likely that the
following simple function will behave differently depending on whether
it's compiled by COMPILE or COMPILE-FILE:
(defun compile-file-p ()
"Should return NIL when COMPILEd, may return T when COMPILE-FILEd."
(eq '(nil) '(nil)))
On the other hand, it generally takes some perverse programming for this
to cause an issue with a real-world application, so it's a pretty minor
issue.
--
Barry Margolin, ······@alum.mit.edu
Arlington, MA
*** PLEASE post questions in newsgroups, not directly to me ***
*** PLEASE don't copy me on replies, I'll read them in the group ***
Barry Margolin <······@alum.mit.edu> writes:
> > I believe you are thinking of coalescing here. Literals (objects) in
> > COMPILEd code are required to reference (as in eql) the literals
> > (objects) in the source code. So, if a literal in the source is
> > already "coalesced", say by the reader, then the COMPILEd code will
> > refer to only one such object for that literal. So, the thrust of
> > what Pascal is saying here still stands.
>
> The reader is not allowed to coalesce constants, AFAIK. Only the
> file-compiler can.
Hence the "scare-quotes". To coalesce literals X and Y from some
source code would mean that they must start out not eql, but their
corresponding objects in the compiled code are eql. But if (eql X Y)
is true, then their corresponding objects in the compiled code of a
COMPILE must also be eql. So, if '(1 2 3) shows up as a literal in
two pieces of some source, and these map to the same object, then they
are eql in the source, and so must be eql in the compiled code.
However, it seems clear now that even with the scare quotes, it was a
bad choice to use the term "coalesce" for this.
> in-core compiler seems like a wart. As a result, it's likely that the
> following simple function will behave differently depending on whether
> it's compiled by COMPILE or COMPILE-FILE:
>
> (defun compile-file-p ()
> "Should return NIL when COMPILEd, may return T when COMPILE-FILEd."
> (eq '(nil) '(nil)))
Interesting. I would have thought otherwise. Here's some data on this:
CL-USER(1): (defun foo () (eq '(1 2 3) '(1 2 3)))
FOO
CL-USER(2): (foo)
NIL ;; !!! a bit odd to me.
CL-USER(3): (compile 'foo)
FOO
NIL
NIL
CL-USER(4): (foo)
T ;;; More like it to my mind, but still odd given the interpreter results
CL-USER(5): (disassemble 'foo)
;; disassembly of #<Function FOO>
;; formals:
;; constant vector:
0: (1 2 3) ;; Looks right to me.
;; code start: #x7140a67c:
0: e3 02 jcxz 4
2: cd 61 int $97 ; EXCL::TRAP-ARGERR
4: 80 7f 97 00 cmpb [edi-105],$0 ; SYS::C_INTERRUPT
8: 74 02 jz 12
10: cd 64 int $100 ; EXCL::TRAP-SIGNAL-HIT
12: 8b 5e 12 movl ebx,[esi+18] ; (1 2 3) [And here we see what I
15: 3b 5e 12 cmpl ebx,[esi+18] ; (1 2 3) would have expected anyway]
18: 74 07 jz 27
20: 8b c7 movl eax,edi
22: f8 clc
23: 8b 75 fc movl esi,[ebp-4]
26: c3 ret
27: 8b 47 e7 movl eax,[edi-25] ; T
30: f8 clc
31: eb f6 jmp 23
33: 90 nop
CL-USER(6):
/Jon
--
'j' - a n t h o n y at romeo/charley/november com
On 24 Dec 2005 01:24:07 -0500, jayessay wrote:
> Barry Margolin <······@alum.mit.edu> writes:
>> > I believe you are thinking of coalescing here. Literals (objects) in
>> > COMPILEd code are required to reference (as in eql) the literals
>> > (objects) in the source code. So, if a literal in the source is
>> > already "coalesced", say by the reader, then the COMPILEd code will
>> > refer to only one such object for that literal. So, the thrust of
>> > what Pascal is saying here still stands.
>>
>> The reader is not allowed to coalesce constants, AFAIK. Only the
>> file-compiler can.
> Hence the "scare-quotes". To coalesce literals X and Y from some
> source code would mean that they must start out not eql, but their
> corresponding objects in the compiled code are eql. But if (eql X Y)
> is true, then their corresponding objects in the compiled code of a
> COMPILE must also be eql. So, if '(1 2 3) shows up as a literal in
> two pieces of some source, and these map to the same object, then they
The literal '(1 2 3) appearing twice (in two pieces of source) can't
"map to the same object", since the list has to be built up at read
time. (Unless you mean something like using #n# notation to put the
same object in two places)
>> in-core compiler seems like a wart. As a result, it's likely that the
>> following simple function will behave differently depending on whether
>> it's compiled by COMPILE or COMPILE-FILE:
>>
>> (defun compile-file-p ()
>> "Should return NIL when COMPILEd, may return T when COMPILE-FILEd."
>> (eq '(nil) '(nil)))
> Interesting. I would have thought otherwise. Here's some data on this:
> CL-USER(1): (defun foo () (eq '(1 2 3) '(1 2 3)))
> FOO
> CL-USER(2): (foo)
> NIL ;; !!! a bit odd to me.
Evaluating (QUOTE x) returns x -- the very same value that occurs in
the QUOTE form, not some "similar" value. The list (1 2 3) in the
first QUOTE form is obviously a different list than the one in the
second QUOTE form, so they /can't/ be EQ.
> CL-USER(3): (compile 'foo)
> FOO
> NIL
> NIL
> CL-USER(4): (foo)
> T ;;; More like it to my mind, but still odd given the interpreter results
Eh? What implementation is this? I'd call that a bug.
--
Quid enim est stultius quam incerta pro certis habere, falsa pro veris?
-- Cicero
(setq reply-to
(concatenate 'string "Paul Foley " "<mycroft" '(··@) "actrix.gen.nz>"))
Paul Foley <···@below.invalid> (http://public.xdi.org/=pf) writes:
> On 24 Dec 2005 01:24:07 -0500, jayessay wrote:
>
>> CL-USER(1): (defun foo () (eq '(1 2 3) '(1 2 3)))
>> FOO
>> CL-USER(2): (foo)
>> NIL ;; !!! a bit odd to me.
>
> Evaluating (QUOTE x) returns x -- the very same value that occurs in
> the QUOTE form, not some "similar" value. The list (1 2 3) in the
> first QUOTE form is obviously a different list than the one in the
> second QUOTE form, so they /can't/ be EQ.
>
>> CL-USER(3): (compile 'foo)
>> FOO
>> NIL
>> NIL
>> CL-USER(4): (foo)
>> T ;;; More like it to my mind, but still odd given the interpreter results
>
> Eh? What implementation is this? I'd call that a bug.
It's probably Allegro CL 6.2 - I recognize the code - and it is
a bug. 7.0 does the right thing.
--
Duane Rettig ·····@franz.com Franz Inc. http://www.franz.com/
555 12th St., Suite 1450 http://www.555citycenter.com/
Oakland, Ca. 94607 Phone: (510) 452-2000; Fax: (510) 452-0182
Paul Foley <···@below.invalid> (http://public.xdi.org/=pf) writes:
>>> in-core compiler seems like a wart. As a result, it's likely that the
>>> following simple function will behave differently depending on whether
>>> it's compiled by COMPILE or COMPILE-FILE:
>>>
>>> (defun compile-file-p ()
>>> "Should return NIL when COMPILEd, may return T when COMPILE-FILEd."
>>> (eq '(nil) '(nil)))
>
>> Interesting. I would have thought otherwise. Here's some data on this:
>
>> CL-USER(1): (defun foo () (eq '(1 2 3) '(1 2 3)))
>> FOO
>> CL-USER(2): (foo)
>> NIL ;; !!! a bit odd to me.
>
> Evaluating (QUOTE x) returns x -- the very same value that occurs in
> the QUOTE form, not some "similar" value. The list (1 2 3) in the
> first QUOTE form is obviously a different list than the one in the
> second QUOTE form, so they /can't/ be EQ.
>
>> CL-USER(3): (compile 'foo)
>> FOO
>> NIL
>> NIL
>> CL-USER(4): (foo)
>> T ;;; More like it to my mind, but still odd given the interpreter results
>
> Eh? What implementation is this? I'd call that a bug.
No, it's a feature. It's called literal folding.
For example, in C, when you have literal strings that are suffixes,
they can share the same storage:
char* p="hello world";
char* q="world";
/* You can have */ q==p+6
/* in addition to the warning of assigning a const char* to a char* */
--
__Pascal Bourguignon__ http://www.informatimago.com/
WARNING: This product attracts every other piece of matter in the
universe, including the products of other manufacturers, with a
force proportional to the product of the masses and inversely
proportional to the distance between them.
Pascal Bourguignon <····@mouse-potato.com> writes:
> Paul Foley <···@below.invalid> (http://public.xdi.org/=pf) writes:
>> Eh? What implementation is this? I'd call that a bug.
>
> No, it's a feature. It's called literal folding.
No, it's a bug. CLHS 3.2.4 states
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.
and
The constraints on literal objects described in this section apply
only to compile-file; eval and compile do not copy or coalesce
constants.
So code processed by compile-file is allowed to coalesce constants, or
do "literal folding" as you call it, but code processed by compile, as
in the grandparent post, is not.
Christophe
On Sat, 24 Dec 2005 10:39:53 +0100, Pascal Bourguignon wrote:
>>> CL-USER(4): (foo)
>>> T ;;; More like it to my mind, but still odd given the interpreter results
>>
>> Eh? What implementation is this? I'd call that a bug.
> No, it's a feature. It's called literal folding.
Yes, and it's fine for the file compiler to do that, but show me where
the in-core compiler is allowed to change the identity of objects!?
The two objects are not EQ going in, so they can't be EQ afterwards.
[Except for fixnums and characters, which don't (per the standard)
have proper identity anyway]
--
Quid enim est stultius quam incerta pro certis habere, falsa pro veris?
-- Cicero
(setq reply-to
(concatenate 'string "Paul Foley " "<mycroft" '(··@) "actrix.gen.nz>"))
Paul Foley <···@below.invalid> (http://public.xdi.org/=pf) writes:
> The literal '(1 2 3) appearing twice (in two pieces of source) can't
> "map to the same object", since the list has to be built up at read
> time.
OK, in that case Barry's points all make sense. I'm still a little
puzzled why a reader couldn't do this. Must be something obvious that
I'm missing. For example, you have some source:
(.... '(1 2 3) .... '(1 2 3) ...)
OK, the reader reads this all in from the starting paren to the ending
paren. Along the way it is building up the internal representation.
What is it about the second literal that the reader can't recognize it
as equal to the first, and thus just have both parts of the rep point
to the same literal object? Or have I just missed where the part in
the spec which simply states that you just can't have the reader doing
this, period, end of story?
> (Unless you mean something like using #n# notation to put the
> same object in two places)
Presumably this might in fact "do the job", but it wasn't what I was
thinking.
> > T ;;; More like it to my mind, but still odd given the interpreter results
>
> Eh? What implementation is this? I'd call that a bug.
Yep, bug.
/Jon
--
'j' - a n t h o n y at romeo/charley/november com
In article <··············@rigel.goldenthreadtech.com>,
jayessay <······@foo.com> wrote:
> Paul Foley <···@below.invalid> (http://public.xdi.org/=pf) writes:
>
> > The literal '(1 2 3) appearing twice (in two pieces of source) can't
> > "map to the same object", since the list has to be built up at read
> > time.
>
> OK, in that case Barry's points all make sense. I'm still a little
> puzzled why a reader couldn't do this. Must be something obvious that
> I'm missing. For example, you have some source:
>
> (.... '(1 2 3) .... '(1 2 3) ...)
>
> OK, the reader reads this all in from the starting paren to the ending
> paren. Along the way it is building up the internal representation.
> What is it about the second literal that the reader can't recognize it
> as equal to the first, and thus just have both parts of the rep point
> to the same literal object? Or have I just missed where the part in
> the spec which simply states that you just can't have the reader doing
> this, period, end of story?
I can't find it now, but I'm pretty sure that somewhere in the
description of the Lisp reader it says that it always returns a fresh
list when it reads the printed representation of a list. This includes
the nested reads that occur for the internal lists.
Is there a search engine for the Hyperspec?
--
Barry Margolin, ······@alum.mit.edu
Arlington, MA
*** PLEASE post questions in newsgroups, not directly to me ***
*** PLEASE don't copy me on replies, I'll read them in the group ***
In article <························@g43g2000cwa.googlegroups.com>,
········@gmail.com wrote:
> Barry Margolin wrote:
> > Is there a search engine for the Hyperspec?
>
> Have you tried:
> http://www.franz.com/search/
Unfortunately, they've included the glossary in their index, with each
letter of the alphabet as a single page. This really screws up the the
matches, because it words in unrelated glossary entries will cause the
whole page to get a good score.
--
Barry Margolin, ······@alum.mit.edu
Arlington, MA
*** PLEASE post questions in newsgroups, not directly to me ***
*** PLEASE don't copy me on replies, I'll read them in the group ***
Barry Margolin <······@alum.mit.edu> writes:
> Is there a search engine for the Hyperspec?
http://www.google.com/search?q=site%3awww.lispworks.com%2fdocumentation%2fHyperSpec+car
--
__Pascal Bourguignon__ http://www.informatimago.com/
HEALTH WARNING: Care should be taken when lifting this product,
since its mass, and thus its weight, is dependent on its velocity
relative to the user.
Pascal Bourguignon <····@mouse-potato.com> writes:
> Barry Margolin <······@alum.mit.edu> writes:
>> Is there a search engine for the Hyperspec?
>
> http://www.google.com/search?q=site%3awww.lispworks.com%2fdocumentation%2fHyperSpec+car
Also,
http://www.franz.com/search/index.lhtml#ansispec
--
Duane Rettig ·····@franz.com Franz Inc. http://www.franz.com/
555 12th St., Suite 1450 http://www.555citycenter.com/
Oakland, Ca. 94607 Phone: (510) 452-2000; Fax: (510) 452-0182
Pascal Bourguignon <····@mouse-potato.com> writes:
> Barry Margolin <······@alum.mit.edu> writes:
>> Is there a search engine for the Hyperspec?
> http://www.google.com/search?q=site%3awww.lispworks.com%2fdocumentation%2fHyperSpec+car
There is a copy of the HyperSpec at http://clhs.lisp.se/, but Google
doesn't index it very well.
Barry Margolin <······@alum.mit.edu> writes:
> In article <··············@rigel.goldenthreadtech.com>,
> jayessay <······@foo.com> wrote:
>
> > Paul Foley <···@below.invalid> (http://public.xdi.org/=pf) writes:
> >
> > > The literal '(1 2 3) appearing twice (in two pieces of source) can't
> > > "map to the same object", since the list has to be built up at read
> > > time.
> >
> > OK, in that case Barry's points all make sense. I'm still a little
> > puzzled why a reader couldn't do this. Must be something obvious that
> > I'm missing. For example, you have some source:
> >
> > (.... '(1 2 3) .... '(1 2 3) ...)
> >
> > OK, the reader reads this all in from the starting paren to the ending
> > paren. Along the way it is building up the internal representation.
> > What is it about the second literal that the reader can't recognize it
> > as equal to the first, and thus just have both parts of the rep point
> > to the same literal object? Or have I just missed where the part in
> > the spec which simply states that you just can't have the reader doing
> > this, period, end of story?
>
> I can't find it now, but I'm pretty sure that somewhere in the
> description of the Lisp reader it says that it always returns a fresh
> list when it reads the printed representation of a list. This includes
> the nested reads that occur for the internal lists.
Ah, OK. Though I haven't yet found that bit yet either. If I find it
I will post; if you, or Duane, find or know where it is, please post
here as well. Thanks,
/Jon
--
'j' - a n t h o n y at romeo/charley/november com
jayessay <······@foo.com> writes:
> Barry Margolin <······@alum.mit.edu> writes:
>
> > In article <··············@rigel.goldenthreadtech.com>,
> > jayessay <······@foo.com> wrote:
...
> > > I'm missing. For example, you have some source:
> > >
> > > (.... '(1 2 3) .... '(1 2 3) ...)
> > >
> > > OK, the reader reads this all in from the starting paren to the ending
> > > paren. Along the way it is building up the internal representation.
> > > What is it about the second literal that the reader can't recognize it
> > > as equal to the first, and thus just have both parts of the rep point
> > > to the same literal object? Or have I just missed where the part in
> > > the spec which simply states that you just can't have the reader doing
> > > this, period, end of story?
> >
> > I can't find it now, but I'm pretty sure that somewhere in the
> > description of the Lisp reader it says that it always returns a fresh
> > list when it reads the printed representation of a list. This includes
> > the nested reads that occur for the internal lists.
>
> Ah, OK. Though I haven't yet found that bit yet either. If I find it
> I will post; if you, or Duane, find or know where it is, please post
> here as well. Thanks,
OK, I'm not convinced I've found this (see one possibility below) and
am giving up. In fact the only two bits that seem to actually
specifically speak to this seem to leave open the possibility that the
literals could be identical:
2.4.1 Left-Paren reader macro defintion:
"The left-parenthesis initiates reading of a list. read is called
recursively to read successive objects until a right parenthesis is
found in the input stream. A list of the objects read is
returned."
Doesn't say a _freshly consed up_ list of the objects is returned.
23.2, the entry for READ:
"read parses the printed representation of an object from
input-stream and builds such an object."
and later:
"return the object read from input-stream."
These two pieces provide some indication that 1) something new is made
("_builds_ such an object", emphasis added) and 2) "return the object
read" may mean the one that was newly built.
But, the object read (in this case) is from the
(-reader-macro-function which as indicated above doesn't say the list
must be freshly consed.
Steele also talks about this a bit (beyond what got into the ANSI
spec.), and indicates that having the reader return identical objects
in these sort of cases is in practice difficult and not always
desirable.
/Jon
--
'j' - a n t h o n y at romeo/charley/november com
In article <··············@rigel.goldenthreadtech.com>,
jayessay <······@foo.com> wrote:
> 2.4.1 Left-Paren reader macro defintion:
>
> "The left-parenthesis initiates reading of a list. read is called
> recursively to read successive objects until a right parenthesis is
> found in the input stream. A list of the objects read is
> returned."
>
> Doesn't say a _freshly consed up_ list of the objects is returned.
Yeah, that's where I was hoping to find it, and was unhappy that it
doesn't say "fresh list".
>
>
> 23.2, the entry for READ:
>
> "read parses the printed representation of an object from
> input-stream and builds such an object."
>
> and later:
>
> "return the object read from input-stream."
>
> These two pieces provide some indication that 1) something new is made
> ("_builds_ such an object", emphasis added) and 2) "return the object
> read" may mean the one that was newly built.
Except that there are some common cases where it *doesn't* return
something new. Most obvious is when it's reading the representation of
a symbol, it will return an existing interned symbol when possible.
I wonder if there's a general statement somewhere that functions return
fresh objects unless the description specifically says that it may
return an existing object.
--
Barry Margolin, ······@alum.mit.edu
Arlington, MA
*** PLEASE post questions in newsgroups, not directly to me ***
*** PLEASE don't copy me on replies, I'll read them in the group ***
On 24 Dec 2005 15:05:40 -0500, jayessay wrote:
> Paul Foley <···@below.invalid> (http://public.xdi.org/=pf) writes:
>> The literal '(1 2 3) appearing twice (in two pieces of source) can't
>> "map to the same object", since the list has to be built up at read
>> time.
> OK, in that case Barry's points all make sense. I'm still a little
> puzzled why a reader couldn't do this. Must be something obvious that
> I'm missing. For example, you have some source:
> (.... '(1 2 3) .... '(1 2 3) ...)
> OK, the reader reads this all in from the starting paren to the ending
> paren. Along the way it is building up the internal representation.
It hits the first embedded list, makes a recursive call to read the
list, and gets the resulting object. When it reads the second
embedded list, the recursive call can't know in advance that it's
going to see a similar list, so it has to build up a new list, right?
Having done that, it doesn't know what the higher-level call has seen,
so it can't notice that this list is similar to the previous one, so
it just returns it. The outer call would then have to examine it to
see if it's similar to the previous one, and replace it. But the
outer call doesn't know the source: it needn't have come from a
literal list; you could have put something like #.*foo* in there, but
replacing /that/ would be very weird: surely the resulting list should
be EQ to *foo*!
--
Quid enim est stultius quam incerta pro certis habere, falsa pro veris?
-- Cicero
(setq reply-to
(concatenate 'string "Paul Foley " "<mycroft" '(··@) "actrix.gen.nz>"))
From: Sam Steingold
Subject: Re: Destructive Functions
Date:
Message-ID: <u8xub3nbv.fsf@gnu.org>
> * <······@tznvy.pbz> [2005-12-22 23:22:47 -0800]:
>
> I had a question I was hoping someone could help me with. I'm writing
> a program where I need to parse this list, but it makes things a lot
> easier if I pass it the list in reverse order and some NILs appended to
> either side. Since the lists I'm dealing with are quite long, I wanted
> to try to make the code as efficient as possible. What I tried to do
> was this:
>
> (defun fixlist (alst)
> (nreverse (nconc '(NIL)
> '(NIL)
> '(NIL)
> '(NIL)
> (copy-list alst)
> '(NIL)
> '(NIL)
> '(NIL))))
>
> This code works neither in clisp nor in openmcl. Or rather, it works
> the first time after I load it and then hangs when I try to call it
> again.
self-modified code is not a very good idea.
http://clisp.cons.org/impnotes/faq.html#faq-self-mod
--
Sam Steingold (http://www.podval.org/~sds) running w2k
http://www.honestreporting.com http://www.savegushkatif.org http://ffii.org/
http://www.dhimmi.com/ http://www.openvotingconsortium.org/
"Syntactic sugar causes cancer of the semicolon." -Alan Perlis
······@gmail.com writes:
> I was wondering if anyone could please exlpain to what problems the
> destructive functions are causing. As far as I can tell I'm only
> modifying cons structures I've just created so I thought it would be
> okay to use the destructive functions to save time. Thanks!
The message that SBCL produces on your code is:
; in: LAMBDA NIL
; (NCONC '(NIL) '(NIL) '(NIL) '(NIL) (COPY-LIST ALST) '(NIL) '(NIL) '(NIL))
;
; caught WARNING:
; Destructive function NCONC called on constant data.
; See also:
; The ANSI Standard, Special Operator QUOTE
; The ANSI Standard, Section 3.2.2.3
I've seen that you've understood what is happening, so my question is
whether seeing this message would have helped you find out earlier
what was going wrong.
Christophe