From: Lyle Graham
Subject: Constructing forms with quoted atoms
Date: 
Message-ID: <3E4B71C7.3070903@biomedicale.univ-paris5.fr>
I would like to construct a form (to be written to a Lisp source file 
and loaded later), that references a variable BAR which in turn may be a 
symbol, a string or a number. In all cases, the value of BAR is the name 
of some object. To account for the case where the variable evaluates to 
a symbol, I need to include a quote to prevent evaluation when the form 
is read at a later time, thus:

   (let ((bar 'baz)) `(foo ',bar)) => (FOO 'BAZ)


Of course, when BAR evaulates to a string or number, the quote is 
retained in the result:

   (let ((bar "baz")) `(foo ',bar)) => (FOO '"baz")


   (let ((bar 123)) `(foo ',bar)) => (FOO '123)


Since

   (equal '"baz" "baz") => t
   (equal '123 123) => t

this result is *correct*, but I suspect that there should be a simple 
way to avoid quoted strings and numbers in such a construction.

Any suggestions (or comments on why the above is not good Lisp "style") 
will be appreciated.

Best,

Lyle

From: Kaz Kylheku
Subject: Re: Constructing forms with quoted atoms
Date: 
Message-ID: <cf333042.0302131052.345085d0@posting.google.com>
Lyle Graham <····@biomedicale.univ-paris5.fr> wrote in message news:<················@biomedicale.univ-paris5.fr>...
> I would like to construct a form (to be written to a Lisp source file 
> and loaded later), that references a variable BAR which in turn may be a 
> symbol, a string or a number. In all cases, the value of BAR is the name 
> of some object.

To clarify, the form you are writing to the file does not actually
refer to a BAR variable. Rather, the backquoted template which is used
to construct that from refers to a BAR variable. The substitution of
BAR's value occurs when you construct the form before you write it to
the file.

> To account for the case where the variable evaluates to 
> a symbol, I need to include a quote to prevent evaluation when the form 
> is read at a later time, thus:

No, reading and evaluation are different things. Reading does not lead
to evaluation (except for read-time evaluation requested by the #.
notation). But you will run into that problem when you later evaluate
the form you have read.

>    (let ((bar 'baz)) `(foo ',bar)) => (FOO 'BAZ)

Try (read-from-string "(FOO BAZ)") for instance: no attempt is made to
evaluate BAZ or to call the function FOO. But of course if you EVAL
the object that has been read, then yes.

> Of course, when BAR evaulates to a string or number, the quote is 
> retained in the result:
> 
>    (let ((bar "baz")) `(foo ',bar)) => (FOO '"baz")

It's okay to quote things which already evaluate to themselves. It's a
general way to suppress evaluation of anything and make it stand for
itself.

>    (let ((bar 123)) `(foo ',bar)) => (FOO '123)
> 
> 
> Since
> 
>    (equal '"baz" "baz") => t
>    (equal '123 123) => t
> 
> this result is *correct*, but I suspect that there should be a simple 
> way to avoid quoted strings and numbers in such a construction.

One quick and dirty hack would be: insert the quote only if the object
satisfies CONSP or SYMBOLP.

   (let ((bar 123)) 
     `(foo ,(if (or (consp bar) (symbolp bar))
              `(quote ,bar) 
              bar)))

Are there any other things whose evaluation you have to worry about
beside symbols and lists?

> Any suggestions (or comments on why the above is not good Lisp "style") 
> will be appreciated.

It's fine. It depends on whether, in the given situation, you care
more about programming convenience or storing the data in a pristine
format.
From: Lyle Graham
Subject: Re: Constructing forms with quoted atoms
Date: 
Message-ID: <3E4CF35E.4030609@biomedicale.univ-paris5.fr>
Thanks very much to all for the suggestions. I had previously used a 
similar explicit check for SYMBOLP while adding the quote or not to a 
FORMAT statement.

Kaz Kylheku wrote:

> 
> One quick and dirty hack would be: insert the quote only if the object
> satisfies CONSP or SYMBOLP.
> 
>    (let ((bar 123)) 
>      `(foo ,(if (or (consp bar) (symbolp bar))
>               `(quote ,bar) 
>               bar)))

I suppose the following macro is generally useful:

(defmacro quote-only-symbol (val)
   `(if (and (symbolp ,val) (not (keywordp ,val))) `',,val ,val))

Thus

(let ((bar 123))
  `(foo ,(quote-only-symbol bar)))

>>Any suggestions (or comments on why the above is not good Lisp "style") 
>>will be appreciated.
> 
> 
> It's fine. It depends on whether, in the given situation, you care
> more about programming convenience or storing the data in a pristine
> format.

Yes, in fact my concern was for a "pristine" data format, specifically 
to avoid non-Lisp-savvy users from scratching their heads over '"foo" 
and '123.

Lyle
From: Kaz Kylheku
Subject: Re: Constructing forms with quoted atoms
Date: 
Message-ID: <cf333042.0302141446.dea23c2@posting.google.com>
Lyle Graham <····@biomedicale.univ-paris5.fr> wrote in message news:<················@biomedicale.univ-paris5.fr>...
> Thanks very much to all for the suggestions. I had previously used a 
> similar explicit check for SYMBOLP while adding the quote or not to a 
> FORMAT statement.
> 
> Kaz Kylheku wrote:
> 
> > 
> > One quick and dirty hack would be: insert the quote only if the object
> > satisfies CONSP or SYMBOLP.
> > 
> >    (let ((bar 123)) 
> >      `(foo ,(if (or (consp bar) (symbolp bar))
> >               `(quote ,bar) 
> >               bar)))
> 
> I suppose the following macro is generally useful:
> 
> (defmacro quote-only-symbol (val)
>    `(if (and (symbolp ,val) (not (keywordp ,val))) `',,val ,val))

Yes, but there is no reason why it has to be a macro, and if it had to
be one, I'd avoid the multiple evaluations of ,val by using a gensym.
;)

Also `',,val raises a bit of a red flag with me. You have more
backquoting and unquoting than necessary, all you need is:

   (if ...  ',val ,val)

Here is the function version:

  ;; all the macro taste, but less filling
  (declaim (inline quote-only-symbol))

  (defun quote-only-symbol (val)
    (if (and (symbolp val)
             (not (keywordp val)))
      `(quote ,val) 
      val))

Lastly, you really do have to quote conses too, so it should be
quote-only-non-keyword-symbol-or-cons.

> Yes, in fact my concern was for a "pristine" data format, specifically 
> to avoid non-Lisp-savvy users from scratching their heads over '"foo" 
> and '123.

They will still scratch them over 'foo and '(+ a b). ;)
From: John Gilson
Subject: Re: Constructing forms with quoted atoms
Date: 
Message-ID: <PNM2a.19943$Mh3.5267995@twister.nyc.rr.com>
"Lyle Graham" <····@biomedicale.univ-paris5.fr> wrote in message
·····················@biomedicale.univ-paris5.fr...
> I would like to construct a form (to be written to a Lisp source file
> and loaded later), that references a variable BAR which in turn may be a
> symbol, a string or a number. In all cases, the value of BAR is the name
> of some object. To account for the case where the variable evaluates to
> a symbol, I need to include a quote to prevent evaluation when the form
> is read at a later time, thus:
>
>    (let ((bar 'baz)) `(foo ',bar)) => (FOO 'BAZ)
>
>
> Of course, when BAR evaulates to a string or number, the quote is
> retained in the result:
>
>    (let ((bar "baz")) `(foo ',bar)) => (FOO '"baz")
>
>
>    (let ((bar 123)) `(foo ',bar)) => (FOO '123)
>
>
> Since
>
>    (equal '"baz" "baz") => t
>    (equal '123 123) => t
>
> this result is *correct*, but I suspect that there should be a simple
> way to avoid quoted strings and numbers in such a construction.
>
> Any suggestions (or comments on why the above is not good Lisp "style")
> will be appreciated.
>
> Best,
>
> Lyle

(let ((bar 'baz))
   `(foo ,(if (and (symbolp bar) (not (keywordp bar)))
                  `',bar
                  bar)))
=>
(FOO 'BAZ)

(let ((bar 123))
   `(foo ,(if (and (symbolp bar) (not (keywordp bar)))
                  `',bar
                  bar)))
=>
(FOO 123)

Regards,
jag
From: Tim Bradshaw
Subject: Re: Constructing forms with quoted atoms
Date: 
Message-ID: <ey3r8ac70c8.fsf@cley.com>
* Lyle Graham wrote:

> this result is *correct*, but I suspect that there should be a simple
> way to avoid quoted strings and numbers in such a construction.

I think it's safe to say that only symbols and conses need to be
quoted (at least in any ANSI CL - CLtL1 CL was vaguer), so you can do
this by checking the type.  However I don't think there's any need to
bother.

--tim