Kaz Kylheku <kkylh...@gmail.com> writes: > On 2008-12-11, Chris Riesbeck <Chris.Riesb...@gmail.com> wrote: >> `(,@10) returns 10 on Allegro, Lispworks Personal and SBCL.
> This is fine.
>> I think the form is not legal but there's a common optimization that all
> It's ``legal'', or should we say, well-defined, because (APPEND 10) is > well-defined. The last argument in APPEND can be an atom other than NIL.
> `(,@form)
> is by definition equivalent to
> (append form)
> See 2.4.6 Backquote in ANSI CL / CL HyperSpec.
As I read 2.4.6, the form is by definition equivalent to
Evaluation of (OR (IGNORE-ERRORS `(,@10)) 10) produced nothing on *STANDARD-OUTPUT* produced nothing on *ERROR-OUTPUT* produced no error produced the following vals: --> 10
; loading system definition from ; /usr/share/common-lisp/systems/asdf-binary-locations.asd into ; #<PACKAGE "ASDF0"> ; registering #<SYSTEM ASDF-BINARY-LOCATIONS {100273BDB1}> as ; ASDF-BINARY-LOCATIONS
Evaluation of (OR (IGNORE-ERRORS 10) 10) produced nothing on *STANDARD-OUTPUT* produced nothing on *ERROR-OUTPUT* produced no error produced the following vals: --> 10
======================================================================== GNU Common Lisp (GCL) GCL 2.6.7
Evaluation of (OR (IGNORE-ERRORS 10) 10) produced nothing on *STANDARD-OUTPUT* produced nothing on *ERROR-OUTPUT* produced no error produced the following vals: --> 10
Evaluation of (OR (IGNORE-ERRORS (SI:QUASIQUOTE ((SI:UNQUOTE-SPLICE 10)))) 10) produced nothing on *STANDARD-OUTPUT* produced nothing on *ERROR-OUTPUT* produced no error produced the following vals: --> 10
> Kaz Kylheku <kkylh...@gmail.com> writes: > > On 2008-12-11, Chris Riesbeck <Chris.Riesb...@gmail.com> wrote: > >> `(,@10) returns 10 on Allegro, Lispworks Personal and SBCL.
> > This is fine.
> >> I think the form is not legal but there's a common optimization that all
> > It's ``legal'', or should we say, well-defined, because (APPEND 10) is > > well-defined. The last argument in APPEND can be an atom other than NIL.
> > `(,@form)
> > is by definition equivalent to
> > (append form)
> > See 2.4.6 Backquote in ANSI CL / CL HyperSpec.
> As I read 2.4.6, the form is by definition equivalent to
> >> On 2008-12-11, Chris Riesbeck <Chris.Riesb...@gmail.com> wrote: > >>> `(,@10) returns 10 on Allegro, Lispworks Personal and SBCL.
> >> This is fine.
> >>> I think the form is not legal but there's a common optimization that all
> >> It's ``legal'', or should we say, well-defined, because (APPEND 10) is > >> well-defined. The last argument in APPEND can be an atom other than NIL.
> >> `(,@form)
> >> is by definition equivalent to
> >> (append form)
> >> See 2.4.6 Backquote in ANSI CL / CL HyperSpec.
> > As I read 2.4.6, the form is by definition equivalent to
> > `(,@10 . nil)
> > which is equivalent to
> > (append 10 'nil)
> > which is an error. No?
> The expansion of backquote is implementation specific.
> I don't remember CLHS saying that an implementation should choose the > expansion that gives a result and not an error.
> So implementations giving either 10 or an error are conformant.
> On the other hand, and by consequence, a program that use this > expression, must behave the same whatever implementation it runs on to > be conformant.
> So if you consider only the program: `(,@10) > I would think it is not a conformant program.
> But if you consider the program: (or (ignore-errors `(,@10)) 10) > then I would think it is a conformant program.
> Evaluation of > (OR (IGNORE-ERRORS `(,@10)) 10) > produced nothing on *STANDARD-OUTPUT* > produced nothing on *ERROR-OUTPUT* > produced no error > produced the following vals: > --> 10
> ; loading system definition from > ; /usr/share/common-lisp/systems/asdf-binary-locations.asd into > ; #<PACKAGE "ASDF0"> > ; registering #<SYSTEM ASDF-BINARY-LOCATIONS {100273BDB1}> as > ; ASDF-BINARY-LOCATIONS
> Evaluation of > (OR (IGNORE-ERRORS 10) 10) > produced nothing on *STANDARD-OUTPUT* > produced nothing on *ERROR-OUTPUT* > produced no error > produced the following vals: > --> 10
> ======================================================================== > GNU Common Lisp (GCL) GCL 2.6.7
> Evaluation of > (OR (IGNORE-ERRORS 10) 10) > produced nothing on *STANDARD-OUTPUT* > produced nothing on *ERROR-OUTPUT* > produced no error > produced the following vals: > --> 10
> Evaluation of > (OR (IGNORE-ERRORS (SI:QUASIQUOTE ((SI:UNQUOTE-SPLICE 10)))) 10) > produced nothing on *STANDARD-OUTPUT* > produced nothing on *ERROR-OUTPUT* > produced no error > produced the following vals: > --> 10
>> >> On 2008-12-11, Chris Riesbeck <Chris.Riesb...@gmail.com> wrote: >> >>> `(,@10) returns 10 on Allegro, Lispworks Personal and SBCL.
>> >> This is fine.
>> >>> I think the form is not legal but there's a common optimization that all
>> >> It's ``legal'', or should we say, well-defined, because (APPEND 10) is >> >> well-defined. The last argument in APPEND can be an atom other than NIL.
>> >> `(,@form)
>> >> is by definition equivalent to
>> >> (append form)
>> >> See 2.4.6 Backquote in ANSI CL / CL HyperSpec.
>> > As I read 2.4.6, the form is by definition equivalent to
>> > `(,@10 . nil)
>> > which is equivalent to
>> > (append 10 'nil)
>> > which is an error. No?
>> The expansion of backquote is implementation specific.
>> I don't remember CLHS saying that an implementation should choose the >> expansion that gives a result and not an error.
>> So implementations giving either 10 or an error are conformant.
>> [...] > I'm not sure what shows.
> Also the question is when an error should be signalled. > At read time? At run time? Depending on the kind > of error?
Yes, we need to consider when the errors must be signaled.
Perhaps that programs that are not read, macroexpanded and compiled by conformant programs cannot be conformant?
Further study is needed... -- __Pascal Bourguignon__
In a form something like `(,1 ,2 ,3 ,4) we can identify as being any tail of the list, for instance by seeing it as: `(,1 ,2 . (,3 ,4))
The above rule works nicely: xn in this case is (,3 ,4) and by the [form] -> (list `form) transformation it becomes (list `(,3 ,4)). So now we end up with
Since most of the forms are ``lifted'' into the domain of one element lists, we need CAR to reduce one of them back down, to get an atom for the dot position.
But there is one form which is not lifted into a one-element list: namely, ,@form -> form. This CAR-based rule now neatly tells us why (... . ,@form) is conceptually wrong. The form hasn't been lifted into the list domain. Even if FORM produces a list, it's wrong list; it's not the one-element wrapper list that needs to be peeled off to be peeled off.
So what becomes of `(#(,a ,b) . #(,c ,d))?
(append (list `#(,a ,b)) (car (list `#(,c ,d))))
Check!
The . NIL) case is handled too, since (CAR `,NIL) is NIL. So there is no need to have a special case for the non-dotted syntax.
Alternatively, the definition could keep the ATOM as distinct from the [xj] forms but say that the ATOM is also subject to its own transformation rules similar to the ones that apply to the [xj] forms, and then appears as the last argument of the append, those rules being:
[atom-form] becomes `atom-form (and so [nil] becomes nil) [,atom-form] becomes form [,@atom-form] is undefined
This covers all the cases.
Somehow I did the right thing in the CLISP backquote. (Or somenoe who cleaned up after me?) ;)
** - Continuable Error SETQ(SYSTEM::*BACKQUOTE-OPTIMIZE-APPEND*): #<PACKAGE SYSTEM> is locked If you continue (by typing 'continue'): Ignore the lock and proceed The following restarts are also available: ABORT :R1 ABORT Break 1 [13]> continue NIL [14]> (macroexpand '`(,a ,b ,c . #(,3 ,4))) (APPEND (LIST A) (APPEND (LIST B) (APPEND (LIST C) `#(,3 ,4)))) ; T
Good! The . #(,3 ,4) wasn't turned into (QUOTE #(,3 ,4)) as the spec seems to require. Phew!
Kaz Kylheku <kkylh...@gmail.com> wrote: +--------------- | What if I want to annotate a cons which is constructed from two vectors? | | `(#(,a ,b ,c) . #(,d ,e ,f)) | | Oops. +---------------
> Kaz Kylheku <kkylh...@gmail.com> wrote: > +--------------- >| What if I want to annotate a cons which is constructed from two vectors? >| >| `(#(,a ,b ,c) . #(,d ,e ,f)) >| >| Oops. > +---------------
Kaz Kylheku <kkylh...@gmail.com> wrote: +--------------- | Rob Warnock <r...@rpw3.org> wrote: | > Kaz Kylheku <kkylh...@gmail.com> wrote: | > +--------------- | >| What if I want to annotate a cons which is constructed from two vectors? | >| `(#(,a ,b ,c) . #(,d ,e ,f)) | >| Oops. | > +--------------- | > | > What "oops"? | > > (let ((a 1) (b 2) (c 3) (d 4) (e 5) (f 6)) | > `(#(,a ,b ,c) . #(,d ,e ,f))) | > (#(1 2 3) . #(4 5 6)) | > > | | Good. The oops is that the spec doesn't require the above behavior. | The form matches the case: | | `(x1 . atom) -> (append [x1] (quote atom)) | | Where x1 is #(,a ,b ,c) and atom is #(,d ,e ,f), | and [x1] follows the [form] -> (list `form) transformation. | Hence the expansion is (append (list `#(,a b c)) (quote #(,d ,e ,f)) | which is nonsense with dangling commas. +---------------
Another possible interpretation -- not in obvious direct contradiction to CLHS 2.4.6 [if one allows non-conflicting extensions] -- is that there is a rule missing from CLHS 2.4.6:
`(x1 . x2) ==> (cons `x1 `x2)
which for your example would result in this expansion:
p.s. FWIW, the actual transformation implemented by CMUCL for the same example is this:
`(#(,a ,b ,c) . #(,d ,e ,f))) ==> (lisp::backq-cons (lisp::backq-vector (lisp::backq-list a b c)) (lisp::backq-vector (lisp::backq-list d e f))) ==> (cons (coerce (list a b c) 'simple-vector) (coerce (list d e f) 'simple-vector))
----- Rob Warnock <r...@rpw3.org> 627 26th Avenue <URL:http://rpw3.org/> San Mateo, CA 94403 (650)572-2607