unofficial mirror of help-gnu-emacs@gnu.org
 help / color / mirror / Atom feed
* Replacement for Common Lisp's GENSYM in Emacs Lisp
@ 2010-03-06 15:19 Teemu Likonen
  2010-03-07  5:48 ` tomas
  0 siblings, 1 reply; 12+ messages in thread
From: Teemu Likonen @ 2010-03-06 15:19 UTC (permalink / raw)
  To: help-gnu-emacs

In Common Lisp GENSYM function generates unique symbol names. It seems
that Emacs Lisp does not have similar function (unless with CL
extension). In plain Emacs Lisp code and macros, what would you suggest
as a replacement for GENSYM? Just some very unlikely names?




^ permalink raw reply	[flat|nested] 12+ messages in thread

* Re: Replacement for Common Lisp's GENSYM in Emacs Lisp
       [not found] <mailman.2359.1267888813.14305.help-gnu-emacs@gnu.org>
@ 2010-03-06 16:10 ` David Kastrup
  2010-03-06 16:35   ` Teemu Likonen
  2010-03-07  7:07 ` Tim X
  1 sibling, 1 reply; 12+ messages in thread
From: David Kastrup @ 2010-03-06 16:10 UTC (permalink / raw)
  To: help-gnu-emacs

Teemu Likonen <tlikonen@iki.fi> writes:

> In Common Lisp GENSYM function generates unique symbol names. It seems
> that Emacs Lisp does not have similar function (unless with CL
> extension). In plain Emacs Lisp code and macros, what would you
> suggest as a replacement for GENSYM? Just some very unlikely names?

Uninterned symbols created with make-symbol work just fine for most
purposes.  Only rare applications need unique print names and/or symbols
accessed by name.

-- 
David Kastrup


^ permalink raw reply	[flat|nested] 12+ messages in thread

* Re: Replacement for Common Lisp's GENSYM in Emacs Lisp
  2010-03-06 16:10 ` Replacement for Common Lisp's GENSYM in Emacs Lisp David Kastrup
@ 2010-03-06 16:35   ` Teemu Likonen
  0 siblings, 0 replies; 12+ messages in thread
From: Teemu Likonen @ 2010-03-06 16:35 UTC (permalink / raw)
  To: help-gnu-emacs

* 2010-03-06 17:10 (+0100), David Kastrup wrote:

> Uninterned symbols created with make-symbol work just fine for most
> purposes. Only rare applications need unique print names and/or
> symbols accessed by name.

Yes, I agree. Thanks.


^ permalink raw reply	[flat|nested] 12+ messages in thread

* Re: Replacement for Common Lisp's GENSYM in Emacs Lisp
  2010-03-06 15:19 Teemu Likonen
@ 2010-03-07  5:48 ` tomas
  2010-03-07  6:13   ` Teemu Likonen
       [not found]   ` <mailman.2390.1267942438.14305.help-gnu-emacs@gnu.org>
  0 siblings, 2 replies; 12+ messages in thread
From: tomas @ 2010-03-07  5:48 UTC (permalink / raw)
  To: Teemu Likonen; +Cc: help-gnu-emacs

-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1

On Sat, Mar 06, 2010 at 05:19:43PM +0200, Teemu Likonen wrote:
> In Common Lisp GENSYM function generates unique symbol names. It seems
> that Emacs Lisp does not have similar function (unless with CL
> extension). In plain Emacs Lisp code and macros, what would you suggest
> as a replacement for GENSYM? Just some very unlikely names?

It seems `make-symbol' is what you are looking for. It generates an
uninterned symbol. Cf. Emacs Lisp manual "13.6.3 Local Variables in
Macro Expansions" to find an usage example.

Regards
- -- tomás
-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.4.6 (GNU/Linux)

iD8DBQFLkz4zBcgs9XrR2kYRAmYlAJ9u8h6o4RUYyjQrTM2BoHZViWsQ5ACaAsiu
WihLVHls9qY7oDOxCU4ysGM=
=3Ghx
-----END PGP SIGNATURE-----




^ permalink raw reply	[flat|nested] 12+ messages in thread

