From: Brian D. Stark
Subject: creating LISP structures dynamically?
Date: 
Message-ID: <1992Jun26.162734.13036@newshub.sdsu.edu>
Hi,

I'm developing a high level robotic control system using LISP with an Austin 
Kyote Common Lisp (AKCL) interpreter.  The system is divided into a planner 
and a scheduler.  The planner is supposed to generate a list of moves to be 
scheduled.  I would like to represent a single move as a LISP structure, but 
the number of moves generated is dynamic to the task.  I would like to be 
able to create the structures dynamically, for example a typical plan would 
consist of:

move1, move2, move3, ... , moven.  

My problem is I don't know how to create a LISP symbol dynamically.  Is there 
any function comparable to PRIN1-TO-STRING that will return a legal symbol.  
The code I have in mind might look like this where "var" is set to the move 
number 1 - n :

(setf (prin1-to-symbol 
         (append
            (list 'move) (list var)
         )
      )
      (make-move)
)

This is just an idea, and I'm open to suggestions if anyone can think of
a better way it wouldn't suprise me one bit, I have a feeling I'm making 
this much harder then it is.

Thanks,

brian

From: Barry Margolin
Subject: Re: creating LISP structures dynamically?
Date: 
Message-ID: <12ft7kINNbb3@early-bird.think.com>
In article <······················@newshub.sdsu.edu> ·····@saturn.sdsu.edu (Brian D. Stark) writes:
>I'm developing a high level robotic control system using LISP with an Austin 
>Kyote Common Lisp (AKCL) interpreter.  The system is divided into a planner 
>and a scheduler.  The planner is supposed to generate a list of moves to be 
>scheduled.  I would like to represent a single move as a LISP structure, but 
>the number of moves generated is dynamic to the task.  I would like to be 
>able to create the structures dynamically, for example a typical plan would 
>consist of:
>
>move1, move2, move3, ... , moven.  
>
>My problem is I don't know how to create a LISP symbol dynamically. 

MAKE-SYMBOL or INTERN, depending on whether you want the symbol to be
interned in a package or not.

I'm curious about why questions like this end up on the net.  There's a
section of CLtL entitled "Creating Symbols", and it's referenced in the
index under "Symbols, creating".  How much more obvious does the reference
manual have to be?

>								      Is there 
>any function comparable to PRIN1-TO-STRING that will return a legal symbol.  
>The code I have in mind might look like this where "var" is set to the move 
>number 1 - n :
>
>(setf (prin1-to-symbol 
>         (append
>            (list 'move) (list var)
>         )
>      )
>      (make-move)
>)

(defun make-move-name (n)
  (intern (format nil "MOVE~D" n) *planner-package*))

(setf (symbol-value (make-move-name var)) (make-move))

However, going back to your original problem description, I'm not sure what
the purpose of these symbols is.  If the number of moves is dynamic, why
not just return a list of them (this is, after all, the LISt Processing
language)?  Your Subject line says that you want to create Lisp structures
dynamically, and that's what MAKE-MOVE (which I assume is a constructor
defined by DEFSTRUCT) does; but you somehow have gotten the notion that in
order to create structures dynamically you also need to create symbols
dynamically, but there's no such connection.
-- 
Barry Margolin
System Manager, Thinking Machines Corp.

······@think.com          {uunet,harvard}!think!barmar
From: Jeff Dalton
Subject: Re: creating LISP structures dynamically?
Date: 
Message-ID: <7011@skye.ed.ac.uk>
In article <············@early-bird.think.com> ······@think.com (Barry Margolin) writes:

[Someone wants to create structures synamically in a planner/
scheduler, but their specific question is about how to create
_symbols_ dynamically.]

>MAKE-SYMBOL or INTERN, depending on whether you want the symbol to be
>interned in a package or not.

Or even GENTEMP or (sometimes) GENSYM.

>However, going back to your original problem description, I'm not sure what
>the purpose of these symbols is.  [...]

>  Your Subject line says that you want to create Lisp structures
>dynamically, and that's what MAKE-MOVE (which I assume is a constructor
>defined by DEFSTRUCT) does; but you somehow have gotten the notion that in
>order to create structures dynamically you also need to create symbols
>dynamically, but there's no such connection.

This puzzles me too.  I've seen it again and again in AI programs
such as planners and schedulers, and from time to time I've asked
the authors why they do it.  

