From: jmckitrick
Subject: Accessing both symbol and contents within macro
Date: 
Message-ID: <1181523192.008567.64050@q66g2000hsg.googlegroups.com>
I want a form that looks like this:

(valid-tokens-p (foo "hello") bar baz)

that evaluates to this:

(and (string= foo "hello") (plusp (length bar)) (plusp (length baz)))

Here's the macro I've defined so far:

(defmacro valid-tokens-p (&rest tokens)
  "Check if TOKENS are valid.
Each item in TOKENS is checked.  If the item is a list, the check
passes
if the first item in the list (the token) is STRING= the second item.
If the item is not a list, the check passes if LENGTH of the token is
> 0."
  `(and
     ,@(loop for token in tokens collect
	    (if (listp token)
		(when (and (symbolp (first token))
			   (stringp (second token)))
		  `(string= ,(first token) ,(second token)))
		(when (symbolp token)
		  `(plusp (length ,token)))))))


An earlier version didn't check the types of the tokens (other than
the LISTP call, of course) but I wanted to make it more robust.  So I
want to be sure that each symbol is bound to a string as well.
Obviously this doesn't work:

(when (and (symbolp token) (stringp token))
.
.
.)

How can I get to the value of TOKEN in this case without EVAL?

From: Dan Bensen
Subject: Re: Accessing both symbol and contents within macro
Date: 
Message-ID: <f4icgo$399$1@wildfire.prairienet.org>
jmckitrick wrote:
> I want a form that looks like this:
> (valid-tokens-p (foo "hello") bar baz)
> that evaluates to this:
> (and (string= foo "hello") (plusp (length bar)) (plusp (length baz)))

>      ,@(loop for token in tokens collect
> 	    (if (listp token)
> 		(when (and (symbolp (first token))
> 			   (stringp (second token)))
> 		  `(string= ,(first token) ,(second token)))
>             (when (symbolp token)
> 	        `(plusp (length ,token)))))))

If you want to return one and only one test form for each token,
I would use cond or an IF cascade instead of WHEN.

> How can I get to the value of TOKEN in this case without EVAL?

You have to return code that does that at runtime.

-- 
Dan
www.prairienet.org/~dsb/
From: Pebblestone
Subject: Re: Accessing both symbol and contents within macro
Date: 
Message-ID: <1181548739.828778.74310@i13g2000prf.googlegroups.com>
> An earlier version didn't check the types of the tokens (other than
> the LISTP call, of course) but I wanted to make it more robust.  So I
> want to be sure that each symbol is bound to a string as well.
> Obviously this doesn't work:
>
> (when (and (symbolp token) (stringp token))
> .
> .
> .)
>
> How can I get to the value of TOKEN in this case without EVAL?

====

I don't know exactly what you want to do, but is it what you want?

(defmacro valid-tokens-p (&rest tokens)
  "Check if TOKENS are valid.
Each item in TOKENS is checked.  If the item is a list, the check
passes
if the first item in the list (the token) is STRING= the second item.
If the item is not a list, the check passes if LENGTH of the token is
> 0."
  `(and
	,@(loop for token in tokens collect
		   (if (listp token)
			   (when (and (symbolp (first token))
						  (stringp (second token)))
				 `(and (boundp ,#1=(first token))
					   (stringp ,#1#)
					   (string= ,#1# ,(second token))))
			   (when (symbolp token)
				 `(and (boundp ,token)
					   (stringp ,token)
					   (plusp (length ,token))))))))

===

which will expand (valid-tokens-p (foo "hello") bar baz) into:

(AND (AND (BOUNDP FOO) (STRINGP FOO) (STRING= FOO "hello"))
     (AND (BOUNDP BAR) (STRINGP BAR) (PLUSP (LENGTH BAR)))
     (AND (BOUNDP BAZ) (STRINGP BAZ) (PLUSP (LENGTH BAZ))))


