From: Sam S. <sd...@gn...> - 2017-12-20 18:12:30
|
Hi, > * <Wbret-Plevy.Ubruyr@g-flfgrzf.pbz> [2017-12-20 17:35:44 +0000]: > >> This would require something like `lazy-let` with the following test case: > > (let ((a 1)) > (lazy-let (a b) > (print a) ; prints 1 > (print b) ; error - unbound variable > (setq a 10) ; inner binding of a is activated > (print a) ; prints 10 > (setq b 22)) ; binding of b is activated > (print b) ; error - unbound variable > (print a)) ; prints 1 > >>Alternatively, `lazy-let` can be implemented as something like >> (let ((a (if (boundp 'a) a (sys::%unbound)))) ...) > Certainly not, BOUNDP would only work with variables declared special. of course - that's the point > Hmm, there's perhaps nothing that another level of delayed evaluation > in order to get the desired scoping couldn't solve, so here it is: > > (defmacro lazy-let1 ((var) &body body) > (let ((shadow (gensym (symbol-name var)))) > `(let ((,shadow 'unbound));(sys::%unbound) > (flet ((access-a () (if (eq ,shadow 'unbound) ,var ,shadow)) > ((setf access-a) (x) (setf ,shadow x))) > (symbol-macrolet ((,var (access-a))) .,body))))) > > ; bonus point 0: Add more required gensyms > ; bonus point 1: Support a list of variables as per Sam's specification > ; bonus point 2: See if LET can work with clisp's %unbound trick > ; bonus point 3.5: See if you can make it work with special variables... > > (let ((a 1)) > (lazy-let1 (a) > (print a) ; prints 1 > (setq a 10) ; inner binding of a is activated > (print a)) ; prints 10 > (print a)) ; prints 1 Wow, I am impressed. However, I am not sure CLISP will compile that to good code. I think the first use of (setf access-a) should modify both (setf access-a) and access-a to be trivial operations. This is why I think a new special form TAGLET is necessary. -- Sam Steingold (http://sds.podval.org/) on darwin Ns 10.3.1504 http://steingoldpsychology.com http://www.childpsy.net http://thereligionofpeace.com https://jihadwatch.org http://memri.org My plan for 'after work' is to retire. |