* Re: Replacement for Common Lisp's GENSYM in Emacs Lisp
  2010-03-07  5:48 ` tomas
@ 2010-03-07  6:13   ` Teemu Likonen
       [not found]   ` <mailman.2390.1267942438.14305.help-gnu-emacs@gnu.org>
  1 sibling, 0 replies; 12+ messages in thread
From: Teemu Likonen @ 2010-03-07  6:13 UTC (permalink / raw)
  To: tomas; +Cc: help-gnu-emacs

* 2010-03-07 06:48 (+0100), tomas@tuxteam.de wrote:

> On Sat, Mar 06, 2010 at 05:19:43PM +0200, Teemu Likonen wrote:
>> In Common Lisp GENSYM function generates unique symbol names. It
>> seems that Emacs Lisp does not have similar function (unless with CL
>> extension). In plain Emacs Lisp code and macros, what would you
>> suggest as a replacement for GENSYM? Just some very unlikely names?
>
> It seems `make-symbol' is what you are looking for. It generates an
> uninterned symbol. Cf. Emacs Lisp manual "13.6.3 Local Variables in
> Macro Expansions" to find an usage example.

That's right. My question was rather stupid, or at least asked too
hastily. It was in my mental patterns that I need GENSYM to create
symbols for macros. So I immediately thought I need to write a GENSYM
replacement for Emacs Lisp. But as you and David pointed out, the point
wasn't really unique print names but uninterned symbols. So make-symbol
is often sufficient. Thanks.




^ permalink raw reply	[flat|nested] 12+ messages in thread

* Re: Replacement for Common Lisp's GENSYM in Emacs Lisp
       [not found] <mailman.2359.1267888813.14305.help-gnu-emacs@gnu.org>
  2010-03-06 16:10 ` Replacement for Common Lisp's GENSYM in Emacs Lisp David Kastrup
@ 2010-03-07  7:07 ` Tim X
  2010-03-07 19:06   ` Stefan Monnier
  1 sibling, 1 reply; 12+ messages in thread
From: Tim X @ 2010-03-07  7:07 UTC (permalink / raw)
  To: help-gnu-emacs

Teemu Likonen <tlikonen@iki.fi> writes:

> In Common Lisp GENSYM function generates unique symbol names. It seems
> that Emacs Lisp does not have similar function (unless with CL
> extension). In plain Emacs Lisp code and macros, what would you suggest
> as a replacement for GENSYM? Just some very unlikely names?
>
>

This is actually a non-trivial problem. Best approach would probably be
to do something similar to how they generate universally unique IDs. 

I'd probably use some combination of letters/name and a random number.
Once generated, I'd look to see if the symbol by that name is already
interned and if it was, increment the number and try again. 

Other approaches I've seen use name/letters and the date as seconds
since epoch plus a cuple of random digits. 

The solution that is best really depends on what the criteria is for
correctness. A large lisp implementation that runs a flight control
centre in a busy airport probalby has a higher correctness criteria than
a bit of elisp that uses gensyms in a macro that handles address records
for a address book.

In reality, I'd just use (require 'cl)

Tim


-- 
tcross (at) rapttech dot com dot au


^ permalink raw reply	[flat|nested] 12+ messages in thread

* Re: Replacement for Common Lisp's GENSYM in Emacs Lisp
  2010-03-07  7:07 ` Tim X
@ 2010-03-07 19:06   ` Stefan Monnier
  2010-03-07 22:07     ` Helmut Eller
  0 siblings, 1 reply; 12+ messages in thread
From: Stefan Monnier @ 2010-03-07 19:06 UTC (permalink / raw)
  To: help-gnu-emacs

> This is actually a non-trivial problem.  Best approach would probably be
> to do something similar to how they generate universally unique IDs.

