From: Robert Goldman
Subject: lisp question - assigning variable names dynamically
Date: 
Message-ID: <35EC8835.4E883780@mail.com>
HI

I'm trying to do something that is simple in C++ but I just can't seem
to get it to work in Lisp.  Any help would be greatly appreciated.

I would like to create N variables at run time that "point" to lists (or
anything else for that matter). In other words, I don't have a "name"
for these variables YET (in code).
As:

(dotimes (i N)

mylist-1
.
.
mylist-N


I've read all about symbols, variables, macros and tried everything I
could thing of. I even tried the following which didn't work:

? (setf (gentemp) '(0 1 1 1)))

and

? (setf (gensym) '(0 1 1 1)))

and many other potential solutions. What am I missing here? It
seems like one should be able to create variable names on the fly
and assign them values.

Thanks, Robert

From: David J Cooper Jr
Subject: Re: lisp question - assigning variable names dynamically
Date: 
Message-ID: <35EC9EB9.67C8205D@genworks.com>
Robert Goldman wrote:

> HI
>
> I'm trying to do something that is simple in C++ but I just can't seem
> to get it to work in Lisp.  Any help would be greatly appreciated.
>
> I would like to create N variables at run time that "point" to lists (or
> anything else for that matter). In other words, I don't have a "name"
> for these variables YET (in code).
> As:
>
> (dotimes (i N)
>
> mylist-1
> .
> .
> mylist-N
>
> I've read all about symbols, variables, macros and tried everything I
> could thing of. I even tried the following which didn't work:
>
> ? (setf (gentemp) '(0 1 1 1)))
>
> and
>
> ? (setf (gensym) '(0 1 1 1)))
>
> and many other potential solutions. What am I missing here? It
> seems like one should be able to create variable names on the fly
> and assign them values.
>
> Thanks, Robert

How about something like this, for assigning global variables anyway. Local
(i.e. let) variables would have to be done differenty I believe.

You can create a symbol with something like (read-from-string), then set
its value with (setf (symbol-value <symbol>)):

> (dotimes (n 10)
                (setf (symbol-value
                       (read-from-string
                        (format nil "list-~a" n)))
                  (list n)))

> list-1
(1)

> list-6
(6)


However,  I would be curious as to what you are trying to do actually, and
whether this would be the best way. You might look into using something
like a ``plist,'' in which you can dynamically build up a list of
alternating keys and values -- the keys could act as the variables you're
trying to create here:


-----

David J Cooper Jr                                       Genworks International
········@genworks.com                                   http://www.genworks.com

 ...Embracing an Open Systems Approach to Knowledge-based Engineering...
From: David Hanley
Subject: Re: lisp question - assigning variable names dynamically
Date: 
Message-ID: <35EF72C9.A8850EF1@nconnect.net>
David J Cooper Jr wrote:

> Robert Goldman wrote:
>
> > HI
> >
> > I'm trying to do something that is simple in C++ but I just can't seem
> > to get it to work in Lisp.  Any help would be greatly appreciated.

    Why not show us the simple C++ code?  Then someone here
will surely translate it.

dave
From: Tim Bradshaw
Subject: Re: lisp question - assigning variable names dynamically
Date: 
Message-ID: <ey34suqu7t9.fsf@todday.aiai.ed.ac.uk>
* Robert Goldman wrote:
> HI
> I'm trying to do something that is simple in C++ but I just can't seem
> to get it to work in Lisp.  Any help would be greatly appreciated.

Is this really easy in C++?  I'd be a bit surprised if it was, because
I think variable names are fixed at compile time in C++.  I might be
wrong though.

You could do something awful with (SETF SYMBOL-VALUE), but I suspect
you are actually trying to do something rather different than that.
For instance, if you don't know the names of these things, how will
you later refer to them --

	(setf (symbol-value (gensym)) ...)

is not going to help you much since you don't know what symbol GENSYM
made...

I think more detail on what you are trying to do is needed.

--tim
From: Christopher J. Vogt
Subject: Re: lisp question - assigning variable names dynamically
Date: 
Message-ID: <35ED48BB.7EA64345@computer.org>
Robert Goldman wrote:
> I would like to create N variables at run time that "point" to lists (or
> anything else for that matter). In other words, I don't have a "name"
> for these variables YET (in code).
> As:
> 
> (dotimes (i N)
> 
> mylist-1
> .
> .
> mylist-N
> 
> I've read all about symbols, variables, macros and tried everything I
> could thing of. I even tried the following which didn't work:
> 
> ? (setf (gentemp) '(0 1 1 1)))
> 
> and
> 
> ? (setf (gensym) '(0 1 1 1)))
> 
> and many other potential solutions. What am I missing here? It
> seems like one should be able to create variable names on the fly
> and assign them values.

Well, I'm not clear on what doesn't work in using gentemp, so here is a little
piece of code that may be of help.

(defun generate-dynamic-variables (how-many)
  ;;
  ;; Generate a list of symbols, and store that list in variables
  ;;
  (let ((variables (loop repeat how-many
                         collect (gentemp))))
    ;;
    ;; For each generated symbol, set its value to something unique,
    ;; in this case case, set it to an integer starting at 0
    ;;
    (loop for variable in variables
          for i from 0 do
          (set variable i))
    ;;
    ;; For each generated symbol, print the symbols name and value
    ;; so we know it worked
    ;;
    (loop for variable in variables           ; for each generated symbol
          for i from 0 do          
          (format t "~%~a ~a" variable (eval variable)))
    ;;
    ;; return the generated list of symbols for use elsewhere
    ;;
    variables))
-- 
Christopher J. Vogt - Computer Consultant - Solving hard problems since 1979
http://members.home.com/vogt/
From: Tim Bradshaw
Subject: Re: lisp question - assigning variable names dynamically
Date: 
Message-ID: <ey3zpcisdn0.fsf@todday.aiai.ed.ac.uk>
* Christopher J Vogt wrote:

> Well, I'm not clear on what doesn't work in using gentemp, so here
> is a little piece of code that may be of help.

[...]

Why is something like this ever a good thing to do?  This is a serious
question!  I've seen code kind of like this in various AI programs,
and I've always been deeply mystified by it, so perhaps I'm being
stupid.

There are a couple of cases that I can understand:

	1. you need something that will hold n items of data and let
	   you get at them.  Arrays do that.

	2. you need something that will map between n names and n data
	   items.  Hash tables do that (or alists, or various other
	   structures with differing sets of properties).

But storing something in n globals with gensymed seems to me deeply
mysterious!  When I'm done, what do I know?  I don't really know which
variable holds which thing (except, because I got the list of variable
names back, I do actually, but this is just arrays done slowly).  I'm
mystified by this.

Please note I do understand using gensymed variables in things like
macro expansions, but this doesn't seem to be that case, and other
cases I've seen like it seemed even less like that.

--tim
From: Sunil Mishra
Subject: Re: lisp question - assigning variable names dynamically
Date: 
Message-ID: <efyzpcixrhs.fsf@cuba.cc.gatech.edu>
Tim Bradshaw <···@aiai.ed.ac.uk> writes:

> Why is something like this ever a good thing to do?  This is a serious
> question!  I've seen code kind of like this in various AI programs,
> and I've always been deeply mystified by it, so perhaps I'm being
> stupid.
> 
> There are a couple of cases that I can understand:
> 
> 	1. you need something that will hold n items of data and let
> 	   you get at them.  Arrays do that.
> 
> 	2. you need something that will map between n names and n data
> 	   items.  Hash tables do that (or alists, or various other
> 	   structures with differing sets of properties).
> 
> But storing something in n globals with gensymed seems to me deeply
> mysterious!  When I'm done, what do I know?  I don't really know which
> variable holds which thing (except, because I got the list of variable
> names back, I do actually, but this is just arrays done slowly).  I'm
> mystified by this.
> 
> Please note I do understand using gensymed variables in things like
> macro expansions, but this doesn't seem to be that case, and other
> cases I've seen like it seemed even less like that.
> 
> --tim

The last time I was considering the symbol value approach, I wanted to keep
track of the appearance of about three or four symbols out of a large list,
efficiently. In other words, no additional consing and fast access. So,
arrays and hash tables would be somewhat wasteful (unnecessary consing),
and there would be no need to track any variables because the symbols would
all be available in the original input list anyway. I gave up on that
approach though, mainly because I didn't want to introduce global bindings
and didn't know about progv.

I haven't seen this in any programs though, probably because I haven't of
late seen very much code written by anyone besides me :-) Not much of an
explanation, I'm afraid.

Sunil
From: Tim Bradshaw
Subject: Re: lisp question - assigning variable names dynamically
Date: 
Message-ID: <ey3ww7lsh6l.fsf@todday.aiai.ed.ac.uk>
* Sunil Mishra wrote:
> The last time I was considering the symbol value approach, I wanted to keep
> track of the appearance of about three or four symbols out of a large list,
> efficiently. In other words, no additional consing and fast access. So,
> arrays and hash tables would be somewhat wasteful (unnecessary consing),
> and there would be no need to track any variables because the symbols would
> all be available in the original input list anyway. I gave up on that
> approach though, mainly because I didn't want to introduce global bindings
> and didn't know about progv.

OK. I've done that in old lisps where I wanted a hashtable really but
used an obarray (as Barry Margolin pointed out in another followup) --
I think I was failing to spot that the person was asking this, if they
were (I'm still not really clear).

One thing that people often miss though is that using symbols to stash
values is often a rather expensive way to do this.  If you keep them
in an array you probably cons one word per thing you want to keep
track of + array header.  But if you keep things in symbols you cons
one symbol per thing, which is almost certainly much more than a word
(perhaps something like 4 + size of namestring + a slot in the
package, assuming it is interned).  Symbols are really big things.
It's almost certainly cheaper to have a hashtable whose keys are
strings.

(Of course one could imagine clever implementations which made symbols
very lightweight and then lazily allocated value/function/plist
slots.)

--tim
From: Sunil Mishra
Subject: Re: lisp question - assigning variable names dynamically
Date: 
Message-ID: <efyvhn364i2.fsf@shooter.cc.gatech.edu>
Tim Bradshaw <···@aiai.ed.ac.uk> writes:

> One thing that people often miss though is that using symbols to stash
> values is often a rather expensive way to do this.  If you keep them
> in an array you probably cons one word per thing you want to keep
> track of + array header.  But if you keep things in symbols you cons
> one symbol per thing, which is almost certainly much more than a word
> (perhaps something like 4 + size of namestring + a slot in the
> package, assuming it is interned).  Symbols are really big things.
> It's almost certainly cheaper to have a hashtable whose keys are
> strings.

Yes, I realize that. But in my situation the symbols were already
there. All I had to do was keep track of some values associated with
them. The simplest analog would be a large list of symbols with many
duplicates, where you wanted to count the frequency of each symbol, or of
some pre-specified symbols.

If these objects were not symbols or did not already have unique symbols
associated with them, then I would certainly not create symbols to count
them. Along with the efficiency issue you have already brought up, symbols
don't go away in garbage collection. A plist or a hash table would
definitely be the way to go.

Sunil
From: Barry Margolin
Subject: Re: lisp question - assigning variable names dynamically
Date: 
Message-ID: <cVjH1.23$BT1.375669@burlma1-snr1.gtei.net>
In article <···············@todday.aiai.ed.ac.uk>,
Tim Bradshaw  <···@aiai.ed.ac.uk> wrote:
>Why is something like this ever a good thing to do?  This is a serious
>question!  I've seen code kind of like this in various AI programs,
>and I've always been deeply mystified by it, so perhaps I'm being
>stupid.

It's a holdover from the early days of Lisp, when we didn't have things
like hash tables built into the language.  PDP-10 Maclisp didn't even have
strings until the late 70's (and the strings it had were kind of weird,
IIRC).  So the traditional way of mapping names to data was by using
symbols and SET (alists were not efficient for large tables).

Actually, there was a hash table mechanism in the language: obarrays (the
precursor to packages).  Applications that wanted to map names to objects
without colliding with variables would bind OBARRAY and call INTERN to get
the symbol.

-- 
Barry Margolin, ······@bbnplanet.com
GTE Internetworking, Powered by BBN, Burlington, MA
*** DON'T SEND TECHNICAL QUESTIONS DIRECTLY TO ME, post them to newsgroups.
From: Sunil Mishra
Subject: Re: lisp question - assigning variable names dynamically
Date: 
Message-ID: <efyww7m5vuv.fsf@shooter.cc.gatech.edu>
"Christopher J. Vogt" <····@computer.org> writes:

> Well, I'm not clear on what doesn't work in using gentemp, so here is a little
> piece of code that may be of help.
> 
> (defun generate-dynamic-variables (how-many)
>   ;;
>   ;; Generate a list of symbols, and store that list in variables
>   ;;
>   (let ((variables (loop repeat how-many
>                          collect (gentemp))))
>     ;;
>     ;; For each generated symbol, set its value to something unique,
>     ;; in this case case, set it to an integer starting at 0
>     ;;
>     (loop for variable in variables
>           for i from 0 do
>           (set variable i))
>     ;;
>     ;; For each generated symbol, print the symbols name and value
>     ;; so we know it worked
>     ;;
>     (loop for variable in variables           ; for each generated symbol
>           for i from 0 do          
>           (format t "~%~a ~a" variable (eval variable)))
                                          ^^^^
                        Perhaps symbol-value would suffice here?
>     ;;
>     ;; return the generated list of symbols for use elsewhere
>     ;;
>     variables))
> -- 
> Christopher J. Vogt - Computer Consultant - Solving hard problems since 1979
> http://members.home.com/vogt/

In general, I am a little wary of permanently modifying the value of a
variable, which is what all the symbol-value solutions would do. Wouldn't
progv be more appropriate for this situation? Something like the function
below or a macro-ised version:

(defun with-n-dynamic-variables (n fn)
  (multiple-value-bind (variables init-values)
      (loop for i from 0 below n
	    collect (gentemp) into variables
	    collect i into init-values	; Or however you wish to generate them
	    finally (return (values variables init-values)))
    (progv variables init-values
      (funcall fn variables))))

I would also like to repeat something that a previous post stated. I don't
think we have enough information on what the problem is. I don't think
there is anything in C++ that can be done at *runtime* that would not be at
least as easy in Lisp. So, if we can get more information on what the
problem is, I'm sure we will be able to give a better response.

Sunil
From: Steven D. Majewski
Subject: Re: lisp question - assigning variable names dynamically
Date: 
Message-ID: <6sjoco$gg7$1@murdoch.acc.Virginia.EDU>
In article <·················@mail.com>,
Robert Goldman  <········@mail.com> wrote:
>HI
>
>I'm trying to do something that is simple in C++ but I just can't seem
>to get it to work in Lisp.  Any help would be greatly appreciated.
>

Like some other posters, I know C++ doesn't do dynamic binding, so 
the problem *as stated* can't be simple in C++ , and I wonder what
you're trying to do here, because there's probably an easier way to
do it in Lisp. 

But, to answer the question ... 

>
>I've read all about symbols, variables, macros and tried everything I
>could thing of. I even tried the following which didn't work:
>
>? (setf (gentemp) '(0 1 1 1)))
>
>and
>
>? (setf (gensym) '(0 1 1 1)))
>
>and many other potential solutions. What am I missing here? It
>seems like one should be able to create variable names on the fly
>and assign them values.
>

Try either:

 ( set ( gentemp "MYLIST-" ) value )

or:

 ( setf ( symbol-value ( gentemp "MYLIST-" )) value )



---|  Steven D. Majewski   (804-982-0831)  <·····@Virginia.EDU>  |---
---|  Department of Molecular Physiology and Biological Physics  |---
---|  University of Virginia             Health Sciences Center  |---
---|  P.O. Box 10011            Charlottesville, VA  22906-0011  |---

"I'm not as big a fool as I used to be, I'm a smaller fool." - Jack Kerouac
Some of the Dharma  <http://members.aol.com/kerouacsis/SomeDharma.html>