Sometimes they think it's necessary to have an extra level of
indirection, but whenever I've pressed them on it (so far), it's
turned out that they aren't actually using the extra indirection
in any interesting way.

Other people have thought that unless they attached each structure 
to a symbol they would be getting _copies_ of the structures whenever
they passed them as arguments in function calls.  (They plan to pass
the symbols instead.)  That is, they are in the grip of a
misunderstanding about how Lisp works.

But I don't think that's the whole story.  Apart from various
confucions, there seem to a a couple of other factors at work:

  1. At one time, a common technique was to represent structures
     as symbols with the plists holding the slots.  Because of
     that, or for some other reason, the use of named objects
     became conventional in certain areas of AI, and new programmers
     learned this convention when they learned how to write AI
     programs.

  2. Some people find it more natural to have named objects.
     (Certainly some people find systems such as KEE that use
     named objects more natural that, say, CLOS.)

In any case, I have never succeeded (so far) in getting anyone to stop
using sybols or some other ids for structures.  The things that keep
them from making the change seem to be:

  1. They want to be able to type in an id and get back the struct.

  2. They want complex and circular structures to print nicely.
     For instance, if one struct contains (pointers to) others,
     they want the others to print as simple ids rather than as
     some complex contents in #s(...) notation.

My solution to these problems is to define :PRINT-FUNCTIONs that
produce ids (as needed) that can be typed-in to get back the same
struct.

However, because Common Lisp does not provide a way for a program to
find all the slots of a struct (unless maybe the CLOS MOP now does
it), defining a :PRINT-FUNCTION makes it difficult to get the #s(...)
version in the cases where you still need it.

-- jd
From: David F. Skoll
Subject: Why name your objects? (was Re: creating LISP ...)
Date: 
Message-ID: <dfs.712009536@ro>
In <····@skye.ed.ac.uk> ····@aiai.ed.ac.uk (Jeff Dalton) writes:

>This puzzles me too.  I've seen it again and again in AI programs
>such as planners and schedulers, and from time to time I've asked
>the authors why they do it. [create symbols for each instance of
> a data structure - dfs]

>Sometimes they think it's necessary to have an extra level of
>indirection, but whenever I've pressed them on it (so far), it's
>turned out that they aren't actually using the extra indirection
>in any interesting way.

I'm working on a large system where that was done, and it does seem a
waste.  However, I've found one good reason for doing it that way -
when objects contain pointers to other objects, it's a bit of a hassle
to write the database to disk in a nice readable way.  If the pointers
simply name the objects, it's very easy to write the database to disk.
Also, it's easy to re-create the database when reading it back from
disk.

--
David F. Skoll
From: David V. Henkel-Wallace
Subject: Why name your objects? (was Re: creating LISP ...)
Date: 
Message-ID: <GUMBY.92Jul27051811@Cygnus.COM>
   Date: Fri, 24 Jul 1992 20:25:36 GMT
   From: ···@doe.carleton.ca (David F. Skoll)

   I'm working on a large system where that was done, and it does seem a
   waste.  However, I've found one good reason for doing it that way -
   when objects contain pointers to other objects, it's a bit of a hassle
   to write the database to disk in a nice readable way.  If the pointers
   simply name the objects, it's very easy to write the database to disk.
   Also, it's easy to re-create the database when reading it back from
   disk.

unless you have a very small database, or need to be able to read it
into many lisps, you probably won't want the time it takes to go
through the reader and the printer.  Instead you want to make a
compiled file.
From: David F. Skoll
Subject: Re: Why name your objects? (was Re: creating LISP ...)
Date: 
Message-ID: <dfs.712254169@ro>
In <···················@Cygnus.COM> ·····@Cygnus.COM (David V.
Henkel-Wallace) writes:

[I wrote that naming objects makes it easy to read/write databases to disk.]

>unless you have a very small database, or need to be able to read it
>into many lisps, you probably won't want the time it takes to go
>through the reader and the printer.  Instead you want to make a
>compiled file.

Right.  But we wanted the database to be human-readable and
human-editable with a text editor.  Also, we wanted to be able to
translate to and from several other (non-Lisp) formats to our database
format, and found that C/awk/sed tools were better than Lisp for doing
the translation.  That virtually mandated an ASCII database.

--
David F. Skoll