Path: utzoo!attcan!uunet!aplcen!uakari.primate.wisc.edu!zaphod.mps.ohio-state.edu!usc!cs.utexas.edu!hellgate.utah.edu!cdr.utah.edu!moore From: moore%cdr.utah.edu@cs.utah.edu (Tim Moore) Newsgroups: comp.lang.scheme Subject: Re: Re: Virtues of Lisp syntax [for extension languages] Message-ID: <1990Sep25.112400.26991@hellgate.utah.edu> Date: 25 Sep 90 17:24:00 GMT References: <10340003@hpfcso.HP.COM> Organization: University of Utah CS Dept Lines: 116 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