Prev: lisp, java and evolution of types
Next: URGENT
From: Pascal Costanza on 3 Nov 2009 09:27 Nicolas Neuss wrote: > Pascal Costanza <pc(a)p-cos.net> writes: > >> _f is too cryptic, I think. What about 'modify-using? > > _f refers to the suffix "f" occurring in several CL operators with > similar modifying behavior. So I think the name fits. And: since it > appears in "On Lisp", I guess that there will be quite some people > knowing it under this name. Fair enough. I still don't like it. ;) Pascal -- My website: http://p-cos.net Common Lisp Document Repository: http://cdr.eurolisp.org Closer to MOP & ContextL: http://common-lisp.net/project/closer/
From: Kaz Kylheku on 3 Nov 2009 13:34 On 2009-11-03, Nicolas Neuss <lastname(a)math.uni-karlsruhe.de> wrote: > Pascal Costanza <pc(a)p-cos.net> writes: > >> _f is too cryptic, I think. What about 'modify-using? > > _f refers to the suffix "f" occurring in several CL operators with > similar modifying behavior. So I think the name fits. And: since it > appears in "On Lisp", I guess that there will be quite some people > knowing it under this name. I highly recommend writing this: (setf a (append a b)) to obtain the effect of this: (setf a (append a b)) :)
From: Nicolas Neuss on 3 Nov 2009 16:33 Kaz Kylheku <kkylheku(a)gmail.com> writes: > > I highly recommend writing this: > > (setf a (append a b)) > > to obtain the effect of this: > > (setf a (append a b)) But what about (_f append (bar-accessor (session-value 'foo)) '(hello)) ?
From: Pascal J. Bourguignon on 3 Nov 2009 16:53 Nicolas Neuss <lastname(a)math.uni-karlsruhe.de> writes: > Kaz Kylheku <kkylheku(a)gmail.com> writes: > >> >> I highly recommend writing this: >> >> (setf a (append a b)) >> >> to obtain the effect of this: >> >> (setf a (append a b)) > > But what about > > (_f append (bar-accessor (session-value 'foo)) '(hello)) What bothers me most, is what if you want actually (setf a (frob b (append c (nicate a) d) e)) ? (_f (frob b (append c _ d) e) (bar-accessor (session-value 'foo))) perhaps? -- __Pascal Bourguignon__
From: Kaz Kylheku on 3 Nov 2009 19:41
On 2009-11-03, Pascal J. Bourguignon <pjb(a)informatimago.com> wrote: > Nicolas Neuss <lastname(a)math.uni-karlsruhe.de> writes: > >> Kaz Kylheku <kkylheku(a)gmail.com> writes: >> >>> >>> I highly recommend writing this: >>> >>> (setf a (append a b)) >>> >>> to obtain the effect of this: >>> >>> (setf a (append a b)) >> >> But what about >> >> (_f append (bar-accessor (session-value 'foo)) '(hello)) > > What bothers me most, is what if you want actually > (setf a (frob b (append c (nicate a) d) e)) ? Then you actually write: (setf a (frob b (append c (nicate a) d) e)) ? There is no side effect if you evaluate a simple variable twice. In fact you can't avoid that. An update requires two accesses: read and write. These ``F'' macros ensure that there are no additional redundant accesses. On the read access, the place is reduced to some object which can then be passed to a store form to update that place without any additional evaluation. So the interesting case arises when we replace your A by some big expression: (setf (BIG EXPR ...) (frob b (append c (nicate (BIG EXPR ...)) d) e)) ? > (_f (frob b (append c _ d) e) (bar-accessor (session-value 'foo))) > > perhaps? What you want is this: (patternsdf-update (frob (update ((var1 place1) (var2 place2) ... (varN placeN)) ... ... ... any number of forms involving var1 through varN as sources ... of values, as well as targets of assignments. ... ...) UPDATE asserts that N places are to be updated. The bodies of the construct refer to the places using names var1 through varN. Each place is accessed without evaluating the place expression twice. The update works like this, in the abstract semantics: prior to the execution of the body, the places are converted into load forms, which are accessed once to retrieve the values of the variables. The action in the body happens using the variables. When the body terminates, the update is committed using the corresponding store forms. If the body terminates by a non-local exit, then the update is aborted. It's implementation-defined how many of the places have been accessed by that point (we'd like to be able to optimize by interleaving some of the accesses into the evaluation of the body, but no place is updated until the body terminates properly). The places are updated in order; if the store form for placeM terminates with a nonlocal exit, then places 1 thorugh M-1 are updated, but M through N are not updated. Furthermore, introducing UPDATE*: (update* ((var1 place1) (var2 place2) ... (varN placeN)) ... ...) In this form, the placeM expression can contain references to var1 through varM-1. This means that the evaluation of the places is interleaved with the establishment of the variable bindings. So, how to express: (setf (BIG EXPR ...) (frob b (append c (nicate (BIG EXPR ...)) d) e)) ? (setf a (frob b (append c (nicate a) d) e)) Like this: (update ((a (BIG EXPR ...))) (setf a (frob b (append c (nicate a) d) e))) So here, it is understood that A is evaluated just once. It's easy to read: ``Do this update, where all occurence of A are understood to represent the place (BIG EXPR ...), such that (BIG EXPR ...) is evaluated only once.'' I could guess the meaning of this better than some obscure _F which cofuses the once-only semantics with a particular /way/ of treating a symbolic argument as a function and passing arguments to it. I believe that it should be possible to implement UPDATE and UPDATE* with the pieces we have in Common Lisp. Moreover, these macros could make it easy to write custom updater functions which avoid multiple evaluation, without having to know DEFINE-SETF-EXPANDER, and GET-SETF-EXPANSION. (defmacro push-clone (val place) (let ((temp (gensym))) `(update ((,temp ,place)) (setf ,temp (cons ,val ,temp))))) |