Correct?
From: jmckitrick
Subject: Re: Accessing both symbol and contents within macro
Date: 
Message-ID: <1181580941.490806.119170@h2g2000hsg.googlegroups.com>
On Jun 11, 3:58 am, Pebblestone <··········@gmail.com> wrote:
> I don't know exactly what you want to do, but is it what you want?
>
> (defmacro valid-tokens-p (&rest tokens)
>   "Check if TOKENS are valid.
> Each item in TOKENS is checked.  If the item is a list, the check
> passes
> if the first item in the list (the token) is STRING= the second item.
> If the item is not a list, the check passes if LENGTH of the token is> 0."
>
>   `(and
>         ,@(loop for token in tokens collect
>                    (if (listp token)
>                            (when (and (symbolp (first token))
>                                                   (stringp (second token)))
>                                  `(and (boundp ,#1=(first token))
>                                            (stringp ,#1#)
>                                            (string= ,#1# ,(second token))))
>                            (when (symbolp token)
>                                  `(and (boundp ,token)
>                                            (stringp ,token)
>                                            (plusp (length ,token))))))))

That's definitely what I want, because the mistake I made was
including the type checks in the macro code rather than the generated
code.  But I'm not familiar with the #1# notation.  What does that
accomplish?
From: Pascal Bourguignon
Subject: Re: Accessing both symbol and contents within macro
Date: 
Message-ID: <87ejkjmg93.fsf@thalassa.lan.informatimago.com>
jmckitrick <···········@yahoo.com> writes:

> I want a form that looks like this:
>
> (valid-tokens-p (foo "hello") bar baz)
>
> that evaluates to this:
>
> (and (string= foo "hello") (plusp (length bar)) (plusp (length baz)))
>
> Here's the macro I've defined so far:
>
> (defmacro valid-tokens-p (&rest tokens)
>   "Check if TOKENS are valid.
> Each item in TOKENS is checked.  If the item is a list, the check
> passes
> if the first item in the list (the token) is STRING= the second item.
> If the item is not a list, the check passes if LENGTH of the token is
>> 0."
>   `(and
>      ,@(loop for token in tokens collect
> 	    (if (listp token)
> 		(when (and (symbolp (first token))
> 			   (stringp (second token)))
> 		  `(string= ,(first token) ,(second token)))
> 		(when (symbolp token)
> 		  `(plusp (length ,token)))))))
>
>
> An earlier version didn't check the types of the tokens (other than
> the LISTP call, of course) but I wanted to make it more robust.  So I
> want to be sure that each symbol is bound to a string as well.
> Obviously this doesn't work:
>
> (when (and (symbolp token) (stringp token))
> .
> .
> .)
>
> How can I get to the value of TOKEN in this case without EVAL?

You cannot.

Asking this is like asking How can I know what will be put in this box
in one thousand years?

-- 
__Pascal Bourguignon__                     http://www.informatimago.com/

NOTE: The most fundamental particles in this product are held
together by a "gluing" force about which little is currently known
and whose adhesive power can therefore not be permanently
guaranteed.
From: jmckitrick
Subject: Re: Accessing both symbol and contents within macro
Date: 
Message-ID: <1181533535.467032.276770@q66g2000hsg.googlegroups.com>
On Jun 10, 9:28 pm, Pascal Bourguignon <····@informatimago.com> wrote:
> jmckitrick <···········@yahoo.com> writes:
> > I want a form that looks like this:
>
> > (valid-tokens-p (foo "hello") bar baz)
>
> > that evaluates to this:
>
> > (and (string= foo "hello") (plusp (length bar)) (plusp (length baz)))
>
> > Here's the macro I've defined so far:
>
> > (defmacro valid-tokens-p (&rest tokens)
> >   "Check if TOKENS are valid.
> > Each item in TOKENS is checked.  If the item is a list, the check
> > passes
> > if the first item in the list (the token) is STRING= the second item.
> > If the item is not a list, the check passes if LENGTH of the token is
> >> 0."
> >   `(and
> >      ,@(loop for token in tokens collect
> >        (if (listp token)
> >            (when (and (symbolp (first token))
> >                       (stringp (second token)))
> >              `(string= ,(first token) ,(second token)))
> >            (when (symbolp token)
> >              `(plusp (length ,token)))))))
>
> > An earlier version didn't check the types of the tokens (other than
> > the LISTP call, of course) but I wanted to make it more robust.  So I
> > want to be sure that each symbol is bound to a string as well.
> > Obviously this doesn't work:
>
> > (when (and (symbolp token) (stringp token))
> > .
> > .
> > .)
>
> > How can I get to the value of TOKEN in this case without EVAL?
>
> You cannot.
>
> Asking this is like asking How can I know what will be put in this box
> in one thousand years?

Thanks, Pascal, that blurry line between compile and run time is
causing me fits.  Everything I've done in Lisp so far has been more
clearly separated, but I'm forcing myself to look for opportunities to
apply macros.  I'll get it eventually.  ;-)
From: Kent M Pitman
Subject: Re: Accessing both symbol and contents within macro
Date: 
Message-ID: <uhcpf2kyh.fsf@nhplace.com>
jmckitrick <···········@yahoo.com> writes:

> Thanks, Pascal, that blurry line between compile and run time is
> causing me fits.  Everything I've done in Lisp so far has been more
> clearly separated, but I'm forcing myself to look for opportunities to
> apply macros.  I'll get it eventually.  ;-)

In MACLISP, which was the main dialect I used while learning to
program Lisp in a serious way, we used to have to start a separate
executable to compile a file.  That made it easy to remember.  It's
often nice that CL has in the same running image, but that's also
what's making it hard on you.  If you have trouble understanding, you
might try putting your programs in a file and then compiling them in
one Lisp and loading them in another.  (You don't have to exit the
Lisp you're using to execute your code in order to get new code, just
call load on the code you compiled from another lisp.)  Having this
actual separation should help you to understood which things happen
when. You'll make some mistakes, and if they happen in the lisp that
has the compiler, you'll know they are about the compiler environment
and will come to understand you don't have access to the runtime
there.  Likewise if they happen in the runtime, you'll see you have no
access to the compiler.