From: ·········@olive-it.ch
Subject: constructing and defining variable at runtime
Date: 
Message-ID: <6d36353d-8059-44e7-beae-243d26ae25d4@i29g2000prf.googlegroups.com>
Somehow i miss a backquote or what
How can i define at runtime variables
(DEFPARAMETER LECTURE-SITE::TEST "/home/olivier/lisp/yawn/lecture-
site/")
at runtime, i.e.
(defparameter <name> <value>)
where <name> and <value> are known at run-time. Tried all my macros -
somehow it wont work.
I get the list (defparameter LECTURE-SITE::TEST "/home/olivier/lisp/
yawn/lecture-site/") which I wont evaluate as am looking for something
without evil eval which, i'm sure, should be possible.

Sorry to bother you, but am blocked.
thanx

From: John Thingstad
Subject: Re: constructing and defining variable at runtime
Date: 
Message-ID: <op.t4slpoq3ut4oq5@pandora.alfanett.no>
P� Sat, 12 Jan 2008 00:16:34 +0100, skrev <·········@olive-it.ch>:

> Somehow i miss a backquote or what
> How can i define at runtime variables
> (DEFPARAMETER LECTURE-SITE::TEST "/home/olivier/lisp/yawn/lecture-
> site/")
> at runtime, i.e.
> (defparameter <name> <value>)
> where <name> and <value> are known at run-time. Tried all my macros -
> somehow it wont work.
> I get the list (defparameter LECTURE-SITE::TEST "/home/olivier/lisp/
> yawn/lecture-site/") which I wont evaluate as am looking for something
> without evil eval which, i'm sure, should be possible.
>
> Sorry to bother you, but am blocked.
> thanx

Well maybe defparameter is a bit misplaced for this.
This is what a macroexpansion produces in LispWorks:

CL-USER 1 > (pprint (macroexpand '(defparameter *list* '( 1 2 3))))

(COMPILER-LET ((DSPEC::*LOCATION*
                 '(:INSIDE (DEFPARAMETER *LIST*) :LISTENER)))
   (COMPILER::TOP-LEVEL-FORM-NAME (DEFPARAMETER *LIST*)
     (EVAL-WHEN (:COMPILE-TOPLEVEL)
       (COMPILER::ADD-SPECIAL '*LIST* 'DSPEC::GLOBAL NIL))
     (DSPEC:INSTALL-DEFPARAMETER '*LIST* (DSPEC:LOCATION) '(1 2 3))))

In partiucular notice the eval-when section.
It is clear that defparameter is only intended to be reinitialized when a  
compile-toplevel
(compile buffer/compile file) is encountered.
If you are creating variables at runtime wouldn't it be better to create  
your own hash table to keep track of the created variables?

--------------
John Thingstad
From: ·········@olive-it.ch
Subject: Re: constructing and defining variable at runtime
Date: 
Message-ID: <dd009667-ae78-48c5-ac3b-c8a5d863f06a@k39g2000hsf.googlegroups.com>
On Jan 12, 2:14 am, "John Thingstad" <·······@online.no> wrote:
> På Sat, 12 Jan 2008 00:16:34 +0100, skrev <·········@olive-it.ch>:
>
> > Somehow i miss a backquote or what
> > How can i define at runtime variables
> > (DEFPARAMETER LECTURE-SITE::TEST "/home/olivier/lisp/yawn/lecture-
> > site/")
> > at runtime, i.e.
> > (defparameter <name> <value>)
> > where <name> and <value> are known at run-time. Tried all my macros -
> > somehow it wont work.
> > I get the list (defparameter LECTURE-SITE::TEST "/home/olivier/lisp/
> > yawn/lecture-site/") which I wont evaluate as am looking for something
> > without evil eval which, i'm sure, should be possible.
>
> > Sorry to bother you, but am blocked.
> > thanx
>
> Well maybe defparameter is a bit misplaced for this.
> This is what a macroexpansion produces in LispWorks:
>
> CL-USER 1 > (pprint (macroexpand '(defparameter *list* '( 1 2 3))))
>
> (COMPILER-LET ((DSPEC::*LOCATION*
>                  '(:INSIDE (DEFPARAMETER *LIST*) :LISTENER)))
>    (COMPILER::TOP-LEVEL-FORM-NAME (DEFPARAMETER *LIST*)
>      (EVAL-WHEN (:COMPILE-TOPLEVEL)
>        (COMPILER::ADD-SPECIAL '*LIST* 'DSPEC::GLOBAL NIL))
>      (DSPEC:INSTALL-DEFPARAMETER '*LIST* (DSPEC:LOCATION) '(1 2 3))))
>
> In partiucular notice the eval-when section.
> It is clear that defparameter is only intended to be reinitialized when a
> compile-toplevel
> (compile buffer/compile file) is encountered.
> If you are creating variables at runtime wouldn't it be better to create
> your own hash table to keep track of the created variables?
I would like to acces the variables more directly than with hash
tables:
(gethash 'test hashtbl)
vs.
test

actually, i have a description like this:
(wap-configuration "lecture"
		   :resources
		   (:files ((test "/home/olivier/lisp/yawn/lecture-site/")
			    (js-prototype "/home/olivier/lisp/yawn/lecture-site/resources/
scriptaculous-js-1.8.1/"))))

which is read in and should generate variables test and js-prototype
so that later in
(cl-who:head
  ((:script :language "JavaScript" :type "text/javascript"
            :src js-prototype)))
i can just use js-prototype instead of (gethash js-prototype'
hashtable)

thanx for the macroexpand of defparameter, will consider that..
I still get confused if what i want is defining variables at run-time,
compile-time or load-time
From: Pascal Bourguignon
Subject: Re: constructing and defining variable at runtime
Date: 
Message-ID: <87abnb5750.fsf@thalassa.informatimago.com>
·········@olive-it.ch writes:
> actually, i have a description like this:
> (wap-configuration "lecture"
> 		   :resources
> 		   (:files ((test "/home/olivier/lisp/yawn/lecture-site/")
> 			        (js-prototype "/home/olivier/lisp/yawn/lecture-site/resources/scriptaculous-js-1.8.1/"))))
>
> which is read in and should generate variables test and js-prototype
> so that later in
> (cl-who:head
>   ((:script :language "JavaScript" :type "text/javascript"
>             :src js-prototype)))
> i can just use js-prototype instead of (gethash js-prototype'
> hashtable)
>
> thanx for the macroexpand of defparameter, will consider that..
> I still get confused if what i want is defining variables at run-time,
> compile-time or load-time


I would define wap-configuration as a macro, and just LOAD these
descriptions as plain lisp files.

This would be a lisp "pattern": read in data file by loading them as
lisp sources, by preparing reader-macro and macros to translate the
data.

Then it would be prudent anyways to read these data file in a separate
package, where you'd import only the operators you allow to read the
data files (your macros and perhaps a few safe lisp operators).  In
this package, you could intern your variables:

(defpackage "CONFIGURATION" (:use))

(defmacro configuration::wap-configuration (...)
  `(progn 
      ...
      (defparameter ,name ,value)
      ...))

(defun load-configuration (filespec &key verbose print if-does-not-exist external-format)
   (let ((*package* (find-package "CONFIGURATION"))
         (*read-eval* nil)
         (*read-base* 10.)  
         ;; ...
         (*readtable* (copy-readtable nil)))
      (setf (readtable-case *readtable*) :preserve) ; or whatever is best for your data
      ;; define and undefine here the reader-macros you need, eg. to disable packages or escapes.
      (load filespec :verbose verbose :print print :if-does-not-exist if-does-not-exist 
                     :external-format external-format)))

Then, since the NAME in the wap-configuration macro will actually be
read and interned in the package CONFIGURATION.



Finally, if you choosed to put the variables in a hash-table, you
could also define a symbol-macro to let the user access the variable
by their names instead of having to write GETHASH:

(defmacro configuration::wap-configuration (...)
  `(progn 
      ...
      (define-symbol-macro ,name (gethash ',name *configuration-variables*))
      (setf ,name ,value)
      ...))


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

CAUTION: The mass of this product contains the energy equivalent of
85 million tons of TNT per net ounce of weight.
From: ·········@olive-it.ch
Subject: Re: constructing and defining variable at runtime
Date: 
Message-ID: <0f2a653e-ff70-416e-953b-0ad6a8243aae@m77g2000hsc.googlegroups.com>
On Jan 12, 5:40 pm, Pascal Bourguignon <····@informatimago.com> wrote:
> ·········@olive-it.ch writes:
> > actually, i have a description like this:
> > (wap-configuration "lecture"
> >               :resources
> >               (:files ((test "/home/olivier/lisp/yawn/lecture-site/")
> >                            (js-prototype "/home/olivier/lisp/yawn/lecture-site/resources/scriptaculous-js-1.8.1/"))))
>
> > which is read in and should generate variables test and js-prototype
> > so that later in
> > (cl-who:head
> >   ((:script :language "JavaScript" :type "text/javascript"
> >             :src js-prototype)))
> > i can just use js-prototype instead of (gethash js-prototype'
> > hashtable)
>
> > thanx for the macroexpand of defparameter, will consider that..
> > I still get confused if what i want is defining variables at run-time,
> > compile-time or load-time
>
> I would define wap-configuration as a macro, and just LOAD these
> descriptions as plain lisp files.
Thats what I do
>
> This would be a lisp "pattern": read in data file by loading them as
> lisp sources, by preparing reader-macro and macros to translate the
> data.
>
Will do some google research on that: others must have done the same
> Then it would be prudent anyways to read these data file in a separate
> package, where you'd import only the operators you allow to read the
> data files (your macros and perhaps a few safe lisp operators).  In
> this package, you could intern your variables:
>
Yeah, right, i did something on that line, but just having a packet
for the configuration details is easy to do and simply prudent..
Thanx:)
> (defpackage "CONFIGURATION" (:use))
>
> (defmacro configuration::wap-configuration (...)
>   `(progn
>       ...
>       (defparameter ,name ,value)
>       ...))
>
Which lets to the original question: how does this macro work? Anyhow
I'm confident that after
a day pause the macro will work
> (defun load-configuration (filespec &key verbose print if-does-not-exist external-format)
>    (let ((*package* (find-package "CONFIGURATION"))
>          (*read-eval* nil)
>          (*read-base* 10.)
>          ;; ...
>          (*readtable* (copy-readtable nil)))
>       (setf (readtable-case *readtable*) :preserve) ; or whatever is best for your data
>       ;; define and undefine here the reader-macros you need, eg. to disable packages or escapes.
>       (load filespec :verbose verbose :print print :if-does-not-exist if-does-not-exist
>                      :external-format external-format)))
>
Will consider that, even if i havent never worked with reader-macros
> Then, since the NAME in the wap-configuration macro will actually be
> read and interned in the package CONFIGURATION.
>
> Finally, if you choosed to put the variables in a hash-table, you
> could also define a symbol-macro to let the user access the variable
> by their names instead of having to write GETHASH:
>
> (defmacro configuration::wap-configuration (...)
>   `(progn
>       ...
>       (define-symbol-macro ,name (gethash ',name *configuration-variables*))
>       (setf ,name ,value)
>       ...))
>
Great, didn't know there was this define-symbol-macro, had to look it
up
Aahh, now I have to rethink if working with hash tables or
defparameter in a package
is more appropriate to solve this configuration pattern.
Thanx  Pascal Bourguignon, you helped a lot
olivier buechel
From: Kalle Olavi Niemitalo
Subject: Re: constructing and defining variable at runtime
Date: 
Message-ID: <878x2vevh6.fsf@Astalo.kon.iki.fi>
·········@olive-it.ch writes:

> (defparameter <name> <value>)
> where <name> and <value> are known at run-time.

(setf (symbol-value name) value) does part of the job.
The SET function does the same but is deprecated.

(proclaim `(special ,name)) does another part.
Then you may also want to use (setf documentation).

Or perhaps you want to bind the variables in the dynamic
environment only, in which case you should use PROGV.

> I get the list (defparameter LECTURE-SITE::TEST "/home/olivier/lisp/
> yawn/lecture-site/") which I wont evaluate as am looking for something
> without evil eval which, i'm sure, should be possible.

One problem with EVAL is that it always uses the null lexical
environment, even though the form may have originally been
intended to be evaluated in some other environment.
However, that doesn't matter with your DEFPARAMETER form,
if the initial-value subform is a self-evaluating object
or (quote ...).  So, in this case, EVAL might not be as bad
as in some other cases.

I vaguely recall reading that EVAL might also hinder "tree
shakers" that remove unused objects from a Lisp image so that
it needs less disk space and memory.

I wonder though, why do you want to generate special variables
with names chosen at run time?  And whether you could rearrange
your code so as to choose the names at macroexpand time instead.
From: ·········@olive-it.ch
Subject: Re: constructing and defining variable at runtime
Date: 
Message-ID: <46c4f515-fabc-48da-aa84-36da32143d39@k2g2000hse.googlegroups.com>
On Jan 12, 1:30 am, Kalle Olavi Niemitalo <····@iki.fi> wrote:
> ·········@olive-it.ch writes:
> > (defparameter <name> <value>)
> > where <name> and <value> are known at run-time.
>
> (setf (symbol-value name) value) does part of the job.
> The SET function does the same but is deprecated.
>
> (proclaim `(special ,name)) does another part.
> Then you may also want to use (setf documentation).
>
> Or perhaps you want to bind the variables in the dynamic
> environment only, in which case you should use PROGV.
>
> > I get the list (defparameter LECTURE-SITE::TEST "/home/olivier/lisp/
> > yawn/lecture-site/") which I wont evaluate as am looking for something
> > without evil eval which, i'm sure, should be possible.
>
> One problem with EVAL is that it always uses the null lexical
> environment, even though the form may have originally been
> intended to be evaluated in some other environment.
> However, that doesn't matter with your DEFPARAMETER form,
> if the initial-value subform is a self-evaluating object
> or (quote ...).  So, in this case, EVAL might not be as bad
> as in some other cases.
>
> I vaguely recall reading that EVAL might also hinder "tree
> shakers" that remove unused objects from a Lisp image so that
> it needs less disk space and memory.
>
> I wonder though, why do you want to generate special variables
> with names chosen at run time?  And whether you could rearrange
> your code so as to choose the names at macroexpand time instead.
Those variables name are read in from a file as are the forms
where they (the variables) are needed

Thanx for clarifying setf and special aprts of work.
From: Pascal Bourguignon
Subject: Re: constructing and defining variable at runtime
Date: 
Message-ID: <87ir1z6bnz.fsf@thalassa.informatimago.com>
·········@olive-it.ch writes:

> Somehow i miss a backquote or what
> How can i define at runtime variables
> (DEFPARAMETER LECTURE-SITE::TEST "/home/olivier/lisp/yawn/lecture-
> site/")
> at runtime, i.e.
> (defparameter <name> <value>)
> where <name> and <value> are known at run-time. Tried all my macros -
> somehow it wont work.
> I get the list (defparameter LECTURE-SITE::TEST "/home/olivier/lisp/
> yawn/lecture-site/") which I wont evaluate as am looking for something
> without evil eval which, i'm sure, should be possible.

To create a special variable, you can merely set it's symbol-value:


   (setf (symbol-value 'lecture-site::*test*) "hi")


   (let ((variable (intern (format nil "*~A*" (compute-some-name))
                           (compute-some-package)))
         (value    (compute-some-value)))
     (setf (symbol-value variable) value))

Now, of course, since it's a variable created at run-time, you won't
have any reference to it in your code.  No (f lecture-site::*test*).
Therefore there's no need for any declaration of the specialness of
this symbol, since there's no code to compile, at run-time, taking
into account this specialness.  You will only access it at run-time,
with (symbol-value variable).

That's why, as John adviced, you may consider using a hash-table or
some other structure to store your data.


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

ADVISORY: There is an extremely small but nonzero chance that,
through a process known as "tunneling," this product may
spontaneously disappear from its present location and reappear at
any random place in the universe, including your neighbor's
domicile. The manufacturer will not be responsible for any damages
or inconveniences that may result.
From: ·········@olive-it.ch
Subject: Re: constructing and defining variable at runtime
Date: 
Message-ID: <ae55a992-4df0-4a4e-8f0b-2c7e64f8668e@s13g2000prd.googlegroups.com>
On Jan 12, 3:05 am, Pascal Bourguignon <····@informatimago.com> wrote:
> ·········@olive-it.ch writes:
> > Somehow i miss a backquote or what
> > How can i define at runtime variables
> > (DEFPARAMETER LECTURE-SITE::TEST "/home/olivier/lisp/yawn/lecture-
> > site/")
> > at runtime, i.e.
> > (defparameter <name> <value>)
> > where <name> and <value> are known at run-time. Tried all my macros -
> > somehow it wont work.
> > I get the list (defparameter LECTURE-SITE::TEST "/home/olivier/lisp/
> > yawn/lecture-site/") which I wont evaluate as am looking for something
> > without evil eval which, i'm sure, should be possible.
>
> To create a special variable, you can merely set it's symbol-value:
>
>    (setf (symbol-value 'lecture-site::*test*) "hi")
>
>    (let ((variable (intern (format nil "*~A*" (compute-some-name))
>                            (compute-some-package)))
>          (value    (compute-some-value)))
>      (setf (symbol-value variable) value))
>

Oh yes thanks, that's what i was looking for, kind of i think..

> Now, of course, since it's a variable created at run-time, you won't
> have any reference to it in your code.  No (f lecture-site::*test*).
Yes I do
somewhere in package lecture-site i have
(cl-who:head
  ((:script :language "JavaScript" :type "text/javascript"
            :src *test*)))
where *test* is used
The definition of *test* is read from a file.
Ahh, so it's read-time i know what name and value are used.
How does that change my problem? I'll have to think more..
Perhaps best would be to let the user write
(cl-who:head
  ((:script :language "JavaScript" :type "text/javascript"
            :src (test))))
i.e. call some function defined at run-time. This will get me more
flexibility,
the user however has to write  parenthesis when he wants to access the
value of that resource..

> Therefore there's no need for any declaration of the specialness of
> this symbol, since there's no code to compile, at run-time, taking
> into account this specialness.  You will only access it at run-time,
> with (symbol-value variable).
>
> That's why, as John adviced, you may consider using a hash-table or
> some other structure to store your data.
>
> --
> __Pascal Bourguignon__                    http://www.informatimago.com/
>
> ADVISORY: There is an extremely small but nonzero chance that,
> through a process known as "tunneling," this product may
> spontaneously disappear from its present location and reappear at
> any random place in the universe, including your neighbor's
> domicile. The manufacturer will not be responsible for any damages
> or inconveniences that may result.
From: Alan Crowe
Subject: Re: constructing and defining variable at runtime
Date: 
Message-ID: <8663xzuht1.fsf@cawtech.freeserve.co.uk>
·········@olive-it.ch writes:

> Somehow i miss a backquote or what
> How can i define at runtime variables
> (DEFPARAMETER LECTURE-SITE::TEST "/home/olivier/lisp/yawn/lecture-
> site/")
> at runtime, i.e.
> (defparameter <name> <value>)
> where <name> and <value> are known at run-time. Tried all my macros -
> somehow it wont work.
> I get the list (defparameter LECTURE-SITE::TEST "/home/olivier/lisp/
> yawn/lecture-site/") which I wont evaluate as am looking for something
> without evil eval which, i'm sure, should be possible.

Can you use PROGV, for example:

CL-USER> (progv (list (read))
             (list (read))
           (eval (read)))
x
3
(- pi x)
0.14159265358979312d0

Alan Crowe
Edinburgh
Scotland
From: Kent M Pitman
Subject: Re: constructing and defining variable at runtime
Date: 
Message-ID: <u7iievr9v.fsf@nhplace.com>
Alan Crowe <····@cawtech.freeserve.co.uk> writes:

> ·········@olive-it.ch writes:
> 
> > Somehow i miss a backquote or what
> > How can i define at runtime variables
> > ... am looking for something
> > without evil eval which, i'm sure, should be possible.
> 
> Can you use PROGV, for example: [...]

Does it need to actually be a variable?  Can it just be data you set and
access by a symbolic tag?  Nothing wrong with specials and PROGV and all
that if you need it, but often you don't.  e.g., can you just write:

 (defvar *info* (make-hash-table))
 (defun info (name)
   (nth-value 0 (gethash name *info*)))
 (defun info-p (name)
   (nth-value 1 (gethash name *info*)))
 (defun (setf info) (value name)
   (setf (gethash name *info*) value))

 (info 'test)          => NIL
 (info-p 'test)        => NIL

 (setf (info 'test) 3) => 3

 (info 'test)          => 3
 (info-p 'test)        => T
From: ·········@olive-it.ch
Subject: Re: constructing and defining variable at runtime
Date: 
Message-ID: <1ebfef8c-e99d-454d-af2e-dde2464028bc@k39g2000hsf.googlegroups.com>
On Jan 12, 7:21 pm, Kent M Pitman <······@nhplace.com> wrote:
> Alan Crowe <····@cawtech.freeserve.co.uk> writes:
> > ·········@olive-it.ch writes:
>
> > > Somehow i miss a backquote or what
> > > How can i define at runtime variables
> > > ... am looking for something
> > > without evil eval which, i'm sure, should be possible.
>
> > Can you use PROGV, for example: [...]
>
> Does it need to actually be a variable?  Can it just be data you set and
> access by a symbolic tag?  Nothing wrong with specials and PROGV and all
> that if you need it, but often you don't.  e.g., can you just write:
>
>  (defvar *info* (make-hash-table))
>  (defun info (name)
>    (nth-value 0 (gethash name *info*)))
>  (defun info-p (name)
>    (nth-value 1 (gethash name *info*)))
>  (defun (setf info) (value name)
>    (setf (gethash name *info*) value))
>
>  (info 'test)          => NIL
>  (info-p 'test)        => NIL
>
>  (setf (info 'test) 3) => 3
>
>  (info 'test)          => 3
>  (info-p 'test)        => T

this would reuire to write
(info 'test) instead of simply test
which may or may not be considered a small difference. I however
prefer
simply to write test when i need test.
As __Pascal Bourguignon__  posted
(define-symbol-macro ,name (gethash ',name *configuration-variables*))
will do the work .
thanx