From: Donald W. <dwi...@bo...> - 2014-08-20 00:35:34
|
With apologies for what is surely a naive question/issue I would like to access wisdom of the group about the recent discussion over backquote and how it has `broken things`. I am at best a cautiously-competent novice with Lisp and have been using SBCL as the primary development language for projects. At current I am using the version of SBCL that comes with Ubuntu 14.4 (1.1.14.debian). I have gone back to read the relevant SBCL-devel discussion in April under the thread title "pprinter regression", but have to admit that I'm not confidently able to make sense of it all. Part of this comes from not having a good handle on the implications of the backquote through all of its applications and indication posted elsewhere that the new backquote behaviour could affect many examples given in Graham's `On Lisp`. So enough of the lead-in: In my code I have several macros and uses of backquote outside of macros. I don't make much use of prettyprinting but am mostly concerned that my macros and other uses of backquote will keep working as they have previously. Short of upgrading to SBCL 1.2.2 and trying it out, is there a way I can determine if I will experience any drama (that is, failure) with my existing code with SBCL 1.2.2 and beyond? Best wishes, _don |
From: Jacek P. <rub...@go...> - 2014-08-20 05:52:06
|
https://github.com/thephoeron/let-over-lambda/commit/21830cd4ec059782a4321e11b36effe61dc3cdf7 That commit give you some clues. Jacek On 20/08/14 01:34, Donald Winiecki wrote: > With apologies for what is surely a naive question/issue I would like > to access wisdom of the group about the recent discussion over > backquote and how it has `broken things`. > > I am at best a cautiously-competent novice with Lisp and have been > using SBCL as the primary development language for projects. At > current I am using the version of SBCL that comes with Ubuntu 14.4 > (1.1.14.debian). > > I have gone back to read the relevant SBCL-devel discussion in April > under the thread title "pprinter regression", but have to admit that > I'm not confidently able to make sense of it all. Part of this comes > from not having a good handle on the implications of the backquote > through all of its applications and indication posted elsewhere that > the new backquote behaviour could affect many examples given in > Graham's `On Lisp`. > > So enough of the lead-in: > > In my code I have several macros and uses of backquote outside of > macros. I don't make much use of prettyprinting but am mostly > concerned that my macros and other uses of backquote will keep working > as they have previously. > > Short of upgrading to SBCL 1.2.2 and trying it out, is there a way I > can determine if I will experience any drama (that is, failure) with > my existing code with SBCL 1.2.2 and beyond? > > Best wishes, > > _don > > > ------------------------------------------------------------------------------ > Slashdot TV. > Video for Nerds. Stuff that matters. > http://tv.slashdot.org/ > > > _______________________________________________ > Sbcl-help mailing list > Sbc...@li... > https://lists.sourceforge.net/lists/listinfo/sbcl-help |
From: Orivej D. <or...@gm...> - 2014-08-20 07:57:13
|
> https://github.com/thephoeron/let-over-lambda/commit/21830cd4ec059782a4321e11b36effe61dc3cdf7 > > That commit give you some clues. In fact, released SBCL 1.2.2 broke a single function in LET-OVER-LAMBDA, namely FLATTEN. And here is how it was fixed: (defun flatten (x) (labels ((rec (x acc) (cond ((null x) acc) #-safe-sbcl ((typep x 'sb-impl::comma) (rec (sb-impl::comma-expr x) acc)) ((atom x) (cons x acc)) (t (rec (car x) (rec (cdr x) acc)))))) (rec x nil))) https://github.com/thephoeron/let-over-lambda/blob/7079cfd2e699c45819aabbf198cc93401361e01a/let-over-lambda.lisp But LET-OVER-LAMBDA is peculiar in its minimalism in that it neigher wants to install a backquote reader with list-form guarantees (such as FARE-QUASIQUOTE), nor use a full-fledged code walker (such as HU.DWIM.WALKER, as used in CL-INDETERMINISM and inderectly in DEFMACRO-ENHANCE, or SB-WALKER with #+sbcl as used in RUTILS, or, as ITERATE does, its own walker). > Short of upgrading to SBCL 1.2.2 and trying it out, is there a way I can > determine if I will experience any drama (that is, failure) with my > existing code with SBCL 1.2.2 and beyond? You don't have to upgrade because you can have multiple versions installed at the same time. Just download the binary release (http://prdownloads.sourceforge.net/sbcl/sbcl-1.2.2-x86-64-linux-binary.tar.bz2), unpack it anywhere and run ./run-sbcl.sh. |
From: Christophe R. <cs...@ca...> - 2014-08-20 08:40:47
|
Donald Winiecki <dwi...@bo...> writes: > Short of upgrading to SBCL 1.2.2 and trying it out, is there a way I can > determine if I will experience any drama (that is, failure) with my > existing code with SBCL 1.2.2 and beyond? Use of backquote as a list or vector constructor outside macros should be unaffected by the change of implementation strategy. For example, if you had functions like (defun make-my-thingy (x y) `(a-thingy :x ,x :y ,y)) the backquote is evaluated, and the evaluation semantics are well-defined. [ So calling (make-my-thingy 2 3) will return the list (A-THINGY :X 2 :Y 3) ] Simple macros are likewise unaffected, because their use of backquote is as a list constructor. So if you do (defmacro with-foo ((x foo) &body body) `(call-with-foo (lambda (,x) ,@body) ,foo)) and then call it with (with-foo (y (make-foo)) (frob y)) The evaluation of WITH-FOO performs recursive macroexpansion before functional evaluation, with the result that all the backquote substitutions are done before evaluation, and so again the result of the use of backquote is as before. The change in behaviour is in code which attempts to rewrite the contents of a backquote form _without_ performing the recursive macroexpansion or evaluation. Typically this code assumes that the relevant syntactical elements are all atoms within conses, and recursively alters the atoms in those conses. Something like (defun subst-var (from to form) (typecase form (symbol (if (eq form from) to form)) (atom form) (cons (cons (subst-var from to (car form)) (subst-var from to (cdr form)))))) which attempts to rewrite all uses of a variable `from' to a variable `to' within the form, without performing any macroexpansion. In the olden days, calling this on a backquoted form would "work" (subst-var 'x 'y '`(+ 1 (symbol-value ',x))) => `(+ ,1 (symbol-value ',y)) whereas in the new implementation it "doesn't work" (subst-var 'x 'y '`(+ 1 (symbol-value ',x))) => `(+ 1 (symbol-value ',x)) The reason I've put "work" and "doesn't work" in scarequotes is that in fact the subst-var implementation really only works by accident, or more charitably by convention; it performs its function if the code it is transforming is sufficiently well-behaved, and totally fails to function otherwise. As a code transformation it should be doing code walking including full macroexpansion; otherwise it will fail on any macros which introduce new symbols to fully macroexpanded code, such as anamorphic macros. A simple example might be: (defmacro awhen (test body) `(let ((it test)) (when it ,@body))) Then (subst-var 'it 'it2 '`(awhen (member '3 foo) (cdr it))) will perform half the rename, changing IT to IT2 in the body but not the binding -- note that this is always a problem, not a function of the particular implementation of backquote. The new problem arises because the backquote implementation "hides away" the unquoted forms inside structures, which are opaque to naïve code transformers such as SUBST-VAR above, and there are some uses of naïve code transformers in the wild (for example, for automatic lambda generators or similar) which therefore no longer work. I can't remember off the top of my head whether /On Lisp/ does any of this simple codewalking. My quick scan of an online copy of the book didn't show anything up: in fact in chapter 20 (on CPS) it looks to me as if he deliberately and explicitly avoids codewalking, instead relying on user convention to limit the difficulty of representing a continuation. So I think that the /On Lisp/ utilities should simply carry on working unaffected. Best wishes, Christophe |
From: Matt K. <kau...@cs...> - 2014-08-21 13:27:41
|
Thank you for that interesting explanation! For what it's worth, here's a brief very simple addition. In building our system (ACL2) we read the forms in a file under different *features* and compare the results. Formerly we compared using equal; now, to accommodate the use of structures by backquote in SBCL 1.2.2, we use equalp. The following SBCL 1.2.2 log helped me to see what's going on: * (setq *print-pretty* nil) NIL * (read) `,x (SB-INT:QUASIQUOTE #S(SB-IMPL::COMMA :EXPR X :KIND 0)) * -- Matt From: Christophe Rhodes <cs...@ca...> Date: Wed, 20 Aug 2014 09:40:34 +0100 Cc: sbc...@li... Donald Winiecki <dwi...@bo...> writes: > Short of upgrading to SBCL 1.2.2 and trying it out, is there a way I can > determine if I will experience any drama (that is, failure) with my > existing code with SBCL 1.2.2 and beyond? Use of backquote as a list or vector constructor outside macros should be unaffected by the change of implementation strategy. For example, if you had functions like (defun make-my-thingy (x y) `(a-thingy :x ,x :y ,y)) the backquote is evaluated, and the evaluation semantics are well-defined. [ So calling (make-my-thingy 2 3) will return the list (A-THINGY :X 2 :Y 3) ] Simple macros are likewise unaffected, because their use of backquote is as a list constructor. So if you do (defmacro with-foo ((x foo) &body body) `(call-with-foo (lambda (,x) ,@body) ,foo)) and then call it with (with-foo (y (make-foo)) (frob y)) The evaluation of WITH-FOO performs recursive macroexpansion before functional evaluation, with the result that all the backquote substitutions are done before evaluation, and so again the result of the use of backquote is as before. The change in behaviour is in code which attempts to rewrite the contents of a backquote form _without_ performing the recursive macroexpansion or evaluation. Typically this code assumes that the relevant syntactical elements are all atoms within conses, and recursively alters the atoms in those conses. Something like (defun subst-var (from to form) (typecase form (symbol (if (eq form from) to form)) (atom form) (cons (cons (subst-var from to (car form)) (subst-var from to (cdr form)))))) which attempts to rewrite all uses of a variable `from' to a variable `to' within the form, without performing any macroexpansion. In the olden days, calling this on a backquoted form would "work" (subst-var 'x 'y '`(+ 1 (symbol-value ',x))) => `(+ ,1 (symbol-value ',y)) whereas in the new implementation it "doesn't work" (subst-var 'x 'y '`(+ 1 (symbol-value ',x))) => `(+ 1 (symbol-value ',x)) The reason I've put "work" and "doesn't work" in scarequotes is that in fact the subst-var implementation really only works by accident, or more charitably by convention; it performs its function if the code it is transforming is sufficiently well-behaved, and totally fails to function otherwise. As a code transformation it should be doing code walking including full macroexpansion; otherwise it will fail on any macros which introduce new symbols to fully macroexpanded code, such as anamorphic macros. A simple example might be: (defmacro awhen (test body) `(let ((it test)) (when it ,@body))) Then (subst-var 'it 'it2 '`(awhen (member '3 foo) (cdr it))) will perform half the rename, changing IT to IT2 in the body but not the binding -- note that this is always a problem, not a function of the particular implementation of backquote. The new problem arises because the backquote implementation "hides away" the unquoted forms inside structures, which are opaque to naïve code transformers such as SUBST-VAR above, and there are some uses of naïve code transformers in the wild (for example, for automatic lambda generators or similar) which therefore no longer work. I can't remember off the top of my head whether /On Lisp/ does any of this simple codewalking. My quick scan of an online copy of the book didn't show anything up: in fact in chapter 20 (on CPS) it looks to me as if he deliberately and explicitly avoids codewalking, instead relying on user convention to limit the difficulty of representing a continuation. So I think that the /On Lisp/ utilities should simply carry on working unaffected. Best wishes, Christophe ------------------------------------------------------------------------------ Slashdot TV. Video for Nerds. Stuff that matters. http://tv.slashdot.org/ _______________________________________________ Sbcl-help mailing list Sbc...@li... https://lists.sourceforge.net/lists/listinfo/sbcl-help |