From: Mikalai
Subject: Popular bug in implementation?
Date: 
Message-ID: <1143258699.569982.210080@u72g2000cwu.googlegroups.com>
Try to do the following in a lisp of your choice:
(setf a '(1 2))
(setf (car a) a)
What do you get, and on which implementation? Please, tell the world
what implementations are OK with this.
In clisp:
[1]> (setf a '(1 2))
(1 2)
[2]> (setf (car a) a)

*** - Lisp stack overflow. RESET

Why? Who knows the answer?
In sbcl, there will be many brackets on the screen before reset.
In gcl:
>(setf a '(1 2))

(1 2)

>(setf (car a) a)


Error: Can't pretty-print.
Fast links are on: do (si::use-fast-links nil) for debugging
Error signalled by SYSTEM:TOP-LEVEL.
Broken at PRIN1.  Type :H for Help.

Wow, we have an answer!! It is print function that is at fault. And we
shall admit, it is a pretty popular bug -- at least three
implementations have it. What about other implementations - franz,
corman, etc.? Can you check?

This is in Python:
>>> a=[1]
>>> a[0]=a
>>> a
[[...]]

Notice how Python's printer works out the problem by ...

From: Kaz Kylheku
Subject: Re: Popular bug in implementation?
Date: 
Message-ID: <1143264727.881670.222930@z34g2000cwc.googlegroups.com>
Mikalai wrote:
> Try to do the following in a lisp of your choice:
> (setf a '(1 2))
> (setf (car a) a)
> What do you get, and on which implementation?

Under BloodLisp 3.14, running on the DeathStation 9000, I get three
10,000 volt electric shocks  in succession, as punishment for each of
the three programming errors. One for the SETF on an undefined
variable, the second for modifying a literal, and the third for trying
to print a circular structure without *PRINT-CIRCLE* set to T.

> Please, tell the world
> what implementations are OK with this.

OK with three undefined behaviors in a row? Oh boy.

> This is in Python:
> >>> a=[1]
> >>> a[0]=a
> >>> a
> [[...]]
>
> Notice how Python's printer works out the problem by ...

Except that this [[...]] doesn't actually represent the structure.
Could you put that into a string, and then read it back to recover that
array?

Moreover, do you not know that Python uses reference counting for
managing memory? How does reference counting deal with circular
structures?

I think you just fed your python a mouse that was about three sizes too
large for its throat.

Lisp has a special variable called *PRINT-CIRCLE*, a generalized
boolean. If this is true, then the cycle detection is performed by the
printer. But you see, the data structure then actually prints out in
such a way that it can be read back to produce a similar structure with
the same cycles:

  ;; turn on cycle detection
  (setf *print-circle* t)

  ;; You must define a variable with DEFVAR or DEFPARAMETER!
  (defvar a (list 1 2))

  ;; You must not change a list literal, that's why we used (LIST 1 2)
to create it!
  (setf (car a) a)

  ;; the result of evaluating the above is a notation which actually
  ;; captures the structure of a list whose first element is itself.

  a -->  #1=(#1# 2)

The #1= means "reader, give the following object numeric tag 1". And
#1# means "reproduce the object from tag 1 here". The reader performs
the necessary backpatching to fill in these references, allowing the
#1# reference to occur in a place where the object isn't complete yet.
From: Mikalai
Subject: Re: Popular bug in implementation?
Date: 
Message-ID: <1143300212.566946.165930@i39g2000cwa.googlegroups.com>
Kaz Kylheku wrote:
> Mikalai wrote:
> > Try to do the following in a lisp of your choice:
> > (setf a '(1 2))
> > (setf (car a) a)
> > What do you get, and on which implementation?
>
> Under BloodLisp 3.14, running on the DeathStation 9000, I get three
> 10,000 volt electric shocks  in succession, as punishment for each of
> the three programming errors. One for the SETF on an undefined
> variable, the second for modifying a literal, and the third for trying
> to print a circular structure without *PRINT-CIRCLE* set to T.
Ha-ha. Agree, funny.
Back to business. Should we tell in tutorials about *PRINT-CIRCLE*, or
should we put it t by default?
Use of setf when symbol does not exist isn't nice. Well, I do not do it
in programs, and at repl my lisps do one same good thing -- create a
special var. Do not call it a mistake, call it a specific knowledge of
lisp implementations :) .
>
> > Please, tell the world
> > what implementations are OK with this.
>
> OK with three undefined behaviors in a row? Oh boy.
I do not get how use of (setf car) is underfined, *when* CLtL2 tells me
that this func is defined for me to *use*. From a perspective of a user
of a language, I honestly do not get what you mean by "underfined".
>
> > This is in Python:
> > >>> a=[1]
> > >>> a[0]=a
> > >>> a
> > [[...]]
> >
> > Notice how Python's printer works out the problem by ...
>
> Except that this [[...]] doesn't actually represent the structure.
> Could you put that into a string, and then read it back to recover that
> array?
>
> Moreover, do you not know that Python uses reference counting for
> managing memory? How does reference counting deal with circular
> structures?
The last time I was doing it, it was GC that collected circles (py2.3,
py2.4). Didn't you know, they kinder have two things working at once,
ref-counting and collection?
>
> I think you just fed your python a mouse that was about three sizes too
> large for its throat.
Actually not. If you try what I did, you'll see for yourself how
quickly it (python) performed.
It is lisps that suprised me by choking. Now we now that it is simply a
default misconfiguration of a printer.
>
> Lisp has a special variable called *PRINT-CIRCLE*, a generalized
> boolean. If this is true, then the cycle detection is performed by the
> printer. But you see, the data structure then actually prints out in
> such a way that it can be read back to produce a similar structure with
> the same cycles:
>
>   ;; turn on cycle detection
>   (setf *print-circle* t)
This is what I needed. Thank you.
>
>   ;; You must define a variable with DEFVAR or DEFPARAMETER!
>   (defvar a (list 1 2))
>
>   ;; You must not change a list literal, that's why we used (LIST 1 2)
> to create it!
>   (setf (car a) a)
What if I need a hash-table? Standard function creates an empty one.
So, if I fear using destructive functions, how should I have a
hash-table with usefull entries?
>
>   ;; the result of evaluating the above is a notation which actually
>   ;; captures the structure of a list whose first element is itself.
>
>   a -->  #1=(#1# 2)
>
> The #1= means "reader, give the following object numeric tag 1". And
> #1# means "reproduce the object from tag 1 here". The reader performs
> the necessary backpatching to fill in these references, allowing the
> #1# reference to occur in a place where the object isn't complete yet.
With #1# reader should probably be able to read it back, right?
From: ······@gmail.com
Subject: Re: Popular bug in implementation?
Date: 
Message-ID: <1143301616.361281.18070@i40g2000cwc.googlegroups.com>
Mikalai wrote:
> Kaz Kylheku wrote:
> > OK with three undefined behaviors in a row? Oh boy.
> I do not get how use of (setf car) is underfined, *when* CLtL2 tells me
> that this func is defined for me to *use*. From a perspective of a user
> of a language, I honestly do not get what you mean by "underfined".

Several people have tried to explain this to you without success.  Let
me try to do so more verbosely.

The problem is not with setf.  Destructive operations are fine.  The
problem is with '(1 2).

Let's try a parallel to C code, even if it is a bad one.

'(1 2) is like "12".  "12" is a string literal in C.  They are
automatically const.

So, for example:

const char *x = "12";
x[0] = '3';

This is illegal in C because x is a const char*.  This doesn't mean
that operator= is bad in C, it just means that you can't, or shouldn't,
use operator= on consts.

(defvar *x* '(1 2))   ;; creates a variable, *x*, that points to a list
literal (a constant)
(setf (car *x*) *x*)  ;; modifies the constant.  this is ILLEGAL

(defvar *x* (list 1 2))  ;; creates a variable, *x*, that points to a
newly created list (like using malloc in C)
(setf (car *x*) *x*)  ;; modifies the list.  this is LEGAL

I hope that helps to make things more clear.

Justin Dubs
From: Mikalai
Subject: Re: Popular bug in implementation?
Date: 
Message-ID: <1143302707.120227.170420@z34g2000cwc.googlegroups.com>
······@gmail.com wrote:
> Mikalai wrote:
> > Kaz Kylheku wrote:
---snip---
>
> (defvar *x* '(1 2))   ;; creates a variable, *x*, that points to a list
> literal (a constant)
> (setf (car *x*) *x*)  ;; modifies the constant.  this is ILLEGAL
>
> (defvar *x* (list 1 2))  ;; creates a variable, *x*, that points to a
> newly created list (like using malloc in C)
> (setf (car *x*) *x*)  ;; modifies the list.  this is LEGAL
>
> I hope that helps to make things more clear.
OK. This is clear now.
So, (quote ...) may create something that looks like list, but
internally *can be* maid rigid, unchangable.
From: Mikalai
Subject: Re: Popular bug in implementation?
Date: 
Message-ID: <1143303350.942233.70150@e56g2000cwe.googlegroups.com>
Ya OK.
Quote:
"""
literal adj. (of an object) referenced directly in a program rather
than being computed by the program; that is, appearing as data in a
quote form, or, if the object is a self-evaluating object, appearing as
unquoted data. ``In the form (cons "one" '("two")), the expressions
"one", ("two"), and "two" are literal objects.''
"""
Got it!
From: Kaz Kylheku
Subject: Re: Popular bug in implementation?
Date: 
Message-ID: <1143308487.711150.119570@i39g2000cwa.googlegroups.com>
Mikalai wrote:
> > I hope that helps to make things more clear.
> OK. This is clear now.
> So, (quote ...) may create something that looks like list, but
> internally *can be* maid rigid, unchangable.

No, you still misunderstand.

What QUOTE does is regurgitate a piece of the program source code as a
datum that is available to that program. So when you try to modify that
something, you are creating a self-modifying program.

That's the real issue, not whether or not that object may be
modifiable. That's a secondary, related problem.

This is not a Lisp issue; it appears in other languages.  For instance,
in the C language, you may not modify a string literal. The following
is undefined behavior:

   "abcd"[0] = 'x';

It actually causes a memory access violation on many C implementations,
because they put string literals into the same area of memory as
executable code, which is mapped by the operating system into read-only
virtual memory pages.

But again, that's a secondary issue. The real issue is that literals
such as strings and lists are part of the program image. Whenever you
evaluate a literal, it doesn't necessarily create a new object: it just
retrieves something from the program image.   If you change that
something, then you can potentially change the value of that
expression! For instance say you have

  (defun return-list () '(1 2))

If you call RETURN-LIST and modify the list, then the next time
somebody calls RETURN-LIST , it may return the modified list!

Moreover, suppose that there is another function in the program:

  (defun return-list-2 () '(1 2))

Guess what, /this/ function can now /also/ returns the modified list!
The Lisp compiler can merge the two literals into a single object in
the program image. Just like the way C compilers can merge identical
strings or substrings into single objects. (And of course strings get
the same treatment in Lisp too).

So you see, when you write self-modifying code, there are things that
may or may not happen. Literals may be in ROM so that the access
appears to work, but no change takes place, without any CPU exception
at all. Literals may be in read-only virtual RAM which kicks an access
violation. Or the modification may work, and not affect the original
expression, affect the original expression or even affect other
expressions in the program, perhaps just in the same module, or
throughout.

There are many choices, all of which represent design points that are
rational and sensible, and the best choice in a given situation. So it
wouldn't make sense to define any one of those behaviors as the
required one.

If detection of error were required, it would be inefficient to
implement without the hardware support: the program's performance would
be penalized with run-time checks.

If successful modification were required, the data parts of code would
not the ROM-able, and so  a ROM-based program would have to copy them
out to RAM, wasting embedded space.

If modifications had to work without affecting the original expression,
then evaluation of literals would have to always cons up new memory.

If modifications had to work without affecting other instances of the
same literal, then literals could not be merged to save space in the
program image.
From: Tim Bradshaw
Subject: Re: Popular bug in implementation?
Date: 
Message-ID: <1143383736.133946.97020@t31g2000cwb.googlegroups.com>
Paul Foley wrote:
>
> I can't imagine how it /could/ be checked, in software or hardware.
> [If it's lexically obvious, the compiler could issue a warning (as
> SBCL apparently does), and if it's file-compiled, it can be loaded
> back into (either software- or hardware-) protected memory to allow
> checking, but in the general case it's impossible, AFAICS]

I think it could be checked in software: every potentially mutable
object would have a mutable bit, and all operations which wanted to
mutate the object would check that bit.  Whether that's expensive is
another question - it's a lot simpler than what the VM system does now
to check mutability - it's probably a single cycle of overhead per
(attempted) mutation, and potentially less depending on whether it can
be executed in parallel etc.

An implementation could have a debug flag which, when turned on, caused
everything to check & set this bit.

Perhaps a better approach would be for the implementation to arrange
that literals were allocated in pages which then had write protection
turned on - in this case the VM system would do the checks for you `for
free'.  Would make GC more interesting, perhaps.  Lots of systems must
do this sort of thing already.

--tim
From: Pascal Bourguignon
Subject: Re: Popular bug in implementation?
Date: 
Message-ID: <87lkuxf8a0.fsf@thalassa.informatimago.com>
Paul Foley <···@below.invalid> (http://public.xdi.org/=pf) writes:
>> Perhaps a better approach would be for the implementation to arrange
>> that literals were allocated in pages which then had write protection
>> turned on
>
> But it can't do that, because it can never be sure what's a literal
> and what isn't.  E.g., READ only knows that it sees a list (or
> whatever); it doesn't know what that list is going to be used for.  It
> can't clear the "mutable" bit for everything, because what if you do
> something like #.*FOO* where *FOO* is a mutable list -- we certainly
> don't want it suddenly marking *FOO* immutable!  Etc.

Good point, but the reader still knows when it reads #. and when it
builds a new object itself.  

- The symbols won't be literals (well, the symbol name is a literal,
  since it's a string), but the symbol itself can change of value,
  function, plist or package at will (unless some restrictions when
  it's in COMMON-LISP or it's defined a constant or keyword).

- Structures and random-states read won't be literals. 

- any cons the reader builds will be a literal, (...)

- any vector or array the reader builds will be a literal. 
  #(...) #A(...) "..."

- any character or any number ever is a literal, but this is already
  specified.

- Things returned by #. are not processed by the reader (at least at
  this level) so nothing special is done on them.

(read-from-string "#(a b c)")            returns an inmutable vector.
(read-from-string "#.(vector 'a 'b 'c)") returns a mutable vector.

AFAIU, these are the rules that are already specified in CLHS anyways.

-- 
__Pascal Bourguignon__                     http://www.informatimago.com/

Nobody can fix the economy.  Nobody can be trusted with their finger
on the button.  Nobody's perfect.  VOTE FOR NOBODY.
From: Joerg Hoehle
Subject: Re: Popular bug in implementation?
Date: 
Message-ID: <ubqv8a5ma.fsf@users.sourceforge.net>
Paul Foley <···@below.invalid> (http://public.xdi.org/=pf) writes:

> On 26 Mar 2006 06:35:36 -0800, Tim Bradshaw wrote:
> >> I can't imagine how it /could/ be checked, in software or hardware.

> > I think it could be checked in software: every potentially mutable
> > object would have a mutable bit, and all operations which wanted to

> > Perhaps a better approach would be for the implementation to arrange
> > that literals were allocated in pages which then had write protection
> > turned on
> But it can't do that, because it can never be sure what's a literal

It has been done already.  CLISP on Sparc had it around ~1994.  It was
removed because of some problems with stability.

It was fun to use it with legacy code.  I used it to detect all those
destructive NCONC etc. optimisations on quoted lists emanating from
program code.  String literals in LOAD'ed files are also immutable.

> Well of course it'd be no problem to check a mutable bit if you had
> one; the problem is, how do you know when to turn off the mutable bit?

Such bits need room.  CLISP users already complain about various low
limits (e.g. fixnum typically 24 bit, ARRAY-DIMENSION-LIMIT etc.).
Reasons are some bits taken of a 32bit word to encode some information
(e.g. immutable, array type etc.)

Regards,
	Jorg Hohle
Telekom/T-Systems Technology Center
From: Andreas Eder
Subject: Re: Popular bug in implementation?
Date: 
Message-ID: <ari1h3-3ab.ln1@eder.homelinux.net>
Hi Joerg,

>>>>> "Joerg" == Joerg Hoehle <······@users.sourceforge.net> writes:

    Joerg> Such bits need room.  CLISP users already complain about various low
    Joerg> limits (e.g. fixnum typically 24 bit, ARRAY-DIMENSION-LIMIT etc.).
    Joerg> Reasons are some bits taken of a 32bit word to encode some information
    Joerg> (e.g. immutable, array type etc.)

So, that is one more reason to go to 64 bits then.

'Andreas
-- 
Wherever I lay my .emacs, there's my $HOME.
From: Marcin 'Qrczak' Kowalczyk
Subject: Re: Popular bug in implementation?
Date: 
Message-ID: <87odztnxqp.fsf@qrnik.zagroda>
Paul Foley <···@below.invalid> (http://public.xdi.org/=pf) writes:

>> If detection of error were required, it would be inefficient to
>> implement without the hardware support: the program's performance would
>> be penalized with run-time checks.
>
> I can't imagine how it /could/ be checked, in software or hardware.
> [If it's lexically obvious, the compiler could issue a warning (as
> SBCL apparently does), and if it's file-compiled, it can be loaded
> back into (either software- or hardware-) protected memory to allow
> checking, but in the general case it's impossible, AFAICS]

It is possible: just distinguish mutable cells from immutable cells
in their representation, and similarly for arrays. Functions like CAR
accept either kind, functions like RPLACA accept only mutable cells.

-- 
   __("<         Marcin Kowalczyk
   \__/       ······@knm.org.pl
    ^^     http://qrnik.knm.org.pl/~qrczak/
From: Marcin 'Qrczak' Kowalczyk
Subject: Re: Popular bug in implementation?
Date: 
Message-ID: <87k6ahnjcz.fsf@qrnik.zagroda>
Paul Foley <···@below.invalid> (http://public.xdi.org/=pf) writes:

>> It is possible: just distinguish mutable cells from immutable cells
>> in their representation, and similarly for arrays. Functions like CAR
>> accept either kind, functions like RPLACA accept only mutable cells.
>
> But there's no way for READ to know what is and isn't going to be a
> mutable cell at execution time, so it can't mark them.  The only thing
> that could is the file compiler, which just gets you back in exactly
> the situation you're in today.

Reading the source for the purpose of compiling could set a private
flag for READ to mark constructed lists appropriately. Building lists
according to descriptions in precompiled files could too make them
read-only.

The only real problem is that many Lisp implementations have special
representations of conses (e.g. without an object header or with
specially marked pointers) and carefully tuned implementations of
functions like CAR, APPLY, LENGTH etc., and thus introducing a
separate kind of conses would make them a bit slower.

-- 
   __("<         Marcin Kowalczyk
   \__/       ······@knm.org.pl
    ^^     http://qrnik.knm.org.pl/~qrczak/
From: Christophe Rhodes
Subject: Re: Popular bug in implementation?
Date: 
Message-ID: <sqlkuw7v9x.fsf@cam.ac.uk>
Paul Foley <···@below.invalid> (http://public.xdi.org/=pf) writes:

> On Sun, 26 Mar 2006 15:26:06 +0200, Kowalczyk  wrote:
>
>> It is possible: just distinguish mutable cells from immutable cells
>> in their representation, and similarly for arrays. Functions like CAR
>> accept either kind, functions like RPLACA accept only mutable cells.
>
> But there's no way for READ to know what is and isn't going to be a
> mutable cell at execution time, so it can't mark them.  The only thing
> that could is the file compiler, which just gets you back in exactly
> the situation you're in today.

Is it not the case that _everything_ that READ constructs should be
immutable?

Christophe
From: Kaz Kylheku
Subject: Re: Popular bug in implementation?
Date: 
Message-ID: <1143423671.433376.108830@e56g2000cwe.googlegroups.com>
Christophe Rhodes wrote:
> Paul Foley <···@below.invalid> (http://public.xdi.org/=pf) writes:
>
> > On Sun, 26 Mar 2006 15:26:06 +0200, Kowalczyk  wrote:
> >
> >> It is possible: just distinguish mutable cells from immutable cells
> >> in their representation, and similarly for arrays. Functions like CAR
> >> accept either kind, functions like RPLACA accept only mutable cells.
> >
> > But there's no way for READ to know what is and isn't going to be a
> > mutable cell at execution time, so it can't mark them.  The only thing
> > that could is the file compiler, which just gets you back in exactly
> > the situation you're in today.
>
> Is it not the case that _everything_ that READ constructs should be
> immutable?

No. READ is just a function that reads characters and conses up a data
structure. You can use this function at run-time to create perfectly
normal data. E.g. implicitly through READ-FROM-STRING.

It's not the reading of data that creates the issue, and the issue is
not immutability either.

The issue is that the program's source code consists of data, and by
accessing some of that data, the program becomes self-referential.
Because the program is self-referential, that gives rise to the
possibility that it can be self-modifying also.

Requirements for the behavior of self-modifying programs could be
precisely specified. It could be required that each evaluation of a
literal allocates a new object which is a copy of that literal.

Or that each literal is a distinct object, even if it looks exactly
like another literal, and that the same object is fetched on each
evaluation of that literal, and is modifiable---i.e. that literals are
just static, mutable data.

But since the behavior of self-modifying programs is not defined, that
creates the opportunity to make their embedded data immutable, for
instance by placing it in write-protected virtual pages along with
code, or burning it into ROM. It creates other opportunities too, like
reducing the storage for the data by identifying common substructures
in distinct literals and merging them.

It creates other opportunities too. For instance:

  (let* ((literal '(1 2)) (one (car literal))) ...)

Here, the compiler could just replace the (CAR LITERAL) expression with
1, without caring what the program does with LITERAL. Even if the (1 2)
is mutated, it could be the case that ONE continues to represent the
value 1. In fact, that 1 could be incorporated into the machine
language program, such that it appears only as an immediate operand
embedded in the instructions.

So you can make mutable data with READ at run time, but if that data is
a program, then if you muck with that data after compiling that
program, or while evaluating it, you make that program undefined.

  (defvar *prog* (read-from-string "(lambda () '(1 2))"))

  (setf (third *prog* (list 'quote (list 3 4)))

  *prog*
  -> (lambda () '(3 4))

Okay, so far we are well-defined.

  (defvar *compiled* (compile nil *prog*))

Now we manipulate the data again:
  (setf (first (third *prog* 42)))

   *prog*
   -> (lambda () '42)

Now we compiled the program, but changed the source code afterward. But
nothing bad has happened yet!

  (funcall *compiled*)

/Now/ we have a problem.  We made a program out of some source code
pieces, some of which ended up as literals data in that program, then
compiled it, and then messed with that original data, and then called
it!

Which data will the program use? 42 or (1 2)? Does the compiled lambda
have the original (QUOTE (1 2)) object, which now became (QUOTE 42)? Or
did the compiler make a copy and put that copy into the lambda?

We don't know!
From: Pascal Bourguignon
Subject: Re: Popular bug in implementation?
Date: 
Message-ID: <87lkuxgu6z.fsf@thalassa.informatimago.com>
Paul Foley <···@below.invalid> (http://public.xdi.org/=pf) writes:

> On 25 Mar 2006 09:41:27 -0800, Kaz Kylheku wrote:
>
>> But again, that's a secondary issue. The real issue is that literals
>> such as strings and lists are part of the program image. Whenever you
>> evaluate a literal, it doesn't necessarily create a new object: it just
>> retrieves something from the program image.   If you change that
>> something, then you can potentially change the value of that
>> expression! For instance say you have
>
>>   (defun return-list () '(1 2))
>
>> If you call RETURN-LIST and modify the list, then the next time
>> somebody calls RETURN-LIST , it may return the modified list!
>
> What is this "doesn't necessarily"/"can potentially"/"may" stuff?  You
> mean "doesn't", "will", and "will".

Not at all.  The fact that '(1 2) is a literal can be detected by the
compiler and it can put it in ROM or in a read-only memory segment.
Then RETURN-LIST will always return the same unmodified literal, 
and the nasal demon will appear when you try to modify it.
Hence these "doesn't necessarily"/"can potentially"/"may", that's the
stuff nasal demons are made of.



> [But that's not actually a problem unless you expected something else]
>
>> Moreover, suppose that there is another function in the program:
>
>>   (defun return-list-2 () '(1 2))
>
>> Guess what, /this/ function can now /also/ returns the modified list!
>
> No it can't.  You're just typing this stuff at the REPL, right?

Nasal demon.  The reader can do whatever it wants, and we don't
consider only the REPL, but all possible programs in all possible kind
of device compiled or interpreted by all possible kind of
implementations.


>> The Lisp compiler can merge the two literals into a single object in
>
> The file compiler can do that; the COMPILE function (and hence EVAL,
> if it's implemented as COMPILE-and-FUNCALL) can't.  Which means that
> modifying literals is perfectly safe and well-defined as long as they
> come from the REPL (or source files; i.e., from calls to READ)

I don't think this is specified so.

In any case, entering at the REPL a defun that has a different
semantics than in a file to be compiled doesn't sound too compliant a
program to me.

Perhaps we should fork comp.lang.lisp.clisp, comp.lang.lisp.sbcl, etc
for discussion of implementation specific programs.


>> If detection of error were required, it would be inefficient to
>> implement without the hardware support: the program's performance would
>> be penalized with run-time checks.
>
> I can't imagine how it /could/ be checked, in software or hardware.
> [If it's lexically obvious, the compiler could issue a warning (as
> SBCL apparently does), and if it's file-compiled, it can be loaded
> back into (either software- or hardware-) protected memory to allow
> checking, but in the general case it's impossible, AFAICS]

That's because of the existance of the special cases that you mustn't
do it in general.

-- 
__Pascal Bourguignon__                     http://www.informatimago.com/
Our enemies are innovative and resourceful, and so are we. They never
stop thinking about new ways to harm our country and our people, and
neither do we. -- Georges W. Bush
From: Bill Atkins
Subject: Re: Popular bug in implementation?
Date: 
Message-ID: <87veu2wkde.fsf@rpi.edu>
"Mikalai" <········@yahoo.com> writes:

> ······@gmail.com wrote:
>> Mikalai wrote:
>> > Kaz Kylheku wrote:
> ---snip---
>>
>> (defvar *x* '(1 2))   ;; creates a variable, *x*, that points to a list
>> literal (a constant)
>> (setf (car *x*) *x*)  ;; modifies the constant.  this is ILLEGAL
>>
>> (defvar *x* (list 1 2))  ;; creates a variable, *x*, that points to a
>> newly created list (like using malloc in C)
>> (setf (car *x*) *x*)  ;; modifies the list.  this is LEGAL
>>
>> I hope that helps to make things more clear.
> OK. This is clear now.
> So, (quote ...) may create something that looks like list, but
> internally *can be* maid rigid, unchangable.

'(1 2 3 4) will return a bona fide list - not just something
masquerading as a list.  The problem is that what it returns should be
considered a literal constant.  For example, compile and run this:

 (defun quote-test (skip)
  (let ((list '(1 2 3 4 5)))
    (if skip
	list
	(progn
	  (setf (car list) 33)
	  list))))

(quote-test nil) will return (1 2 3 4 5) every time, but as soon as
you call (quote-test t) you'll get (33 2 3 4 5) every time after that
(with skip set to nil or t), because you've made a change to a literal
constant.  Every time this function is called, the LIST variable is
initialized to point to the same list - since you changed it, all
future invocations of this function will see that change.

SBCL was kind enough to warn me that what I'm doing here is nuts.

;;;; (defun quote-test (skip)   (let ((list '(1 2 3 4 5)))     (i ...
; in: LAMBDA NIL
;     (SETF (CAR LIST) 33)
; ==>
;   (SB-KERNEL:%RPLACA LIST 33)
; 
; caught WARNING:
;   Destructive function SB-KERNEL:%RPLACA called on constant data.
;   See also:
;     The ANSI Standard, Special Operator QUOTE
;     The ANSI Standard, Section 3.2.2.3
; 
; compilation unit finished
;   caught 1 WARNING condition

CL-USER> (quote-test t)
(1 2 3 4 5)
CL-USER> (quote-test t)
(1 2 3 4 5)
CL-USER> (quote-test nil)
(33 2 3 4 5)
CL-USER> (quote-test t)
(33 2 3 4 5)
CL-USER> 


HTH,
Bill Atkins
From: Kaz Kylheku
Subject: Re: Popular bug in implementation?
Date: 
Message-ID: <1143307612.979788.147640@g10g2000cwb.googlegroups.com>
Mikalai wrote:
> Back to business. Should we tell in tutorials about *PRINT-CIRCLE*, or
> should we put it t by default?

Who is "we"?

"We" have an ANSI standard for this language, which says that
*PRINT-CIRCLE* top level binding is initialized to NIL.

You do know that cycle detection costs ... machine cycles? It's
expensive!

> I do not get how use of (setf car) is underfined, *when* CLtL2 tells me
> that this func is defined for me to *use*.

Do you not recognize the idea that a good function could be invoked on
bad or inappropriate data?

The division function / is also defined for you to use. Does that mean
you can divide by zero?

Assignment is defined. Does that mean you can assign to a constant?

Etc.

> From a perspective of a user  of a language, I honestly do not get what you mean by "underfined".

That's a typo for undefined.  You see how the R key is close to the E?

> > I think you just fed your python a mouse that was about three sizes too
> > large for its throat.
> Actually not. If you try what I did, you'll see for yourself how
> quickly it (python) performed.

Yes, except that it produced a useless result.  Who cares how fast?

> It is lisps that suprised me by choking. Now we now that it is simply a
> default misconfiguration of a printer.

"We" know no such thing. Don't include others with you.

There is no miscofinguration. People who have a clue want it that way.

Cycle detection means that every substructure in the object being
printed has to be put through some look-up index to see if it is a
reference to a neighboring or parent structure.

Here is a question: how do you turn that detection /off/ in Python?

> > The #1= means "reader, give the following object numeric tag 1". And
> > #1# means "reproduce the object from tag 1 here". The reader performs
> > the necessary backpatching to fill in these references, allowing the
> > #1# reference to occur in a place where the object isn't complete yet.
> With #1# reader should probably be able to read it back, right?

That doesn't make any sense. The #1# reader just reads the #1#.

Stick to Python, I think.
From: Mikalai
Subject: Re: Popular bug in implementation?
Date: 
Message-ID: <1143309040.759192.159640@i39g2000cwa.googlegroups.com>
Kaz Kylheku wrote:
> Mikalai wrote:
> > Back to business. Should we tell in tutorials about *PRINT-CIRCLE*, or
> > should we put it t by default?
>
> Who is "we"?
>
> "We" have an ANSI standard for this language, which says that
> *PRINT-CIRCLE* top level binding is initialized to NIL.
>
> You do know that cycle detection costs ... machine cycles? It's
> expensive!
Make it default t for *repl only*. How many people will be
performance-wise hit by it. I tend to run *expensive* stuff, detached
at all from a printer.
>
---snip---
>
> That doesn't make any sense. The #1# reader just reads the #1#.
I'll quot you:
"
Except that this [[...]] doesn't actually represent the structure.
Could you put that into a string, and then read it back to recover that
array?
"
Your saying this thing, makes me think that lisp is able to print a
thing and read it back even with a loop inside.
Shall we say that, unfortunately, lisp cannot read a beast with a
circle back. Putting it on the same level with python in this
*particular* aspect.
>
> Stick to Python, I think.
I thought it was a smarter choice to use lisp. That is why I am here,
asking questions. Isn't this forum maid for this?
From: jayessay
Subject: Re: Popular bug in implementation?
Date: 
Message-ID: <m3r74q1f0c.fsf@rigel.goldenthreadtech.com>
"Mikalai" <········@yahoo.com> writes:

> Kaz Kylheku wrote:

> > That doesn't make any sense. The #1# reader just reads the #1#.
> I'll quot you:
> "
> Except that this [[...]] doesn't actually represent the structure.
> Could you put that into a string, and then read it back to recover that
> array?
> "
> Your saying this thing, makes me think that lisp is able to print a
> thing and read it back even with a loop inside.

Yes

> Shall we say that, unfortunately, lisp cannot read a beast with a
> circle back. Putting it on the same level with python in this
> *particular* aspect.

No, why would you think that??  Here, just try it:

CL-USER(1): (defparameter *a* (list 1 2))
*A*
CL-USER(2): (setf *print-circle* t)
T
CL-USER(3): (setf (car *a*) *a*)
#1=(#1# 2)
CL-USER(4): (format nil "~S" *a*)
"#1=(#1# 2)"
CL-USER(5): (read-from-string *)
#1=(#1# 2)
10
CL-USER(9): (eq * (car *))
T
CL-USER(10):


> > Stick to Python, I think.
> I thought it was a smarter choice to use lisp. That is why I am here,
> asking questions. Isn't this forum maid for this?

Yes, but you have to put a least a modicum amount of effort into
reading and understanding the answers you get without acting like you
know the answers you get are wrong and that the people giving the
answers don't understand your question.


/Jon

-- 
'j' - a n t h o n y at romeo/charley/november com
From: Benjamin Teuber
Subject: Re: Popular bug in implementation?
Date: 
Message-ID: <e0421f$4ul$1@kohl.informatik.uni-bremen.de>
Mikalai wrote:
> Shall we say that, unfortunately, lisp cannot read a beast with a
> circle back. Putting it on the same level with python in this
> *particular* aspect.

I think that was a misunderstanding... with #1# stuff the reader can 
read back the circular structures.
From: Mikalai
Subject: Re: Popular bug in implementation?
Date: 
Message-ID: <1143311699.362110.200030@u72g2000cwu.googlegroups.com>
Benjamin Teuber wrote:
> Mikalai wrote:
> > Shall we say that, unfortunately, lisp cannot read a beast with a
> > circle back. Putting it on the same level with python in this
> > *particular* aspect.
>
> I think that was a misunderstanding... with #1# stuff the reader can
> read back the circular structures.
Show it.
- I do not know how to do it.
- Kaz maid a hint that its possible. Or he wasn't serious?

But with printing #1#'s there seems to be *enough* info to recover the
stucture back.
Does anyone know if its possible? Please, show *the* code.
From: jayessay
Subject: Re: Popular bug in implementation?
Date: 
Message-ID: <m3veu21fa1.fsf@rigel.goldenthreadtech.com>
"Mikalai" <········@yahoo.com> writes:

> Benjamin Teuber wrote:
> > Mikalai wrote:
> > > Shall we say that, unfortunately, lisp cannot read a beast with a
> > > circle back. Putting it on the same level with python in this
> > > *particular* aspect.
> >
> > I think that was a misunderstanding... with #1# stuff the reader can
> > read back the circular structures.
> Show it.

CL-USER(1): (defparameter *a* (list 1 2))
*A*
CL-USER(2): (setf *print-circle* t)
T
CL-USER(3): (setf (car *a*) *a*)
#1=(#1# 2)
CL-USER(4): (format nil "~S" *a*)
"#1=(#1# 2)"
CL-USER(5): (read-from-string *)
#1=(#1# 2)
10
CL-USER(6):

> - I do not know how to do it.

???


> Does anyone know if its possible? Please, show *the* code.

Is there some reason you couldn't have just tried it yourself???


/Jon

-- 
'j' - a n t h o n y at romeo/charley/november com
From: Alexander Schmolck
Subject: Re: Popular bug in implementation?
Date: 
Message-ID: <yfsy7yyb7rm.fsf@oc.ex.ac.uk>
jayessay <······@foo.com> writes:

> Is there some reason you couldn't have just tried it yourself???

My guess would be that he still hasn't quite figured out the difference
between (READ ...) and (EVAL (READ ...)).

'as
From: Pascal Bourguignon
Subject: Re: Popular bug in implementation?
Date: 
Message-ID: <87irq2ibb8.fsf@thalassa.informatimago.com>
"Mikalai" <········@yahoo.com> writes:

> Benjamin Teuber wrote:
>> Mikalai wrote:
>> > Shall we say that, unfortunately, lisp cannot read a beast with a
>> > circle back. Putting it on the same level with python in this
>> > *particular* aspect.
>>
>> I think that was a misunderstanding... with #1# stuff the reader can
>> read back the circular structures.
> Show it.

See my other post, but see also below.  Instead of objecting to what
we say to you, you should try to understand and read or experiment!


> - I do not know how to do it.

Learn more Common Lisp!   Read CLHS, read PCL, etc.


> - Kaz maid a hint that its possible. Or he wasn't serious?

he was serrious.

> But with printing #1#'s there seems to be *enough* info to recover the
> stucture back.

Indeed.


> Does anyone know if its possible? 

Everybody knows it is possible!


> Please, show *the* code.

There is NO code!   ZERO!   Никакой!

Just read what Kaz explained:

>   #1=(#1# 2)
> 
> The #1= means "reader, give the following object numeric tag 1". And
> #1# means "reproduce the object from tag 1 here". The reader performs
> the necessary backpatching to fill in these references, allowing the
> #1# reference to occur in a place where the object isn't complete yet.
 
Then try some copy-pasting with your REPL:

[82]> (setf *print-circle* t)
T
[83]> (read)                          ; you type
#1=(#1# 2)                            ; you type
#1=(#1# 2)                            ; REPL prints
[84]> (car (read))                    ; you type
#1=(#1# 2)                            ; you type
#1=(#1# 2)                            ; REPL prints
[85]> (cdr (read))                    ; you type
#1=(#1# 2)                            ; you type
(2)                                   ; REPL prints
[86]> (quote #1=(#1# 2))              ; you type
#1=(#1# 2)                            ; REPL prints
[87]> (car (quote #1=(#1# 2)))        ; you type
#1=(#1# 2)                            ; REPL prints
[88]> (cdr (quote #1=(#1# 2)))        ; you type
(2)                                   ; REPL prints
[89]> 




-- 
__Pascal Bourguignon__                     http://www.informatimago.com/
Cats meow out of angst
"Thumbs! If only we had thumbs!
We could break so much!"
From: Rob Warnock
Subject: Re: Popular bug in implementation?
Date: 
Message-ID: <rsudnVl7_IyamrvZnZ2dnUVZ_sOdnZ2d@speakeasy.net>
Kaz Kylheku <········@gmail.com> wrote:
+---------------
| Mikalai wrote:
| > Back to business. Should we tell in tutorials about *PRINT-CIRCLE*, or
| > should we put it t by default?
| 
| Who is "we"?
| 
| "We" have an ANSI standard for this language, which says that
| *PRINT-CIRCLE* top level binding is initialized to NIL.
| 
| You do know that cycle detection costs ... machine cycles?
| It's expensive!
+---------------

More than that, it's often *UG-LEE*! Consider what you get in the
following example with the ANSI-mandated default:

    > (defun f () "a simple string")
    > (f)
    "a simple string"
    > (list (f) (f) (f) (f))

    ("a simple string" "a simple string" "a simple string" "a simple string")
    >

A normal-enough looking session, yes? Now turn on *PRINT-CIRCLE* and
repeat the LIST call:

    > (setf *print-circle* t)

    T
    > (list (f) (f) (f) (f))

    (#1="a simple string" #1# #1# #1#)
    > 

Is that *really* what you want to see all the time in your default REPL?!?

I speak from experience: For a few days I was debugging some code
that created some fairly-complex graphs with nodes containing lots
of up/down/self-references, and in that case *PRINT-CIRCLE* was pretty
a necessity. After only a couple of times forgetting to turn it on
when starting a session (and getting into infinite print loops!),
I just put a (SETF *PRINT-CIRCLE* T) in my "~/.cmucl-init" file.
And a few days after I was no longer working on the graph-table code,
I took it right back out again!!! Why?  Because it made too many
common REPL outputs look so *UG-LEE*!


-Rob

-----
Rob Warnock			<····@rpw3.org>
627 26th Avenue			<URL:http://rpw3.org/>
San Mateo, CA 94403		(650)572-2607
From: Mikalai
Subject: Re: Popular bug in implementation?
Date: 
Message-ID: <1143385994.696902.253450@i40g2000cwc.googlegroups.com>
Rob Warnock wrote:
---snip---
> A normal-enough looking session, yes? Now turn on *PRINT-CIRCLE* and
> repeat the LIST call:
>
>     > (setf *print-circle* t)
>
>     T
>     > (list (f) (f) (f) (f))
>
>     (#1="a simple string" #1# #1# #1#)
>     >
>
> Is that *really* what you want to see all the time in your default REPL?!?
Aha.
I see, my expectation was that only objects that may contain refs to
other objects get #1#, since the point is in not writting infinit
circles (or is motivation a little different?). But printer goes a
little bit "over the top" with placing this labels for strings,
numbers, if these come from the same place:

>>> a="abc"

"abc"
>>> [a,a,a]

#(#1="abc" #1# #1#)
>>> ["abc","abc","abc"]

#("abc" "abc" "abc")

Indeed, I'd love to see some better behaviour. And I wonder, if printer
is "further adjustable", or, no luck...
From: Pascal Bourguignon
Subject: Re: Popular bug in implementation?
Date: 
Message-ID: <87hd5lf7ba.fsf@thalassa.informatimago.com>
"Mikalai" <········@yahoo.com> writes:
> Indeed, I'd love to see some better behaviour. And I wonder, if printer
> is "further adjustable", or, no luck...

This is the best of the behaviour!

In Common Lisp, everything is rather interelated (while still orthogonal).

There's this difference between EQL and EQUAL:

[158]> (equal "abc" "abc")
T
[159]> (eql "abc" "abc")
NIL
[160]> (eql #1="abc" #1#)
T
[161]> (equal #1="abc" #1#)  ; of course, (eql x y) ==> (equal x y)
T
[162]> 

So if you print a list of lisp objects, such as:

  ("abc" "abc" "abc" "abc")

with *print-circle* nil, you don't know if any two of these objects
are distinct or identical.  But if you print it with *print-circle*,
you can distinguish between 15 different situations (IIANW):


[177]> (loop for *print-circle* in '(nil t) 
             do (print (list '*print-circle* *print-circle*))
                (loop for i from 0 to 14 
                      do  (print (loop for k from 0 to 3
                                       collect (if  (logbitp k i) (f) (g))))))

(*PRINT-CIRCLE* NIL) 
("abc" "abc" "abc" "abc") 
("abc" "abc" "abc" "abc") 
("abc" "abc" "abc" "abc") 
("abc" "abc" "abc" "abc") 
("abc" "abc" "abc" "abc") 
("abc" "abc" "abc" "abc") 
("abc" "abc" "abc" "abc") 
("abc" "abc" "abc" "abc") 
("abc" "abc" "abc" "abc") 
("abc" "abc" "abc" "abc") 
("abc" "abc" "abc" "abc") 
("abc" "abc" "abc" "abc") 
("abc" "abc" "abc" "abc") 
("abc" "abc" "abc" "abc") 
("abc" "abc" "abc" "abc") 
(*PRINT-CIRCLE* T) 
(#1="abc" #1# #1# #1#) 
("abc" #1="abc" #1# #1#) 
(#1="abc" "abc" #1# #1#) 
(#1="abc" #1# #2="abc" #2#) 
(#1="abc" #1# "abc" #1#) 
(#1="abc" #2="abc" #1# #2#) 
(#1="abc" #2="abc" #2# #1#) 
(#1="abc" #1# #1# "abc") 
(#1="abc" #1# #1# "abc") 
(#1="abc" #2="abc" #2# #1#) 
(#1="abc" #2="abc" #1# #2#) 
(#1="abc" #1# "abc" #1#) 
(#1="abc" #1# #2="abc" #2#) 
(#1="abc" "abc" #1# #1#) 
("abc" #1="abc" #1# #1#) 
NIL

-- 
__Pascal Bourguignon__                     http://www.informatimago.com/

In a World without Walls and Fences, 
who needs Windows and Gates?
From: Joerg Hoehle
Subject: Re: Popular bug in implementation?
Date: 
Message-ID: <u64lga4pc.fsf@users.sourceforge.net>
"Mikalai" <········@yahoo.com> writes:
> Indeed, I'd love to see some better behaviour. And I wonder, if printer
> is "further adjustable", or, no luck...

And I wonder why you ignored repeated advice to read a bit of CL
literature or standards.
You know about *print-readably*.  Why didn't you read about I/O in CL?

Then you'd have found about *print-level* and *print-length*.

Actually, I recommend you use
	(setq *print-length* 50 *print-level* 10)
instead of (setq *print-readably* t)

I believe you would have found answers faster by reading yourself across
the printer section of CLHS (section 22) then by waiting for people to
respond to some Usenet posts in this thread that last at least 2 days.
Do you have access to WWW or just e-mail and/or Usenet news?

An excerpt From CLHS: "A number of option variables, called printer
control variables, are provided to permit control of individual
aspects of the printed representation of objects. The next figure
shows the standardized printer control variables; there might also be
implementation-defined printer control variables.

*print-array*   *print-gensym*       *print-pprint-dispatch*
*print-base*    *print-length*       *print-pretty*
*print-case*    *print-level*        *print-radix*
*print-circle*  *print-lines*        *print-readably*
*print-escape*  *print-miser-width*  *print-right-margin*
"

Regards,
	Jorg Hohle
Telekom/T-Systems Technology Center
From: Carl Shapiro
Subject: Re: Popular bug in implementation?
Date: 
Message-ID: <ouyhd5nyvyq.fsf@panix3.panix.com>
"Mikalai" <········@yahoo.com> writes:

> Wow, we have an answer!! It is print function that is at fault. And we
> shall admit, it is a pretty popular bug -- at least three
> implementations have it. 
                           
There is no bug.  Set the value of *PRINT-CIRCLE* to T if you want to
print circular structures.

(let ((x (list nil))) (rplaca x x) x) 
=> #1=(#1#)
From: Mikalai
Subject: Re: Popular bug in implementation?
Date: 
Message-ID: <1143295919.533980.90910@v46g2000cwv.googlegroups.com>
Carl Shapiro wrote:
> "Mikalai" <········@yahoo.com> writes:
>
> > Wow, we have an answer!! It is print function that is at fault. And we
> > shall admit, it is a pretty popular bug -- at least three
> > implementations have it.
>
> There is no bug.  Set the value of *PRINT-CIRCLE* to T if you want to
> print circular structures.
>
> (let ((x (list nil))) (rplaca x x) x)
> => #1=(#1#)
Thank you for the info about *print-circle*.
From: David Sletten
Subject: Re: Popular bug in implementation?
Date: 
Message-ID: <3K3Vf.11927$w86.11891@tornado.socal.rr.com>
Mikalai wrote:

> Try to do the following in a lisp of your choice:
> (setf a '(1 2))
> (setf (car a) a)
> What do you get, and on which implementation? Please, tell the world
> what implementations are OK with this.
> In clisp:

First of all you are engaging in behavior that results in undefined 
consequences. You attempt to change the value of a variable that has no 
(apparent) binding:
> [1]> (setf a '(1 2))
> (1 2)

Next you attempt to destructively modify a literal object (see 
http://www.lispworks.com/documentation/HyperSpec/Body/03_ga.htm):
> [2]> (setf (car a) a)
> 

So you get what you get...

But you are complaining about a different problem. Here are the results 
from Allegro:
CL-USER(205): (defvar *a* (list 1 2))
*A*
CL-USER(206): *print-circle*
NIL
CL-USER(207): *print-length*
NIL
CL-USER(208): (setf (car *a*) *a*)
(((((# 2) 2) 2) 2) 2)
CL-USER(209): *a*
(((((# 2) 2) 2) 2) 2)

SBCL by default will have problems printing this circular structure, but 
it handles it easily enough by doing this:
* (setf *print-circle* t)

T
* *a*

#1=(#1# 2)

> This is in Python:
> 
>>>>a=[1]
>>>>a[0]=a
>>>>a
> 
> [[...]]
> 
> Notice how Python's printer works out the problem by ...
> 

Notice how Common Lisp works out the problem in a meaningful way.

Aloha,
David Sletten
From: Mikalai
Subject: Re: Popular bug in implementation?
Date: 
Message-ID: <1143298288.206492.190130@z34g2000cwc.googlegroups.com>
David Sletten wrote:
> Mikalai wrote:
>
> > Try to do the following in a lisp of your choice:
> > (setf a '(1 2))
> > (setf (car a) a)
> > What do you get, and on which implementation? Please, tell the world
> > what implementations are OK with this.
> > In clisp:
>
> First of all you are engaging in behavior that results in undefined
> consequences. You attempt to change the value of a variable that has no
> (apparent) binding:
> > [1]> (setf a '(1 2))
> > (1 2)
Agree that standard does not say anything about it. And all lisps that
I use do the same thing -- create a special variable. Do I smell a
defacto standard? Not ANSI, though.
I confess, that in programs I use defvar's, but at repl playing setf
goes right to the point.
>
> Next you attempt to destructively modify a literal object (see
> http://www.lispworks.com/documentation/HyperSpec/Body/03_ga.htm):
> > [2]> (setf (car a) a)
> >
I do not think this is not allowed by the language. And in fact it
simply works, since it *should* work.
Should I read the link that you provided, that setf-car is bad, then
lower entries about modifying a hash-table are also bad, if I follow
your logic. Then, how am I going to populate a hash-table, if a
standard function creates an empty one? Etc. Etc. By the way, in the
same place we have "Performing I/O operations on the stream" -- exactly
what print does!! So, I see no problem in my doing some destructive
operations.
I honestly do not get what the link is trying to say, or, may be it
should be digested under some different light? But, there is a defined
(setf car), and behaviour is set. Same for other funcs.
>
> So you get what you get...
Since above was all *correct*, I was expecting to get something normal
instead of RESET. Which made me wonder.
My opinion now is that, for the sake of people, *print-circle* should
be t be default.
>
> But you are complaining about a different problem. Here are the results
> from Allegro:
> CL-USER(205): (defvar *a* (list 1 2))
> *A*
> CL-USER(206): *print-circle*
This is what I was missing.
It might seem simple to you, but out of many tutorials I've read, none
says about this configuration thing.
Thank you for info.
> NIL
> CL-USER(207): *print-length*
> NIL
> CL-USER(208): (setf (car *a*) *a*)
> (((((# 2) 2) 2) 2) 2)
> CL-USER(209): *a*
> (((((# 2) 2) 2) 2) 2)
>
> SBCL by default will have problems printing this circular structure, but
> it handles it easily enough by doing this:
> * (setf *print-circle* t)
>
> T
> * *a*
>
> #1=(#1# 2)
>
> > This is in Python:
> >
> >>>>a=[1]
> >>>>a[0]=a
> >>>>a
> >
> > [[...]]
> >
> > Notice how Python's printer works out the problem by ...
> >
>
> Notice how Common Lisp works out the problem in a meaningful way.
> 
> Aloha,
> David Sletten
From: David Sletten
Subject: Re: Popular bug in implementation?
Date: 
Message-ID: <_idVf.11973$w86.8183@tornado.socal.rr.com>
Mikalai wrote:

> David Sletten wrote:
> 
>>Mikalai wrote:
>>
>>
>>>Try to do the following in a lisp of your choice:
>>>(setf a '(1 2))
>>>(setf (car a) a)
>>>What do you get, and on which implementation? Please, tell the world
>>>what implementations are OK with this.
>>>In clisp:
>>
>>First of all you are engaging in behavior that results in undefined
>>consequences. You attempt to change the value of a variable that has no
>>(apparent) binding:
>>
>>>[1]> (setf a '(1 2))
>>>(1 2)
> 
> Agree that standard does not say anything about it. And all lisps that
> I use do the same thing -- create a special variable. Do I smell a
> defacto standard? Not ANSI, though.
> I confess, that in programs I use defvar's, but at repl playing setf
> goes right to the point.
> 

I didn't say that the standard says nothing about it. The SETQ entry 
(which is what your SETF turns into) says that it "Assigns values to 
variables." The Glossary defines "assign":

     assign v.t. (a variable) to change the value of the variable in a 
binding that has already been established. See the special operator setq.

But you have not established any binding for A, so you should not be 
using SETQ (SETF) on this non-existent variable.

>>Next you attempt to destructively modify a literal object (see
>>http://www.lispworks.com/documentation/HyperSpec/Body/03_ga.htm):
>>
>>>[2]> (setf (car a) a)
>>>
> 
> I do not think this is not allowed by the language. And in fact it
> simply works, since it *should* work.
> Should I read the link that you provided, that setf-car is bad, then
> lower entries about modifying a hash-table are also bad, if I follow
> your logic. Then, how am I going to populate a hash-table, if a
> standard function creates an empty one? Etc. Etc. By the way, in the
> same place we have "Performing I/O operations on the stream" -- exactly
> what print does!! So, I see no problem in my doing some destructive
> operations.
> I honestly do not get what the link is trying to say, or, may be it
> should be digested under some different light? But, there is a defined
> (setf car), and behaviour is set. Same for other funcs.
> 

The HyperSpec is perfectly clear here in the link I gave you. The very 
first sentence states that the consequences are undefined if you 
destructively modify a literal object, which means 
(http://www.lispworks.com/documentation/HyperSpec/Body/01_db.htm):

     The consequences are undefined

     This means that the consequences are unpredictable. The 
consequences may range from harmless to fatal. No conforming code may 
depend on the results or effects. Conforming code must treat the 
consequences as unpredictable. In places where the words ``must,'' 
``must not,'' or ``may not'' are used, then ``the consequences are 
undefined'' if the stated requirement is not met and no specific 
consequence is explicitly stated. An implementation is permitted to 
signal an error in this case.

So you get what you get...

> 
> Since above was all *correct*, I was expecting to get something normal
> instead of RESET. Which made me wonder.
> My opinion now is that, for the sake of people, *print-circle* should
> be t be default.
> 

> 
> This is what I was missing.
> It might seem simple to you, but out of many tutorials I've read, none
> says about this configuration thing.
> Thank you for info.
> 

It takes time to become familiar with all of the details. That's one 
purpose of this forum.

Aloha,
David Sletten
From: Mikalai
Subject: Re: Popular bug in implementation?
Date: 
Message-ID: <1143301959.927156.296410@j33g2000cwa.googlegroups.com>
David Sletten wrote:
---snip---
> But you have not established any binding for A, so you should not be
> using SETQ (SETF) on this non-existent variable.
My mistake. I ment exactly this, that there is nothing in the ref that
says what should happen when SETF is used on non-existent variable.
>
---snip---
> The HyperSpec is perfectly clear here in the link I gave you. The very
> first sentence states that the consequences are undefined if you
> destructively modify a literal object, which means
> (http://www.lispworks.com/documentation/HyperSpec/Body/01_db.htm):
>
>      The consequences are undefined
>
>      This means that the consequences are unpredictable. The
> consequences may range from harmless to fatal. No conforming code may
> depend on the results or effects. Conforming code must treat the
> consequences as unpredictable. In places where the words ``must,''
> ``must not,'' or ``may not'' are used, then ``the consequences are
> undefined'' if the stated requirement is not met and no specific
> consequence is explicitly stated. An implementation is permitted to
> signal an error in this case.
>
> So you get what you get...
Disclamer, I am not a professional at reading or writting specs.
So in its perfect clarity, none of mentioned destructive functions
should be used. Which includes (setf cdr) -- how should I create a
circle list? Which includes IO -- no files, no printing to tty. Etc.
Doesn't it limits a lisp as we know it?
On another hand CLtL2 tells me what destructive functions are available
and what they do, and how to use them. For example (setf cdr), or IO
operations. Do these docs contradict each other?
>
---snip---
>
> It takes time to become familiar with all of the details. That's one
> purpose of this forum.
That's what I think.
From: Tim Bradshaw
Subject: Re: Popular bug in implementation?
Date: 
Message-ID: <1143306779.960760.321220@i39g2000cwa.googlegroups.com>
Mikalai wrote:

> Disclamer, I am not a professional at reading or writting specs.
> So in its perfect clarity, none of mentioned destructive functions
> should be used. Which includes (setf cdr) -- how should I create a
> circle list?

Try and read.  You can use destructive operations, what you can't do is
destructively modify *literals*.
From: Harald Hanche-Olsen
Subject: Re: Popular bug in implementation?
Date: 
Message-ID: <pcofyl6o027.fsf@shuttle.math.ntnu.no>
+ "Tim Bradshaw" <··········@tfeb.org>:

| Try and read.  You can use destructive operations, what you can't do
| is destructively modify *literals*.

I tried it just for fun.

cl-user> (defun foo (first)
	   (let ((list '(a b)))
	     (if first
		 (setf (first list) 'x)
		 (setf (second list) 'x))
	     list))

(SBCL warns about the standard violation; that's nice.)

cl-user> (foo t)
(x b)
cl-user> (foo nil)
(x x)

Newbies may find the example illuminating.

-- 
* Harald Hanche-Olsen     <URL:http://www.math.ntnu.no/~hanche/>
- It is undesirable to believe a proposition
  when there is no ground whatsoever for supposing it is true.
  -- Bertrand Russell
From: Mikalai
Subject: Re: Popular bug in implementation?
Date: 
Message-ID: <1143311936.471327.41640@i39g2000cwa.googlegroups.com>
Harald Hanche-Olsen wrote:
> + "Tim Bradshaw" <··········@tfeb.org>:
>
> | Try and read.  You can use destructive operations, what you can't do
> | is destructively modify *literals*.
>
> I tried it just for fun.
>
> cl-user> (defun foo (first)
> 	   (let ((list '(a b)))
> 	     (if first
> 		 (setf (first list) 'x)
> 		 (setf (second list) 'x))
> 	     list))
>
> (SBCL warns about the standard violation; that's nice.)
>
> cl-user> (foo t)
> (x b)
> cl-user> (foo nil)
> (x x)
> 
> Newbies may find the example illuminating.
Indeed it is.
From: Pascal Bourguignon
Subject: Re: Popular bug in implementation?
Date: 
Message-ID: <8764m2jx90.fsf@thalassa.informatimago.com>
"Mikalai" <········@yahoo.com> writes:

> David Sletten wrote:
>> Mikalai wrote:
>>
>> > Try to do the following in a lisp of your choice:
>> > (setf a '(1 2))
>> > (setf (car a) a)
>> > What do you get, and on which implementation? Please, tell the world
>> > what implementations are OK with this.
>> > In clisp:
>>
>> First of all you are engaging in behavior that results in undefined
>> consequences. You attempt to change the value of a variable that has no
>> (apparent) binding:
>> > [1]> (setf a '(1 2))
>> > (1 2)
> Agree that standard does not say anything about it. And all lisps that
> I use do the same thing -- create a special variable. Do I smell a
> defacto standard? Not ANSI, though.
> I confess, that in programs I use defvar's, but at repl playing setf
> goes right to the point.

This is still dangerous to do it at the REPL, because A becomes a
special variable, and stays it, so the semantics of some further 
(LET ((a ...)) (f)) change.

It would be better to evaluate: (setf *a* '(1 2))
if you count on the implementation to make it a special variable.


>> Next you attempt to destructively modify a literal object (see
>> http://www.lispworks.com/documentation/HyperSpec/Body/03_ga.htm):
>> > [2]> (setf (car a) a)
> [...]
> I honestly do not get what the link is trying to say, or, may be it
> should be digested under some different light? But, there is a defined
> (setf car), and behaviour is set. Same for other funcs.

Just read what David writes!

      you attempt to destructively modify a literal object

To see an example of what may happen:

(defun f ()
   (let ((y '(1 2)))
      (incf (car y))
      y))

(list (f) (f) (f) (f))      ; What will this form result in?

[ In clisp, we get: ((5 2) (5 2) (5 2) (5 2)) 
  have a look at: (function-lambda-expression 'f)  ]

       

>> So you get what you get...
> Since above was all *correct*, I was expecting to get something normal
> instead of RESET. Which made me wonder.
> My opinion now is that, for the sake of people, *print-circle* should
> be t be default.

If you like it this way, you can set it this way in your ~/.clisprc or
equivalent user initialization file.


>> #1=(#1# 2)
>>
>> > This is in Python:
>> >
>> >>>>a=[1]
>> >>>>a[0]=a
>> >>>>a
>> >
>> > [[...]]
>> >
>> > Notice how Python's printer works out the problem by ...
>> >
>>
>> Notice how Common Lisp works out the problem in a meaningful way.

Why don't you try to _read_?

Compare:

    #1=(#1# 2)
    [[...]]


-- 
__Pascal Bourguignon__                     http://www.informatimago.com/
You're always typing.
Well, let's see you ignore my
sitting on your hands.
From: Mikalai
Subject: Re: Popular bug in implementation?
Date: 
Message-ID: <1143306814.643430.195570@u72g2000cwu.googlegroups.com>
Pascal Bourguignon wrote:
> "Mikalai" <········@yahoo.com> writes:
>
---snip---
> Why don't you try to _read_?
Because it wasn't me who came with the idea of python should be reading
back [[...]]. So, I thought, that person will know, what lisp reader
will (can) do, and he can share this knowledge with us :) .
>
> Compare:
>
>     #1=(#1# 2)
>     [[...]]
If you insist, here it is how #1=... can not be read back *as a
string*.
TL on top of clisp:
>>> a=[1]

#(1)
>>> a[0]=a

#1=#(#1#)
>>> &read-from-string("#1=#(#1#)")

#1=#(#1#)  ;
9

Can it be maid to read this back?
This is not a silly question, since, if yes, this is a simple way to
store ciclic groups of objects, say, in file.
The original poster (check the thread) sounded with the hint that
python cannot read [[...]] back, but lisp's reader can get #1=#(#1#) .
Was he mistaken?
From: David Golden
Subject: Re: Popular bug in implementation?
Date: 
Message-ID: <1XgVf.7560$j7.271305@news.indigo.ie>
Mikalai wrote:

>>>> &read-from-string("#1=#(#1#)")
> 
> #1=#(#1#)  ;
> 9
> 
> Can it be maid to read this back?

^^^ yes, you just did it ?!  (primary return value of the function
as above ?!)

> This is not a silly question, since, if yes, this is a simple way to
> store ciclic groups of objects, say, in file.
> The original poster (check the thread) sounded with the hint that
> python cannot read [[...]] back, but lisp's reader can get #1=#(#1#) .
> Was he mistaken?

Assuming *print-circle* is t :

; circular list
CL-USER> (read-from-string "#1=(hello nurse . #1#)")
#1=(HELLO NURSE . #1#)
22

; also works for a vector with itself as an element as 
; your example  #1=#(#1#)
CL-USER> (read-from-string "#1=#(#1#)")
#1=#(#1#)  
9
CL-USER> (defparameter a (read-from-string "#1=#(#1#)"))
A
CL-USER> (type-of a)
(SIMPLE-VECTOR 1)
CL-USER> 

; Just to confuse matters.
; remembering read-from-string reads a string's contents as
; lisp syntax data, if you want to read a string constant 
; from a string, one obvious   way to do it is to put the 
; quotes in, i.e. use the lisp syntax for a string within the 
; string you're reading from.

CL-USER> (read-from-string "\"#1=#(#1#)\"")
"#1=#(#1#)"
11
CL-USER> (defparameter a (read-from-string "\"#1=#(#1#)\""))
A
CL-USER> (type-of a)
(SIMPLE-BASE-STRING 9)
CL-USER> 


Now, let's try typing it in.

CL-USER> #1=#(#1#)
#1=#(#1#)
CL-USER> 

CL-USER> #1=(hello nurse . #1#)

; my lisp instance hangs... not entirely unexpectedly; that
; looked sortof like a wonky function call 
<<interrupt lisp>>
; Evaluation aborted

; so quote it!

CL-USER> '#1=(hello nurse . #1#)
#1=(HELLO NURSE . #1#)
CL-USER> 
From: David Golden
Subject: Re: Popular bug in implementation?
Date: 
Message-ID: <12hVf.7561$j7.271591@news.indigo.ie>
David Golden wrote:

> CL-USER> (defparameter a (read-from-string "\"#1=#(#1#)\""))
> A

Minor aside, it's conventional (but not mandatory) to name special vars
with stars, e.g. *a* in common lisp, my bad.
From: Pascal Bourguignon
Subject: Re: Popular bug in implementation?
Date: 
Message-ID: <87mzfeibwv.fsf@thalassa.informatimago.com>
"Mikalai" <········@yahoo.com> writes:

> Pascal Bourguignon wrote:
>> "Mikalai" <········@yahoo.com> writes:
>>
> ---snip---
>> Why don't you try to _read_?
> Because it wasn't me who came with the idea of python should be reading
> back [[...]]. So, I thought, that person will know, what lisp reader
> will (can) do, and he can share this knowledge with us :) .

That's not exactly the point. [[...]] doesn't give a lot of
information about the represented data structure.

But #1=(#1# 2) gives all the information needed to see (and rebuild)
the represented data structure.

You can configure CL to behave like python if you want:


[67]> (setf *print-circle* nil
            *print-length* 3
            *print-depth*  3)
3

;; first on a non-circular structure:
[68]> '(#1=(#2=(#3=(#4=(a b c d e f) #4# #4# #4# #4# #4#) #3# #3# #3# #3# #3#)
            #2# #2# #2# #2# #2#) #1# #1# #1# #1# #1# #1#)
(((((A B C ...) (A B C ...) (A B C ...) ...)
   ((A B C ...) (A B C ...) (A B C ...) ...)
   ((A B C ...) (A B C ...) (A B C ...) ...) ...)
  (((A B C ...) (A B C ...) (A B C ...) ...)
   ((A B C ...) (A B C ...) (A B C ...) ...)
   ((A B C ...) (A B C ...) (A B C ...) ...) ...)
  (((A B C ...) (A B C ...) (A B C ...) ...)
   ((A B C ...) (A B C ...) (A B C ...) ...)
   ((A B C ...) (A B C ...) (A B C ...) ...) ...)
  ...)
 ((((A B C ...) (A B C ...) (A B C ...) ...)
   ((A B C ...) (A B C ...) (A B C ...) ...)
   ((A B C ...) (A B C ...) (A B C ...) ...) ...)
  (((A B C ...) (A B C ...) (A B C ...) ...)
   ((A B C ...) (A B C ...) (A B C ...) ...)
   ((A B C ...) (A B C ...) (A B C ...) ...) ...)
  (((A B C ...) (A B C ...) (A B C ...) ...)
   ((A B C ...) (A B C ...) (A B C ...) ...)
   ((A B C ...) (A B C ...) (A B C ...) ...) ...)
  ...)
 ((((A B C ...) (A B C ...) (A B C ...) ...)
   ((A B C ...) (A B C ...) (A B C ...) ...)
   ((A B C ...) (A B C ...) (A B C ...) ...) ...)
  (((A B C ...) (A B C ...) (A B C ...) ...)
   ((A B C ...) (A B C ...) (A B C ...) ...)
   ((A B C ...) (A B C ...) (A B C ...) ...) ...)
  (((A B C ...) (A B C ...) (A B C ...) ...)
   ((A B C ...) (A B C ...) (A B C ...) ...)
   ((A B C ...) (A B C ...) (A B C ...) ...) ...)
  ...)
 ...)

;; next on a circular structure:
[69]> '#1=( a . #1# )
(A A A ...)

[70]> '(a a a a a a)
(A A A ...)

All these ... are not too useful because they hide the deeptest
structures: you cannot distinguis the circular structure of line [69]
from the simple proper list of line [70].




[71]> (setf *print-circle* t
            *print-length* nil
            *print-depth*  nil)
NIL

;; first on a non-circular structure:
[72]> '(#1=(#2=(#3=(#4=(a b c d e f) #4# #4# #4# #4# #4#) #3# #3# #3# #3# #3#)
            #2# #2# #2# #2# #2#) #1# #1# #1# #1# #1# #1#)
(#1=(#2=(#3=(#4=(A B C D E F) #4# #4# #4# #4# #4#) #3# #3# #3# #3# #3#) #2# #2# #2#
     #2# #2#)
 #1# #1# #1# #1# #1# #1#)

;; next on a circular structure:
[73]> '#1=( a . #1# )
#1=(A . #1#)

There, not only we can see that we have a circular structure, but we
can see all the circles, and the lisp reader can as well as we.


>> Compare:
>>
>>     #1=(#1# 2)
>>     [[...]]
> If you insist, here it is how #1=... can not be read back *as a
> string*.

#1=... is not a string why should it be read back as a string?


[77]> (read) 
#1=...

*** - READ from #<IO TERMINAL-STREAM>: a token consisting only of dots cannot be
      meaningfully read in




> TL on top of clisp:
>>>> a=[1]
>
> #(1)
>>>> a[0]=a
>
> #1=#(#1#)
>>>> &read-from-string("#1=#(#1#)")
>
> #1=#(#1#)  ;
> 9
>
> Can it be maid to read this back?

You just did it!!!
                                             (maid = unmarried woman
                                              made = past perfect of make)

[80]> (let ((item-read (read-from-string "#1=#(#1#)"))
            (*print-circle* t))
   (loop repeat 10
         for current = item-read then (aref current 0)
         do (format t "current = ~S ; (type-of current) = ~S ~%" 
                      current (type-of current))))
current = #1=#(#1#) ; (type-of current) = (SIMPLE-VECTOR 1) 
current = #1=#(#1#) ; (type-of current) = (SIMPLE-VECTOR 1) 
current = #1=#(#1#) ; (type-of current) = (SIMPLE-VECTOR 1) 
current = #1=#(#1#) ; (type-of current) = (SIMPLE-VECTOR 1) 
current = #1=#(#1#) ; (type-of current) = (SIMPLE-VECTOR 1) 
current = #1=#(#1#) ; (type-of current) = (SIMPLE-VECTOR 1) 
current = #1=#(#1#) ; (type-of current) = (SIMPLE-VECTOR 1) 
current = #1=#(#1#) ; (type-of current) = (SIMPLE-VECTOR 1) 
current = #1=#(#1#) ; (type-of current) = (SIMPLE-VECTOR 1) 
current = #1=#(#1#) ; (type-of current) = (SIMPLE-VECTOR 1) 
NIL


> This is not a silly question, since, if yes, this is a simple way to
> store ciclic groups of objects, say, in file.

Indeed we can.

> The original poster (check the thread) sounded with the hint that
> python cannot read [[...]] back, but lisp's reader can get #1=#(#1#) .
> Was he mistaken?

He wasn't.   Check how the lisp reader read the circular data
structure of lines [69] and [73] above.

-- 
__Pascal Bourguignon__                     http://www.informatimago.com/
Cats meow out of angst
"Thumbs! If only we had thumbs!
We could break so much!"
From: Mikalai
Subject: Re: Popular bug in implementation?
Date: 
Message-ID: <1143318263.760766.245320@z34g2000cwc.googlegroups.com>
Pascal Bourguignon wrote:
> "Mikalai" <········@yahoo.com> writes:
>
>
> > TL on top of clisp:
> >>>> a=[1]
> >
> > #(1)
> >>>> a[0]=a
> >
> > #1=#(#1#)
> >>>> &read-from-string("#1=#(#1#)")
> >
> > #1=#(#1#)  ;
> > 9
> >
> > Can it be maid to read this back?
>
> You just did it!!!
You are right. Gosh, I thought it is a symbol, why?
So, to clear it once and for all:
>>> b=&read-from-string("#1=#(#1#)")

#1=#(#1#)
>>> inspect(b)
#<ARRAY T (1) #x203FC0BE>:  Vector
 dimension: 1
 element-type: T
 no fill pointer
 not displaced
0:  #<ARRAY T (1) #x203FC0BE>
INSPECT-- type :h for help; :q to return to the REPL ---> :q

Inspection tells that it is indeed read back.
For record, I retract my statements of it being otherwise.

Wonderful :) .

I have another question. This printing to a string and then reading
things back may be used as a form of storage. But are there any
specialized functions for it, that will use may be quicker algorithm?
Do you know of any?
Thanks in advance.
From: Mikalai
Subject: Re: Popular bug in implementation?
Date: 
Message-ID: <1143319447.200833.174870@e56g2000cwe.googlegroups.com>
Actually, in printing #1=#(#1#) there is a loss of information. My
initial vector had a fill pointer and was adjustable. When list reads a
thing back, there are no fill pointer.
So, for persistance some other functions are needed.
From: Pascal Bourguignon
Subject: Re: Popular bug in implementation?
Date: 
Message-ID: <87wteigmu6.fsf@thalassa.informatimago.com>
"Mikalai" <········@yahoo.com> writes:
> Actually, in printing #1=#(#1#) there is a loss of information. My
> initial vector had a fill pointer and was adjustable. When list reads a
> thing back, there are no fill pointer.
> So, for persistance some other functions are needed.

Indeed.  

But this depends on the semantics of your application. Perhaps your
application uses the fill pointer as an optimization of: 

   (subseq vect (- (length vect) some-positive-value))

Why would you want to save it in that case?


-- 
__Pascal Bourguignon__                     http://www.informatimago.com/

HANDLE WITH EXTREME CARE: This product contains minute electrically
charged particles moving at velocities in excess of five hundred
million miles per hour.
From: Joerg Hoehle
Subject: Re: Popular bug in implementation?
Date: 
Message-ID: <ufykka6f3.fsf@users.sourceforge.net>
"Mikalai" <········@yahoo.com> writes:
> Actually, in printing #1=#(#1#) there is a loss of information. My
> initial vector had a fill pointer and was adjustable. When list reads a
> thing back, there are no fill pointer.
> So, for persistance some other functions are needed.

That's the reason why there's no standard way to readably print a
hashtable.  Newbies rarely get the reason and complain here from time
to time.

A CL hashtable is more than an a-list of (key . value) pairs and a :test.
A CL hashtable can have arbitrary extensions (slots), e.g. :size
(standard), :weak (non-standard). There's no standard for printing these.

One could consider this behaviour a very old inconsistency in CL:
while an array is printed under *print-readably* True, ignoring its
:adjustable, or :fill-pointer properties -- as you point out -- CL
does not even attempt to print the simplest hashtables readably.

Regards,
	Jorg Hohle
ECLM Hamburg meeting http://weitz.de/eclm2006/ coming soon
From: Pascal Bourguignon
Subject: Re: Popular bug in implementation?
Date: 
Message-ID: <871wwqi226.fsf@thalassa.informatimago.com>
"Mikalai" <········@yahoo.com> writes:
> I have another question. This printing to a string and then reading
> things back may be used as a form of storage. But are there any
> specialized functions for it, that will use may be quicker algorithm?

First, you must realize that some lisp objects are NOT printable readably.
All those objects that are printed as a string starting with #< for example.
In particular, functions, closures, CLOS objects by default, etc.
More over, you must remember to set *PRINT-READABLY* T, and this doesn't
produce necessarily a nice output:

[93]> (let ((*print-readably* t)
            (*print-circle* t)
            (*print-length* nil)
            (*print-depth* nil))
        (print (list 42 pi "Hello" '|Howdy| 'sin #(1 a (b . c)))))

(42. 3.1415926535897932385L0 "Hello" |COMMON-LISP-USER|::|Howdy| |COMMON-LISP|::|SIN|
 #(1. |COMMON-LISP-USER|::|A| (|COMMON-LISP-USER|::|B| . |COMMON-LISP-USER|::|C|))) 


Want do you mean by quicker algorithm?

The defined properties of an algorithm include asymtotic time
complexity, asymtotic space complexity, things like that, but not a
'quickness".

Please ponder the differences in transmission speed between L1 cache,
L2 cache, RAM, Hard disk cache, Hard disk magnetic medium, the 1Gb/s,
100Mb/s, WiFi, ADSL and cable networks.


> Do you know of any?
> Thanks in advance.

There are other ways to store lisp objects.
See for example: http://www.cliki.net/admin/search?words=database
or even: #+CLISP EXT:SAVEINITMEM
         #+SBCL  SB-EXT:SAVE-LISP-AND-DIE
         etc...

-- 
__Pascal Bourguignon__                     http://www.informatimago.com/

"Logiciels libres : nourris au code source sans farine animale."
From: Tim X
Subject: Re: Popular bug in implementation?
Date: 
Message-ID: <87bqvtdh30.fsf@tiger.rapttech.com.au>
"Mikalai" <········@yahoo.com> writes:

> David Sletten wrote:
>> Mikalai wrote:
>>
>> > Try to do the following in a lisp of your choice:
>> > (setf a '(1 2))
>> > (setf (car a) a)
>> > What do you get, and on which implementation? Please, tell the world
>> > what implementations are OK with this.
>> > In clisp:
>>
>> First of all you are engaging in behavior that results in undefined
>> consequences. You attempt to change the value of a variable that has no
>> (apparent) binding:
>> > [1]> (setf a '(1 2))
>> > (1 2)
> Agree that standard does not say anything about it. And all lisps that
> I use do the same thing -- create a special variable. Do I smell a
> defacto standard? Not ANSI, though.
> I confess, that in programs I use defvar's, but at repl playing setf
> goes right to the point.
>>
>> Next you attempt to destructively modify a literal object (see
>> http://www.lispworks.com/documentation/HyperSpec/Body/03_ga.htm):
>> > [2]> (setf (car a) a)
>> >
> I do not think this is not allowed by the language. And in fact it
> simply works, since it *should* work.
> Should I read the link that you provided, that setf-car is bad, then
> lower entries about modifying a hash-table are also bad, if I follow
> your logic. Then, how am I going to populate a hash-table, if a
> standard function creates an empty one? Etc. Etc. By the way, in the
> same place we have "Performing I/O operations on the stream" -- exactly
> what print does!! So, I see no problem in my doing some destructive
> operations.
> I honestly do not get what the link is trying to say, or, may be it
> should be digested under some different light? But, there is a defined
> (setf car), and behaviour is set. Same for other funcs.

I think you may be missing the crucial point in what David was
explaining - the problem isn't with setf/setq, but with the fact you
are trying to change a *literal* i.e. '(1 2) is *not* the same as
(list 1 2).

Tim

-- 
tcross (at) rapttech dot com dot au