Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

`(,@10)

6 views
Skip to first unread message

Chris Riesbeck

unread,
Dec 11, 2008, 3:20:39 PM12/11/08
to
`(,@10) returns 10 on Allegro, Lispworks Personal and SBCL.

I think the form is not legal but there's a common optimization that all
three implementations use that makes this work.

Or am I misreading the Hyperspec and this is OK?

Rainer Joswig

unread,
Dec 11, 2008, 4:43:50 PM12/11/08
to
In article <6qdb0oF...@mid.individual.net>,
Chris Riesbeck <Chris.R...@gmail.com> wrote:


Check the result of (append 10) -> 10

`(,@10) is the equivalent of (append 10)

--
http://lispm.dyndns.org/

Kaz Kylheku

unread,
Dec 11, 2008, 6:28:40 PM12/11/08
to
On 2008-12-11, Chris Riesbeck <Chris.R...@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.

Todd Sabin

unread,
Dec 12, 2008, 9:02:55 AM12/12/08
to
Kaz Kylheku <kkyl...@gmail.com> writes:

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?

--
Todd Sabin <todd....@gmail.com>

Pascal J. Bourguignon

unread,
Dec 12, 2008, 9:24:53 AM12/12/08
to
Todd Sabin <todd....@gmail.com> writes:

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.


[pjb@simias :0.0 ~]$ clall '(or (ignore-errors `(,@10)) 10)'


========================================================================
CLISP 2.43 (2007-11-18) (built 3414750461) (memory 3414750593)


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

========================================================================
SBCL 1.0.14-gentoo


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


========================================================================
ECL 0.9j


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


========================================================================

[pjb@simias :0.0 ~]$

--
__Pascal Bourguignon__

jos...@corporate-world.lisp.de

unread,
Dec 12, 2008, 9:51:16 AM12/12/08
to
On 12 Dez., 15:02, Todd Sabin <todd.sa...@gmail.com> wrote:
> 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
>
>   `(,@10 . nil)
>
> which is equivalent to
>
>    (append 10 'nil)
>
> which is an error.  No?
>
> --
> Todd Sabin                                          <todd.sa...@gmail.com>

hmm, could be.

I find the whole chapter to be completely vague. I would guess that it
would be much better if things like backquote syntax would be nailed
down.

jos...@corporate-world.lisp.de

unread,
Dec 12, 2008, 9:55:34 AM12/12/08
to
On 12 Dez., 15:24, p...@informatimago.com (Pascal J. Bourguignon)
wrote:
> Todd Sabin <todd.sa...@gmail.com> writes:
> > Kaz Kylheku <kkylh...@gmail.com> writes:

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?


Pascal J. Bourguignon

unread,
Dec 12, 2008, 11:20:25 AM12/12/08
to
"jos...@corporate-world.lisp.de" <jos...@corporate-world.lisp.de> writes:

> On 12 Dez., 15:24, p...@informatimago.com (Pascal J. Bourguignon)
> wrote:
>> Todd Sabin <todd.sa...@gmail.com> writes:
>> > 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
>>
>> >   `(,@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__

Kaz Kylheku

unread,
Dec 12, 2008, 11:19:22 PM12/12/08
to
On 2008-12-12, Todd Sabin <todd....@gmail.com> wrote:
> As I read 2.4.6, the form is by definition equivalent to
>
> `(,@10 . nil)

Damn, you're right. This case "may" be reduced to one involving (quote nil).

What a stupidity.

Actually treating ( ... . atom) as (append ... (quote atom)) is silly too,
because a vector can be an atom, and backquoting vectors is supported.

What if I want to annotate a cons which is constructed from two vectors?

`(#(,a ,b ,c) . #(,d ,e ,f))

Oops.

A possible right rule is:

(x1 x2 ... xn-1 . xn) -> (append [x1] [x2] ... [xn-1] (car [xn]))

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

(append (list `,1) (list `,2) (car (list `(,3 ,4))))

Which is right: (1 2 3 4).

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?) ;)

[12]> (setf system::*backquote-optimize-append* nil)

** - 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!

Rob Warnock

unread,
Dec 12, 2008, 11:37:07 PM12/12/08
to
Kaz Kylheku <kkyl...@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))
>


-Rob

-----
Rob Warnock <rp...@rpw3.org>
627 26th Avenue <URL:http://rpw3.org/>
San Mateo, CA 94403 (650)572-2607

Kaz Kylheku

unread,
Dec 12, 2008, 11:52:16 PM12/12/08
to
On 2008-12-13, Rob Warnock <rp...@rpw3.org> wrote:
> Kaz Kylheku <kkyl...@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.

Rob Warnock

unread,
Dec 13, 2008, 9:50:30 AM12/13/08
to
+---------------

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:

`(#(,a ,b ,c) . #(,d ,e ,f))) ==>
(cons `#(,a ,b ,c) `#(,d ,e ,f))) ==>
(cons (apply #'vector `(,a ,b ,c)) (apply #'vector `(,d ,e ,f))) ==>
(cons (apply #'vector (append (list a) (list b) (list c)))
(apply #'vector (append (list d) (list e) (list f))))


-Rob

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))

0 new messages