[comp.lang.scheme] Virtues of Lisp syntax for extension languages

peter@ficc.ferranti.com (Peter da Silva) (09/22/90)

In article <20301@well.sf.ca.us> jjacobs@well.sf.ca.us (Jeffrey Jacobs) writes:
> Having watched the LISP Syntax thread for a while, I thought a little
> history might be in order...

> Way back in the old days, [...] LISP was an interpreted language.

Extension languages, by and large, still *are* interpreted...

> However, if compilation is the primary development strategy (which it
> is with CL), then the LISP syntax is not particularly useful.  [...]

... so the LISP syntax *remains* particularly useful in this domain. And,
remember, that's where this discussion started...
-- 
Peter da Silva.   `-_-'
+1 713 274 5180.   'U`
peter@ferranti.com

dgr@hpfcso.HP.COM (Dave Roberts) (09/24/90)

moore%cdr.utah.edu@cs.utah.edu (Tim Moore) writes:

> In article <20692@well.sf.ca.us> jjacobs@well.sf.ca.us (Jeffrey Jacobs) writes:
> >
> >Larry Masinter wrote:
> >>>>[As a side note, many learning LISP programmers frequently do
> >>>> encounter self-modifying code and are mystified by it, e.g.,
> >>>>   (let ((var '(a b c)))
> >>>>       ...
> >>>>       (nconc var value))
> ...
> >And Tim Moore wrote:
> ...
> >>>It's not legal Common
> >>>Lisp code, because the constant may be in read-only memory.
> >
> >Correct me if I'm wrong, but it seems to me that this *is* legal and
> >that the compiler should specifically *not* allocate quoted lists such
> >as that to read-only memory!
> 
> For better or worse, this is from CLtL2, pg 115:
> X3J13 [the body specifying ANSI Common Lisp] voted in January 1989 to
> clarify that it is an error to destructively modify any object that
> appears as a constant in executable code, whether within a quote
> special form or as a self-evaluating form.
> 
> I'm not sure where this was specified in the orginal CLtL; obviously
> it wasn't specified too clearly or X3J13 wouldn't have needed to
> clarify this point.


Umm... I don't want to stick my head into a CL discussion, but this is
a Scheme group, or so I though :-).  This is supposed to be
technically illegal in Scheme, too, right?  I mean, you're not supposed
to mutate a constant.  What I'm curious about is what exactly
constitutes mutation?  The following is legal; correct?

	(let ((label '(a b c)))
	     (set! label (append label '(d e f))))

Here I'm just messing with the symbol's definition, not with the
actual structure of the constant (...I think, since labels are always
handled the same way and it's the actual data that isn't) Now it's
definitely illegal to do the following, right?

	(let ((label '(a b c)))
	     (set-cdr! label '(d e)))

I guess my basic question is ``What part of the structure aren't I
supposed to mess with, and what if I use a constant to make another
structure?  Is the resulting structure still a constant?'' IE. is the
following okay?

	(let ((label (append '(a b c) '(d e f))))
	     (set-cdr! label '(x y z)))

How about stuff built up with quasiquote?

Help!! I'm really confused about this whole thing. :-) I have this
attitude that I don't want to mess with anything that I might have
build up from a constant, but I may be overly cautious.  How does a
procedure that does mutation on its arguments know if the arguments
are actually constants or not?  When a procedure call is actually
done, the call is done by reference, not by value, for complex
structures (ie. lists), right?

	(define x '(a b c))
	(define (proc some-list)
		(set-car! some-list '(d e)))

Now,
	(proc x)

should be an error, right, because the symbol some-list isn't bound to
a copy of what x contains, but rather to exactly what x is bound to
(the original copy of '(a b c)), which I am supposedly not allowed to
mess with.


Could someone who knows what's going on lend me some intelligence?
Thanks.

Dave Roberts
Hewlett-Packard Co.
dgr@hpfcla.fc.hp.com

moore%cdr.utah.edu@cs.utah.edu (Tim Moore) (09/26/90)

In article <10340003@hpfcso.HP.COM> dgr@hpfcso.HP.COM (Dave Roberts) writes:
>
>Umm... I don't want to stick my head into a CL discussion, but this is
>a Scheme group, or so I though :-).  This is supposed to be
>technically illegal in Scheme, too, right?  I mean, you're not supposed
>to mutate a constant.  What I'm curious about is what exactly
>constitutes mutation?  

Actually, according to R3RS, the effects of modifying literal data
"are not specified". Maybe someone in touch with the Scheme
standardization process can comment.

>The following is legal; correct?
>
>	(let ((label '(a b c)))
>	     (set! label (append label '(d e f))))
>
>Here I'm just messing with the symbol's definition, not with the
>actual structure of the constant (...I think, since labels are always
>handled the same way and it's the actual data that isn't) 

You can do anything you want to label. It's the value of label that's
of interest. The above code is quite legal because append (in effect)
copies its arguments except for the last.

>Now it's
>definitely illegal to do the following, right?
>
>	(let ((label '(a b c)))
>	     (set-cdr! label '(d e)))

You're right. You're trying to set-cdr! a quoted constant '(a b c).

>I guess my basic question is ``What part of the structure aren't I
>supposed to mess with, and what if I use a constant to make another
>structure?  Is the resulting structure still a constant?'' 

I think you may be confusing the setting of a variable with the
mutation of its contents. It's mutation of constant structures that
can cause problems.

>IE. is the following okay?
>
>	(let ((label (append '(a b c) '(d e f))))
>	     (set-cdr! label '(x y z)))
>

Sure, you're set-cdring a cons cell that was freshly consed by append.
On the other hand, (set-cdr! (cdddr label) '(x y z)) could cause
problems because that is set-cdring a cons-cell of one of the original
quoted lists (the first cons cell of '(d e f)).

>How about stuff built up with quasiquote?
>

It depends :-) In Common Lisp, "no guarantees are made as to whether
the constructed copy of the template will or will not share list
structure with template itself", so it's best not to mutate the
results of backquote, at least not without thinking hard first! 
R3RS merely says that , and ,@ expressions are "inserted into the
structure". However, the quasiquote mechanism is clearly intended to
work like Common Lisp's backquote, so the same warnings should apply.

Now, there are cases when it's obviously OK to mutate a backquoted list.
For example, (following examples are from Utah Common Lisp's
backquote, based heavily (completely) on Guy Steele's sample backquote):

`(,a b c) => (CONS A '(B C))

In any implementation, the value of a needs to be inserted into the
list, so it must be OK to mutate the first cons cell of the list. In
ucl it's not OK to mutate the other cons cells of the list because
they're part of a quoted constant. A naive implementation might produce

`(,a b c) => (APPEND (LIST A) (LIST 'B) (LIST 'C))

so it would be OK to mutate any part of the list. As a programmer,
it's best to think about what an "optimizing" backquote would do; play
it safe.It should be OK to mutate any part of the structure that
quasiquote itself would have had to cons freshly or mutate in order to
create the structure.

As another example, in ucl
`((a b ,c) (d e f)) => (CONS (LIST 'A 'B C) '((D E F)))

You can mutate the car of the top level list here, and the list
that is the car, but nothing else safely.

>Help!! I'm really confused about this whole thing. :-) I have this
>attitude that I don't want to mess with anything that I might have
>build up from a constant, but I may be overly cautious.  How does a
>procedure that does mutation on its arguments know if the arguments
>are actually constants or not?  When a procedure call is actually
>done, the call is done by reference, not by value, for complex
>structures (ie. lists), right?
>

Either 1) never mutate arguments, always freshly cons anew, or 2)
don't pass constants to procedures that will try to mutate them.
Sounds glib, but 1) is quite good advice unless you are willing to
put in the time and effort to ensure 2). Even if mutating a quoted
constant doesn't cause a segmentation violation, it's probably an
error in you program and may cause wierd problems.

>
>Could someone who knows what's going on lend me some intelligence?
>Thanks.
>
Hope this helps a bit.
>Dave Roberts
>Hewlett-Packard Co.
>dgr@hpfcla.fc.hp.com

Tim Moore                    moore@cs.utah.edu {bellcore,hplabs}!utah-cs!moore
"Ah, youth. Ah, statute of limitations."
		-John Waters