The best approach often is to not use "unique symbols" at all.  A common
technique is to rely on lexical scoping to precisely control which
variables are visible to each part of a macro's argument during its
evaluation.  E.g.:

  (defmacro dotimes (xl e)
    (let ((x (car xl))
          (l (cadr xl)))
      `(let ((body (lambda (,x) ,e))
             (list ,l))
         (while (consp list)
           (funcall body (car list))
           (setq list (cdr list))))))

Notice how the expressions `l' and `e' are evaluated in a context where
neither of `body', nor `list' exist.  No need for gensym.

Of course Elisp's lack of good support for lexical scoping makes such
a technique impractical.  But `make-symbol' can be used instead of
`gensym' and works very well for that purpose.


        Stefan


^ permalink raw reply	[flat|nested] 12+ messages in thread

* Re: Replacement for Common Lisp's GENSYM in Emacs Lisp
  2010-03-07 19:06   ` Stefan Monnier
@ 2010-03-07 22:07     ` Helmut Eller
  2010-03-08  4:55       ` Stefan Monnier
  0 siblings, 1 reply; 12+ messages in thread
From: Helmut Eller @ 2010-03-07 22:07 UTC (permalink / raw)
  To: help-gnu-emacs

* Stefan Monnier [2010-03-07 20:06+0100] writes:

>> This is actually a non-trivial problem.  Best approach would probably be
>> to do something similar to how they generate universally unique IDs.
>
> The best approach often is to not use "unique symbols" at all.  A common
> technique is to rely on lexical scoping to precisely control which
> variables are visible to each part of a macro's argument during its
> evaluation.  E.g.:
>
>   (defmacro dotimes (xl e)
>     (let ((x (car xl))
>           (l (cadr xl)))
>       `(let ((body (lambda (,x) ,e))
>              (list ,l))
>          (while (consp list)
>            (funcall body (car list))
>            (setq list (cdr list))))))
>
> Notice how the expressions `l' and `e' are evaluated in a context where
> neither of `body', nor `list' exist.  No need for gensym.

What makes you think that body and list aren't bound in e?

Helmut


^ permalink raw reply	[flat|nested] 12+ messages in thread

* Re: Replacement for Common Lisp's GENSYM in Emacs Lisp
  2010-03-07 22:07     ` Helmut Eller
@ 2010-03-08  4:55       ` Stefan Monnier
  2010-03-08  7:01         ` Helmut Eller
  0 siblings, 1 reply; 12+ messages in thread
From: Stefan Monnier @ 2010-03-08  4:55 UTC (permalink / raw)
  To: help-gnu-emacs

>>   (defmacro dotimes (xl e)
>>     (let ((x (car xl))
>>           (l (cadr xl)))
>>       `(let ((body (lambda (,x) ,e))
>>              (list ,l))
>>          (while (consp list)
>>            (funcall body (car list))
>>            (setq list (cdr list))))))
>> 
>> Notice how the expressions `l' and `e' are evaluated in a context where
>> neither of `body', nor `list' exist.  No need for gensym.

> What makes you think that body and list aren't bound in e?

Nothing, but luckily it doesn't make any difference whether they are
or not.


        Stefan


^ permalink raw reply	[flat|nested] 12+ messages in thread

* Re: Replacement for Common Lisp's GENSYM in Emacs Lisp
  2010-03-08  4:55       ` Stefan Monnier
@ 2010-03-08  7:01         ` Helmut Eller
  2010-03-09  2:33           ` Stefan Monnier
  0 siblings, 1 reply; 12+ messages in thread
From: Helmut Eller @ 2010-03-08  7:01 UTC (permalink / raw)
  To: help-gnu-emacs

* Stefan Monnier [2010-03-08 05:55+0100] writes:

>>>   (defmacro dotimes (xl e)
>>>     (let ((x (car xl))
>>>           (l (cadr xl)))
>>>       `(let ((body (lambda (,x) ,e))
>>>              (list ,l))
>>>          (while (consp list)
>>>            (funcall body (car list))
>>>            (setq list (cdr list))))))
>>> 
>>> Notice how the expressions `l' and `e' are evaluated in a context where
>>> neither of `body', nor `list' exist.  No need for gensym.
>
>> What makes you think that body and list aren't bound in e?
>
> Nothing, but luckily it doesn't make any difference whether they are
> or not.

Your "dotimes" macro produces:

(let ((list '(1)) (result ()))
  (dotimes (i '(1 2 3)) (push list result))
  result) => ((3) (2 3) (1 2 3))

While a version which doesn't shadow "list" produces this:

(let ((list '(1)) (result ()))
  (dolist (i '(1 2 3)) (push list result))
  result) => ((1) (1) (1))

Helmut


^ permalink raw reply	[flat|nested] 12+ messages in thread

* Re: Replacement for Common Lisp's GENSYM in Emacs Lisp
  2010-03-08  7:01         ` Helmut Eller
@ 2010-03-09  2:33           ` Stefan Monnier
  0 siblings, 0 replies; 12+ messages in thread
From: Stefan Monnier @ 2010-03-09  2:33 UTC (permalink / raw)
  To: help-gnu-emacs

>> Nothing, but luckily it doesn't make any difference whether they are
>> or not.

> Your "dotimes" macro produces:

> (let ((list '(1)) (result ()))
>   (dotimes (i '(1 2 3)) (push list result))
>   result) => ((3) (2 3) (1 2 3))

> While a version which doesn't shadow "list" produces this:

> (let ((list '(1)) (result ()))
>   (dolist (i '(1 2 3)) (push list result))
>   result) => ((1) (1) (1))

Because you're trying it out in Elisp (which uses dynamic scoping),
whereas this technique relies on lexical-scoping.


        Stefan


^ permalink raw reply	[flat|nested] 12+ messages in thread

* Re: Replacement for Common Lisp's GENSYM in Emacs Lisp
       [not found]   ` <mailman.2390.1267942438.14305.help-gnu-emacs@gnu.org>
@ 2010-03-11 22:48     ` Pascal J. Bourguignon
  0 siblings, 0 replies; 12+ messages in thread
From: Pascal J. Bourguignon @ 2010-03-11 22:48 UTC (permalink / raw)
  To: help-gnu-emacs

Teemu Likonen <tlikonen@iki.fi> writes:

> * 2010-03-07 06:48 (+0100), tomas@tuxteam.de wrote:
>
>> On Sat, Mar 06, 2010 at 05:19:43PM +0200, Teemu Likonen wrote:
>>> In Common Lisp GENSYM function generates unique symbol names. It
>>> seems that Emacs Lisp does not have similar function (unless with CL
>>> extension). In plain Emacs Lisp code and macros, what would you
>>> suggest as a replacement for GENSYM? Just some very unlikely names?
>>
>> It seems `make-symbol' is what you are looking for. It generates an
>> uninterned symbol. Cf. Emacs Lisp manual "13.6.3 Local Variables in
>> Macro Expansions" to find an usage example.
>
> That's right. My question was rather stupid, or at least asked too
> hastily. It was in my mental patterns that I need GENSYM to create
> symbols for macros. So I immediately thought I need to write a GENSYM
> replacement for Emacs Lisp. But as you and David pointed out, the point
> wasn't really unique print names but uninterned symbols. So make-symbol
> is often sufficient. Thanks.

Of course, (even in Common Lisp) macros could always use make-symbol.
If we use (gensym), or even better, (gensym "varname"), it's to be able
to read the expansion of macros.  It's a debugging device.

But we could also (setq print-circle t) and use (make-symbol "varname");
the #=/## notation will allow us to distinguish the different symbols
generated.


-- 
__Pascal Bourguignon__


^ permalink raw reply	[flat|nested] 12+ messages in thread

end of thread, other threads:[~2010-03-11 22:48 UTC | newest]

Thread overview: 12+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
     [not found] <mailman.2359.1267888813.14305.help-gnu-emacs@gnu.org>
2010-03-06 16:10 ` Replacement for Common Lisp's GENSYM in Emacs Lisp David Kastrup
2010-03-06 16:35   ` Teemu Likonen
2010-03-07  7:07 ` Tim X
2010-03-07 19:06   ` Stefan Monnier
2010-03-07 22:07     ` Helmut Eller
2010-03-08  4:55       ` Stefan Monnier
2010-03-08  7:01         ` Helmut Eller
2010-03-09  2:33           ` Stefan Monnier
2010-03-06 15:19 Teemu Likonen
2010-03-07  5:48 ` tomas
2010-03-07  6:13   ` Teemu Likonen
     [not found]   ` <mailman.2390.1267942438.14305.help-gnu-emacs@gnu.org>
2010-03-11 22:48     ` Pascal J. Bourguignon

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).