Xref: utzoo comp.lang.lisp:4921 comp.lang.scheme:2547 comp.sources.wanted:16789 Path: utzoo!utgpu!news-server.csri.toronto.edu!cs.utexas.edu!asuvax!ncar!csn!hellgate.utah.edu!defmacro.utah.edu!moore From: moore%defmacro.utah.edu@cs.utah.edu (Tim Moore) Newsgroups: comp.lang.lisp,comp.lang.scheme,comp.sources.wanted Subject: Re: SETF of LET Message-ID: <1991May22.134211.13554@hellgate.utah.edu> Date: 22 May 91 19:42:11 GMT References: <1991May20.201244.21948@uicbert.eecs.uic.edu> <1991May22.072355.22077@kestrel.edu> <1991May22.180507.4914@Think.COM> Organization: University of Utah CS Dept Lines: 62 In article <1991May22.180507.4914@Think.COM> barmar@think.com writes: >In article <1991May22.072355.22077@kestrel.edu> gyro@kestrel.edu (Scott Layson Burson) writes: >>I have just come to the conclusion, after trying for several hours, >>that it is not possible to write a SETF method for LET using >>DEFINE-SETF-METHOD. > ... >> (define-setf-method let (clauses &rest body) >> (let ((storevar (gensym))) >> (values '() '() (list storevar) >> `(let ,clauses >> ,@(butlast body) >> (setf ,(car (last body)) ,storevar) >> (car (last body)))))) >> >>So, roughly speaking, (setf (let ((x ...)) (car x)) 'foo) turns into >>(let ((x ...)) (setf (car x) 'foo)). >> >>The problem with the definition above is that it potentially evaluates >>the subforms of the last form in the body more than once; so > >Could the problem be that you're expanding into another SETF, rather than >using GET-SETF-METHOD-MULTIPLE-VALUE on (car (last body))? If the last >form in the body needs special attention like this, its SETF expansion >should take care of it. I fooled around a bit with this problem this morning. The bindings of the let probably need to be bound around the accessor form too, so you want to move the let bindings into the vars and vals returned by define-setf-method. BUT define-setf-method has to return gensyms (or gentemps) for its bindings. So you need to augment the environment passed to the inner GET-SETF-METHOD-MULTIPLE-VALUE with symbol-macro bindings that substitute references to the variables of the LET with refs to temporaries. For good measure, you should add new declaration info (with reference to the temporaries) to the environment too. Then wrap LOCALLY around the store and accessor forms, and you're set. Unfortunately, there won't be a portable way to do this in ANSI Common Lisp because the environment functions from Chapter 8 of CLtL2 were booted at the last meeting. You basically need to do a codewalk to do this right. > >>So I'm surprised that CLtL2 doesn't specify (at least not that I've >>been able to find) that SETF of LET should work. Is this perhaps >>simply an oversight, that should be brought to the attention of X3J13? > >I think it's just an oversight by the original SETF designers in MacLisp, >which the CL SETF is basically a clone of. You can bring it to our >attention, but I don't think anything will come of it in the near future, >as it's too late to add something significant like this to the language. I can't see that SETF of LET would really be that useful. Unless you make restrict the last form the LET to be a generalized location, which seems very restrictive, you would have to write setf methods for every special form in the language to make this work in the general case. -- Tim Moore moore@cs.utah.edu {bellcore,hplabs}!utah-cs!moore "Ah, youth. Ah, statute of limitations." -John Waters