From: fortunatus
Subject: Macro Writing Question #1
Date: 
Message-ID: <034a337e-4937-4bfb-baad-94fee4822afc@q30g2000prq.googlegroups.com>
Hi All,

I'm working on a macro using keyword args, and I wish to have a
unnamed default like this:

(defmacro test (&key arg)
  (when (eq arg 't) (setq arg (gensym)))
  ...

The idea is I can call it any of three ways:

(test)
(test :arg my-arg)
(test :arg t)

This works fine as long as I use T in that last form and not, say,
'T.  But for the sake of the fact that I will always forget and first
try 'T, I'd like to support that too.

Any ideas?  (I'm using SBCL...)  I suppose this ? applies to functions
as well as macros.  Thanks!

From: Jeff M.
Subject: Re: Macro Writing Question #1
Date: 
Message-ID: <043bf5df-559f-48be-9496-cbb4d0a4c359@e18g2000yqo.googlegroups.com>
On Dec 2, 1:05 pm, fortunatus <··············@excite.com> wrote:
> Hi All,
>
> I'm working on a macro using keyword args, and I wish to have a
> unnamed default like this:
>
> (defmacro test (&key arg)
>   (when (eq arg 't) (setq arg (gensym)))
>   ...
>
> The idea is I can call it any of three ways:
>
> (test)
> (test :arg my-arg)
> (test :arg t)
>
> This works fine as long as I use T in that last form and not, say,
> 'T.  But for the sake of the fact that I will always forget and first
> try 'T, I'd like to support that too.

Remember that 'T ==> (QUOTE T) at read time. Also, you could just use
GENSYM as the default value for the key, which would be a lot easier:

(DEFMACRO TEST (&KEY (ARG (GENSYM)))
  ...)

But it's hard to give much more help beyond that without knowing what
you want the macro to do. My gut tells me you're heading down the
wrong path with whatever solution you have in mind.

HTH, ;-)

Jeff M.
From: fortunatus
Subject: Re: Macro Writing Question #1
Date: 
Message-ID: <2cfd49b4-8268-4cd7-8f66-5f38494ceefb@g1g2000pra.googlegroups.com>
> Remember that 'T ==> (QUOTE T) at read time.

Ah - yes!  If I use EQUALP rather than EQ, that works - thanks!

> Also, you could just use
> GENSYM as the default value for the key, which would be a lot easier:
>
> (DEFMACRO TEST (&KEY (ARG (GENSYM)))
>   ...)

That precludes one of the forms I wish to support, when the keyword
and arg are omitted, in which case I avoid generating some code...

> My gut tells me you're heading down the
> wrong path with whatever solution you have in mind.

Mine too, I agree!  ;->  But it's working now, and somewhat
reasonable...
From: fortunatus
Subject: Re: Macro Writing Question #1
Date: 
Message-ID: <8caa8474-d970-4161-ab10-eec82101a745@k1g2000prb.googlegroups.com>
> Ah - yes!  If I use EQUALP rather than EQ, that works - thanks!

Actually, I take it back - this works on CLISP where I tried it first,
but not on SBCL.  Dang!
From: fortunatus
Subject: Re: Macro Writing Question #1
Date: 
Message-ID: <3526a77c-7c49-4798-8a0f-5080e4ae7a92@q26g2000prq.googlegroups.com>
> > Ah - yes!  If I use EQUALP rather than EQ, that works - thanks!
> Actually, I take it back - this works on CLISP where I tried it first,
> but not on SBCL.  Dang!

To support both (TEST :ARG T) and (TEST :ARG 'T) calls, on CLISP
all I had to do was:

(defmacro test (&key arg)
  (when (equalp arg 't) (setq arg (gensym)))
  ...

Whereas on SBCL I had to do:

(defmacro test (&key arg)
  (when (or (eq 't arg)
            (equalp '(quote t) arg)) (setq arg (gensym)))
  ...

Which does NOT work the same way on CLISP...  So now it's working, but
what is the closest to the Common Lisp standard behaviour???

BTW, my gut really hurts now!!!  ;->
From: ··················@gmail.com
Subject: Re: Macro Writing Question #1
Date: 
Message-ID: <5baa7abb-0f02-41c0-b828-77b31f576459@u14g2000yqg.googlegroups.com>
On Dec 2, 4:45 pm, fortunatus <··············@excite.com> wrote:
> > > Ah - yes!  If I use EQUALP rather than EQ, that works - thanks!
> > Actually, I take it back - this works on CLISP where I tried it first,
> > but not on SBCL.  Dang!
>
> To support both (TEST :ARG T) and (TEST :ARG 'T) calls, on CLISP
> all I had to do was:
>
> (defmacro test (&key arg)
>   (when (equalp arg 't) (setq arg (gensym)))
>   ...
>
> Whereas on SBCL I had to do:
>
> (defmacro test (&key arg)
>   (when (or (eq 't arg)
>             (equalp '(quote t) arg)) (setq arg (gensym)))
>   ...
>
> Which does NOT work the same way on CLISP...  So now it's working, but
> what is the closest to the Common Lisp standard behaviour???
>
> BTW, my gut really hurts now!!!  ;->

Well, T evaluates to itself. So you shouldn't quote it (there isn't
any point).
--------------
from http://sunsite.univie.ac.at/textbooks/cltl/clm/node70.html (CLTL)

[Constant]
t

The value of t is always t.
---------------

It may be that in one implementation T is its own boolean type,
Whereas in another it is actually a symbol which evaluates to itself.
From: ··············@excite.com
Subject: Re: Macro Writing Question #1
Date: 
Message-ID: <a24bf9ae-f80d-4e0c-b29a-e9a737dd7dab@w24g2000prd.googlegroups.com>
On Dec 2, 8:54 pm, ··················@gmail.com wrote:
> Well, T evaluates to itself. So you shouldn't quote it (there isn't
> any point).

Aren't you saying that T evaluates to 'T?  I mean, the expression T
(which is a variable) evaluates to the symbol T (which is a value)?

But then if I quote it, doesn't it (conceptually at least) save the
need to evalutate?

So that by quoting T, I am directly coding the value I wish to have in
the expression at that point.
From: ··················@gmail.com
Subject: Re: Macro Writing Question #1
Date: 
Message-ID: <8963c2b3-dd10-4aa7-bfa1-3a3aafacb0aa@k36g2000yqe.googlegroups.com>
On Dec 3, 9:51 am, ··············@excite.com wrote:
> On Dec 2, 8:54 pm, ··················@gmail.com wrote:
>
> > Well, T evaluates to itself. So you shouldn't quote it (there isn't
> > any point).
>
> Aren't you saying that T evaluates to 'T?  I mean, the expression T
> (which is a variable) evaluates to the symbol T (which is a value)?
>

No. 't should evaluate to t, but t does not evaluate to 't

> But then if I quote it, doesn't it (conceptually at least) save the
> need to evalutate?

Is quote evaluated? (yes)

>
> So that by quoting T, I am directly coding the value I wish to have in
> the expression at that point.

Imagine a keyword. Would you quote a keyword?
The whole point of the keyword is that you don't have to quote it.

---------------------------------------
An additional complication being that in the lambda of a macro,
things are not evaluated until the return-form.
(i.e. you can pass a symbol to a macro at top level)

ex.

>(defmacro foo (arg)
   (print arg)
 `(print ,arg))

>(foo bar)
BAR
>>> Error: {Determining function in error.}

>>> Error:Unbound variable: BAR
(#<COMPILED-FUNCTION 3:E196> ...)
---------------------------

so what you 'get' with your expansion is:
>(foo 't)    ;what you enter
>(quote t)   ;this print is in your macro expression [code to 'create' the form to be expanded]
>T           ; this print is the macro expansion
>T           ;this is what the print statement returns

---------------------------
So you see (eq t (quote t)) doesn't evaluate to t.
From: Thomas A. Russ
Subject: Re: Macro Writing Question #1
Date: 
Message-ID: <ymi7i6igem8.fsf@blackcat.isi.edu>
fortunatus <··············@excite.com> writes:

Well, of course, the real answer is to learn to use your macro properly
and not invoke it with 'T or 'VAR-NAME either.  In fact, I bet if you
called it with

   (test :arg 'my-variable)

it wouldn't do what you want either.

So pass it the proper arguments, namely unquoted symbols.


> Whereas on SBCL I had to do:
> 
> (defmacro test (&key arg)
>   (when (or (eq 't arg)
>             (equalp '(quote t) arg)) (setq arg (gensym)))
>   ...

But if you insist on ignoring my advice:

This is really the only safe way.  You could also use EQUAL rather than
EQUALP, by the way.  That is because you could be getting either T or
(QUOTE T) as the input.  I'm guessing that CLISP may do some
short-circuiting of reading quoted constants like T, NIL and perhaps
numbers as well.

-- 
Thomas A. Russ,  USC/Information Sciences Institute
From: Pascal J. Bourguignon
Subject: Re: Macro Writing Question #1
Date: 
Message-ID: <7ciqq1v3ga.fsf@pbourguignon.anevia.com>
···@sevak.isi.edu (Thomas A. Russ) writes:

> [...] I'm guessing that CLISP may do some
> short-circuiting of reading quoted constants like T, NIL and perhaps
> numbers as well.

Not at all.  It's conformant.


-- 
__Pascal Bourguignon__
From: ··············@excite.com
Subject: Re: Macro Writing Question #1
Date: 
Message-ID: <50f12c74-08bb-416a-ae44-10ef5553ada4@s9g2000prg.googlegroups.com>
On Dec 3, 7:38 am, ····@informatimago.com (Pascal J. Bourguignon)
wrote:
> ····@sevak.isi.edu (Thomas A. Russ) writes:
>
> > [...] I'm guessing that CLISP may do some
> > short-circuiting of reading quoted constants like T, NIL and perhaps
> > numbers as well.
>
> Not at all.  It's conformant.
>
> --
> __Pascal Bourguignon__


Is the SBCL behaviour also conformant?
From: Pascal J. Bourguignon
Subject: Re: Macro Writing Question #1
Date: 
Message-ID: <7ciqq19sqo.fsf@pbourguignon.anevia.com>
··············@excite.com writes:

> On Dec 3, 7:38�am, ····@informatimago.com (Pascal J. Bourguignon)
> wrote:
>> ····@sevak.isi.edu (Thomas A. Russ) writes:
>>
>> > [...] I'm guessing that CLISP may do some
>> > short-circuiting of reading quoted constants like T, NIL and perhaps
>> > numbers as well.
>>
>> Not at all. �It's conformant.
>
> Is the SBCL behaviour also conformant?

Yes of course.  There's no difference in behavior; when you pass 1 to
a macro, you get 1, when you pass '1 you get '1.


[···@simias :0.0 ~]$ clall '(defmacro m (arg) `(list (type-of (quote ,arg)) (quote ,arg)))' '(values (m t) (m (quote t)) (m 1) (m (quote 1)))'


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


Evaluation of
(DEFMACRO M (ARG) `(LIST (TYPE-OF ',ARG) ',ARG))
produced nothing on *STANDARD-OUTPUT*
produced nothing on *ERROR-OUTPUT*
produced no error
produced the following vals:
--> M


Evaluation of
(VALUES (M T) (M 'T) (M 1) (M '1))
produced nothing on *STANDARD-OUTPUT*
produced nothing on *ERROR-OUTPUT*
produced no error
produced the following vals:
--> (BOOLEAN T) ;
    (CONS 'T) ;
    (BIT 1) ;
    (CONS '1)

; 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
(DEFMACRO M (ARG) `(LIST (TYPE-OF ',ARG) ',ARG))
produced nothing on *STANDARD-OUTPUT*
produced nothing on *ERROR-OUTPUT*
produced no error
produced the following vals:
--> M


Evaluation of
(VALUES (M T) (M 'T) (M 1) (M '1))
produced nothing on *STANDARD-OUTPUT*
produced nothing on *ERROR-OUTPUT*
produced no error
produced the following vals:
--> (BOOLEAN T) ;
    (CONS 'T) ;
    (BIT 1) ;
    (CONS '1)


========================================================================
GNU Common Lisp (GCL) GCL 2.6.7 


Evaluation of
(DEFMACRO M (ARG)
  (LIST 'LIST (LIST 'TYPE-OF (LIST 'QUOTE ARG)) (LIST 'QUOTE ARG)))
produced nothing on *STANDARD-OUTPUT*
produced nothing on *ERROR-OUTPUT*
produced no error
produced the following vals:
--> M


Evaluation of
(VALUES (M T) (M 'T) (M 1) (M '1))
produced nothing on *STANDARD-OUTPUT*
produced nothing on *ERROR-OUTPUT*
produced no error
produced the following vals:
--> (SYMBOL T) ;
    (CONS 'T) ;
    (FIXNUM 1) ;
    (CONS '1)


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


Evaluation of
(DEFMACRO M (ARG)
  (SI:QUASIQUOTE (LIST (TYPE-OF '(SI:UNQUOTE ARG)) '(SI:UNQUOTE ARG))))
produced nothing on *STANDARD-OUTPUT*
produced nothing on *ERROR-OUTPUT*
produced no error
produced the following vals:
--> M


Evaluation of
(VALUES (M T) (M 'T) (M 1) (M '1))
produced nothing on *STANDARD-OUTPUT*
produced nothing on *ERROR-OUTPUT*
produced no error
produced the following vals:
--> (BOOLEAN T) ;
    (CONS 'T) ;
    ((INTEGER 1 1) 1) ;
    (CONS '1)


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

-- 
__Pascal Bourguignon__
From: Kaz Kylheku
Subject: Re: Macro Writing Question #1
Date: 
Message-ID: <20081218192335.427@gmail.com>
On 2008-12-03, Thomas A. Russ <···@sevak.isi.edu> wrote:
> (QUOTE T) as the input.  I'm guessing that CLISP may do some
> short-circuiting of reading quoted constants like T, NIL and perhaps
> numbers as well.

The expressions (QUOTE T) and T only mean the same thing when they are an
evaluated portion of code.  Reducing one to the other at read time would be
unbelievably broken.