From: G. Pontix
Subject: sharing variables between functions
Date: 
Message-ID: <1121711343.210156@athnrd02>
Hello everybody, 

I have been self-learning LISP recently, after a decade programming solely
in FORTRAN. I am an engineer and I am interested in numerical analysis
software. In order to assess LISP for such projects, I am trying to
re-implement some existing software in LISP. So, here is an issue that I
need help:

I need to share some variables between several functions in LISP. These must
be accessible by different groups of LISP functions and they are not
necessarily constants (they may also represent e.g. state).

In FORTRAN, this was feasible with named common blocks (in FORTRAN 77), or
with modules (in FORTRAN 90). I do not know how to accomplish this in LISP.

To be more specific, here is what I have thought and fails:

1. I could bundle the variables in structures or lists and transfer them as
function arguments. I find this ugly, since the variables mainly represent
state, or physical constants, and they are not strictly input data for the
functions.

2. I could define functions inside some let statement:
(let ((var1 10)
   (var2 20)
   (var3 30))
 (defun function1 () (...))
 (defun function2 () (...))
 (defun function3 () (...))

This fails because in case I need e.g. function3 to access variables var1 &
var2 only.

3. I suspect I could store each function and its corresponding variables in
hash tables, and subsequently retrieve them, using funcall. I am not really
sure how to implement such an idea but I keep experimenting.

Do you have any suggestions? I understand that thinking in LISP requires
re-training, but as an engineer who has grown up with FORTRAN, I find it
hard to re-wire my brain. Nevertheless, programming in LISP seems much more
fun and the language is clearly more powerful, so I intend to give LISP a
serious try. Therefore, references to books or articles where I can find
information or sample code about numerical computing in LISP would also be
appreciated. I am currently studying Paul Graham's "ANSI Common Lisp"
although Peter Seibel's book has been recommended to me as well.

Thank you very much in advance,
Giorgos

From: Harold
Subject: Re: sharing variables between functions
Date: 
Message-ID: <1121715911.095185.242910@g47g2000cwa.googlegroups.com>
<pre><code>
(let ((var1 10)
      (var2 20))
  (let ((var3 30))
    (defun function1 () (...))
    (defun function2 () (...)))
  (defun function3 () (...)))
</code></pre>

In this example, function1 and function2 can see var1, var2 and var3,
but function3 can only see var1 and var2. All three functions access
the same var1 and var2.
From: Eric Lavigne
Subject: Re: sharing variables between functions
Date: 
Message-ID: <1121715596.471246.154660@g44g2000cwa.googlegroups.com>
>I have been self-learning LISP recently, after a decade programming solely
>in FORTRAN. I am an engineer and I am interested in numerical analysis
>software. In order to assess LISP for such projects, I am trying to
>re-implement some existing software in LISP.

Nicolas Neuss, one of the regulars on this newsgroup, is using Lisp for
numerical solutions to partial differential equations:
http://www.femlisp.org/

You might be interested in his publications, some of which discuss the
suitability of Lisp for numerical applications:
http://www1.iwr.uni-heidelberg.de/~Nicolas.Neuss/publications.html

>In FORTRAN, this was feasible with named common blocks
>(in FORTRAN 77), or with modules (in FORTRAN 90). I do not
>know how to accomplish this in LISP.

Have you heard of packages? They are similar to the modules in FORTRAN
90. Another possibility is to just use global variables (assuming there
are no name conflicts between your modules). To make a global variable,
use (defvar var1 10). As a convention, to remind us which variables are
global, we usually add asterisks to the names of global variables:
(defvar *var1* 10)

>3. I suspect I could store each function and its corresponding variables in
>hash tables, and subsequently retrieve them, using funcall. I am not really
>sure how to implement such an idea but I keep experimenting.

Yes, you could. That sounds unnecessarily complicated, though.

>Do you have any suggestions? I understand that thinking in LISP requires
>re-training, but as an engineer who has grown up with FORTRAN, I find it
>hard to re-wire my brain.

The rules for variable scope (which you are dealing with right now) are
very different from FORTRAN. Lisp also has a lot of neat stuff that
FORTRAN doesn't have. Aside from those two issues, there is generally a
simple relationship between FORTRAN code and corresponding Lisp code.
If you focus only on the part of Lisp that you need for that
translation, you will find that very little re-wiring is required. That
is the approach I took to get started working quickly. Then I went back
to look at the other neat stuff later. There's no need to absorb the
whole language at once.

>I am currently studying Paul Graham's "ANSI Common Lisp"
>although Peter Seibel's book has been recommended to me as well.

Those are good books. I also recommend the Common Lisp Hyperspec:
http://www.lisp.org/HyperSpec/FrontMatter/index.html
From: JP Massar
Subject: Re: sharing variables between functions
Date: 
Message-ID: <i18od1t3nn5tvp9935321uja0chhtr40mk@4ax.com>
On Mon, 18 Jul 2005 21:29:05 +0300, "G. Pontix" <···@freemail.gr>
wrote:

>Hello everybody, 
>
>I have been self-learning LISP recently, after a decade programming solely
>in FORTRAN. I am an engineer and I am interested in numerical analysis
>software. In order to assess LISP for such projects, I am trying to
>re-implement some existing software in LISP. So, here is an issue that I
>need help:
>
>I need to share some variables between several functions in LISP. These must
>be accessible by different groups of LISP functions and they are not
>necessarily constants (they may also represent e.g. state).
>
 
Here is an approach:

(defvar *current-state* nil)

(defun main-function ()
    ...
    (let ((*current-state* (define-my-current-state ...)))
     ...
      (subfunction1 )
     ...
     (subfunction2 3.2)
    ...
    ))

(defun subfunction1 ()
    (when (>  (temperature *current-state*) 100) ...))

(defun subfunction2 (evalue)
   (when (>  (entropy *current-state*) evalue) ...))


     
The value of *current-state* can be anything you like:  a structure, a
class, a list of key-value pairs, whatever.
From: G. Pontix
Subject: Re: sharing variables between functions
Date: 
Message-ID: <1121730112.386531@athnrd02>
JP Massar wrote:

> Here is an approach:
> 
> (defvar *current-state* nil)
> 
> (defun main-function ()
>     ...
>     (let ((*current-state* (define-my-current-state ...)))
>      ...
>       (subfunction1 )
>      ...
>      (subfunction2 3.2)
>     ...
>     ))
> 
> (defun subfunction1 ()
>     (when (>  (temperature *current-state*) 100) ...))
> 
> (defun subfunction2 (evalue)
>    (when (>  (entropy *current-state*) evalue) ...))
> 
> 
>      
> The value of *current-state* can be anything you like:  a structure, a
> class, a list of key-value pairs, whatever.


Thank you, this is pretty much what I was searching for. (Maybe packages are
another good approach for me, as suggested by others, but I really don't
know -- I'll study further.) But your solution gave me the following idea: 

Instead of using the *current-state* global variable to communicate between
the definition of the subfunctions and the main-function, could I nest the 
subfunctions' defuns into the function "define-my-current-state", which you
use in the above example to get the current-state? Specifically:

(defun define-my-current-state ()
 (setf temperature ...)
 (setf entropy ...)
 (defun subfunction1 ()
     (when (>  (temperature *current-state*) 100) ...))
 (defun subfunction2 (evalue)
    (when (>  (entropy *current-state*) evalue) ...)))

Is this a good idea?

To my understanding, the above defuns will re-define the global subfunction1
& subfunction2, every time define-my-current-state is called to update the
state. But I suspect from the few things that I have seen on the web, that
nested defuns are not usually used, except in Scheme, although they seem to
work in my implementation (clisp on slackware linux). Is there a
possibility to interfere with e.g. compilation or performance? 

It seems a little strange to be able to do such things, from a Fortran
perspective :-)


-- Giorgos
From: JP Massar
Subject: Re: sharing variables between functions
Date: 
Message-ID: <8alod1hn48vk69c1d1t6t2oel7qlqavine@4ax.com>
 
>
>
>Thank you, this is pretty much what I was searching for. (Maybe packages are
>another good approach for me, as suggested by others, but I really don't
>know -- I'll study further.) But your solution gave me the following idea: 
>
>Instead of using the *current-state* global variable to communicate between
>the definition of the subfunctions and the main-function, could I nest the 
>subfunctions' defuns into the function "define-my-current-state", which you
>use in the above example to get the current-state? Specifically:

I'm confused.  You say above 'instead of using *current-state*' and
then you go ahead and use *current-state* in your example below.


>
>(defun define-my-current-state ()
> (setf temperature ...)
> (setf entropy ...)
> (defun subfunction1 ()
>     (when (>  (temperature *current-state*) 100) ...))
> (defun subfunction2 (evalue)
>    (when (>  (entropy *current-state*) evalue) ...)))
>
>Is this a good idea?

As a rule for a new Lisper, no.  There is almost always a better
approach than nested defuns.

>
>To my understanding, the above defuns will re-define the global subfunction1
>& subfunction2, every time define-my-current-state is called to update the
>state.

Yes.


>But I suspect from the few things that I have seen on the web, that
>nested defuns are not usually used, except in Scheme, although they seem to
>work in my implementation (clisp on slackware linux). Is there a
>possibility to interfere with e.g. compilation or performance? 
>


I suspect that using most Lisp compilers performance would suffer.

>It seems a little strange to be able to do such things, from a Fortran
>perspective :-)
>
 
Yes.  
From: Jock Cooper
Subject: Re: sharing variables between functions
Date: 
Message-ID: <m31x5tdpjw.fsf@jcooper02.sagepub.com>
"G. Pontix" <···@freemail.gr> writes:

> JP Massar wrote:
> 
> > Here is an approach:
> > 
> > (defvar *current-state* nil)
> > 
> > (defun main-function ()
> >     ...
> >     (let ((*current-state* (define-my-current-state ...)))
> >      ...
> >       (subfunction1 )
> >      ...
> >      (subfunction2 3.2)
> >     ...
> >     ))
> > 
> > (defun subfunction1 ()
> >     (when (>  (temperature *current-state*) 100) ...))
> > 
> > (defun subfunction2 (evalue)
> >    (when (>  (entropy *current-state*) evalue) ...))
> > 
> > 
> >      
> > The value of *current-state* can be anything you like:  a structure, a
> > class, a list of key-value pairs, whatever.
> 
> 
> Thank you, this is pretty much what I was searching for. (Maybe packages are
> another good approach for me, as suggested by others, but I really don't
> know -- I'll study further.) But your solution gave me the following idea: 
> 
> Instead of using the *current-state* global variable to communicate between
> the definition of the subfunctions and the main-function, could I nest the 
> subfunctions' defuns into the function "define-my-current-state", which you
> use in the above example to get the current-state? Specifically:
> 
> (defun define-my-current-state ()
>  (setf temperature ...)
>  (setf entropy ...)
>  (defun subfunction1 ()
>      (when (>  (temperature *current-state*) 100) ...))
>  (defun subfunction2 (evalue)
>     (when (>  (entropy *current-state*) evalue) ...)))
> 
> Is this a good idea?
> 
> To my understanding, the above defuns will re-define the global subfunction1
> & subfunction2, every time define-my-current-state is called to update the
> state. But I suspect from the few things that I have seen on the web, that
> nested defuns are not usually used, except in Scheme, although they seem to
> work in my implementation (clisp on slackware linux). Is there a
> possibility to interfere with e.g. compilation or performance? 
> 
> It seems a little strange to be able to do such things, from a Fortran
> perspective :-)
> 

*current-state* is special, not global.  It isn't like a global in C
for example.  Read up on special vars and you will see that they
provide exactly what you need.
From: Pascal Costanza
Subject: Re: sharing variables between functions
Date: 
Message-ID: <3k2df6Fs7ruuU1@individual.net>
G. Pontix wrote:
> Hello everybody, 
> 
> I have been self-learning LISP recently, after a decade programming solely
> in FORTRAN. I am an engineer and I am interested in numerical analysis
> software. In order to assess LISP for such projects, I am trying to
> re-implement some existing software in LISP. So, here is an issue that I
> need help:
> 
> I need to share some variables between several functions in LISP. These must
> be accessible by different groups of LISP functions and they are not
> necessarily constants (they may also represent e.g. state).
> 
> In FORTRAN, this was feasible with named common blocks (in FORTRAN 77), or
> with modules (in FORTRAN 90). I do not know how to accomplish this in LISP.

Let's assume you mean Common Lisp. (It's old-fashioned to write LISP in 
all upper case, and since there are many Lisp dialects around, it's 
helpful to state what Lisp you are using. In comp.lang.lisp, by default 
Common Lisp is assumed. This is not a rule, it is just the most common 
case.)

In Common Lisp, packages are used to group functionality. They are used 
in similar cases when modules are used in other languages, but they work 
quite differently. This can be confusing at first, so it's wise to read 
some good tutorial about this. A recent book is Practical Common Lisp 
where you can read about it - see http://www.gigamonkeys.com/book/ for 
an online version. Other books are listed at 
http://www.cliki.net/Lisp%20books

> 2. I could define functions inside some let statement:
> (let ((var1 10)
>    (var2 20)
>    (var3 30))
>  (defun function1 () (...))
>  (defun function2 () (...))
>  (defun function3 () (...))
> 
> This fails because in case I need e.g. function3 to access variables var1 &
> var2 only.

No, this would actually work. Functions only close over variables they 
actually use - this can be statically determined by a Lisp compiler.

Nevertheless, it's unusual to do it like that. It's more common to do this:

(defvar *var1* 10)
(defvar *var2* 20)
(defvar *var3* 30)

(defun function1 () (...))
(defun function2 () (...))
(defun function3 () (...))

The convention to use asterisks in variable names (like *var1*) is to 
indicate that these are global variables. (Actually, that they are 
"special" variables. Again, a good tutorial will explain what this means 
in more detail.)

When you define those variables and functions in your own package, but 
only export the names of the functions, you have created the abstraction 
boundary you're looking for.

> Do you have any suggestions? I understand that thinking in LISP requires
> re-training, but as an engineer who has grown up with FORTRAN, I find it
> hard to re-wire my brain. Nevertheless, programming in LISP seems much more
> fun and the language is clearly more powerful, so I intend to give LISP a
> serious try. Therefore, references to books or articles where I can find
> information or sample code about numerical computing in LISP would also be
> appreciated. I am currently studying Paul Graham's "ANSI Common Lisp"
> although Peter Seibel's book has been recommended to me as well.

I liked the first two chapters in Paul Graham's ANSI Common Lisp because 
they get you going very early on. However, Peter Seibel's book uses a 
more "modern" approach with a focus on applications typically written 
nowadays whereas the "traditional" books use more "traditional" examples 
(for obvious reasons). Since many of the books are available online, you 
can skip through some of them and pick the one that suits your style the 
most. Among the books that don't have online versions, "Paradigms of 
Artificial Intelligence Programming" by Peter Norvig is also recommended 
(but he doesn't introduce packages, IIRC).


I hope this helps.


Pascal

-- 
2nd European Lisp and Scheme Workshop
July 26 - Glasgow, Scotland - co-located with ECOOP 2005
http://lisp-ecoop05.bknr.net/
From: Christopher C. Stacy
Subject: Re: sharing variables between functions
Date: 
Message-ID: <ufyubend6.fsf@news.dtpq.com>
"G. Pontix" <···@freemail.gr> writes:

> In FORTRAN, this was feasible with named common blocks 
>(in FORTRAN 77), or with modules (in FORTRAN 90).
> I do not know how to accomplish this in LISP.

> Do you have any suggestions? 

In Fortran, you run programs seperately and can have
a common overlay area.  In Lisp, you can dynamically 
load up more than one program at once.   

So the simple answer is that you can just use some 
global variables that are referenced by all the programs.
See DEFVAR.  Global variables are conventionally named
with asteriks, like *TEMPERATURE*.

If you want some more structure, you can place your each 
of your programs into a "package" (symbol namespace).
They could be in seperate packages, and you could put
the variable definitions into a seperate package that
they all "use".  See DEFPACKAGE and the :USE option.

You could also bundle the variables into objects,
so that you could have more than one set of values
for the variables.  You would define a class (DEFCLASS),
and each variable would be a slot with a functional
accessor. 

You might have different classes that group certain
related variables together.  And/or you might have
classes that describe analysis sessions (parameters
and results).  Perhaps there would be a hash table
of sessions keyed by some identifier. You might have
a global variable binding to the current session.
From: Pascal Bourguignon
Subject: Re: sharing variables between functions
Date: 
Message-ID: <87ackjcwjc.fsf@thalassa.informatimago.com>
"G. Pontix" <···@freemail.gr> writes:

> Hello everybody, 
>
> I have been self-learning LISP recently, after a decade programming solely
> in FORTRAN. I am an engineer and I am interested in numerical analysis
> software. In order to assess LISP for such projects, I am trying to
> re-implement some existing software in LISP. So, here is an issue that I
> need help:
>
> I need to share some variables between several functions in LISP. These must
> be accessible by different groups of LISP functions and they are not
> necessarily constants (they may also represent e.g. state).
>
> In FORTRAN, this was feasible with named common blocks (in FORTRAN 77), or
> with modules (in FORTRAN 90). I do not know how to accomplish this in LISP.
>
> To be more specific, here is what I have thought and fails:
>
> 1. I could bundle the variables in structures or lists and transfer them as
> function arguments. I find this ugly, since the variables mainly represent
> state, or physical constants, and they are not strictly input data for the
> functions.

Physical constants  can be defined as constants:

(defconstant +g+  6.672e-11    "gravitation (* (^ kg -1) (^ m 3) (^ s -2))")
(defconstant +e+  1.602189e-19 "charge      C")
(defconstant +c+  299792458.0  "light speed (* m (^ s -1))")
(defconstant +k+  1.38066e-23  "Boltzmann's (* J (^ K -1))")
;; ...

But you could omit the conventional +'s in names of constant, the
constants in COMMON-LISP don't have it.


State ARE input data (Input-Output data actually).

Actually, you could implement state as objects and functions working
on these state as methods.

In any case, you NEED to pass them as arguments, to be able to use
your function on two items at the same time.


> 2. I could define functions inside some let statement:
> (let ((var1 10)
>    (var2 20)
>    (var3 30))
>  (defun function1 () (...))
>  (defun function2 () (...))
>  (defun function3 () (...))
>
> This fails because in case I need e.g. function3 to access variables var1 &
> var2 only.

Given the theorical equivalence between closures and objects, you've got it.


> 3. I suspect I could store each function and its corresponding variables in
> hash tables, and subsequently retrieve them, using funcall. I am not really
> sure how to implement such an idea but I keep experimenting.

Accessing slots in an object would be faster than using a hash table...


If you keep the state in global variables, then when you want to apply
the same function on various instances you need to copy the global
variables back and from which is very inefficient.  It's better to
keep the state in objects, and pass to the functions just a reference
to one instance or the other.


You could say that when you compute the explosion of a nuclear device,
one bomb is enought to simulate.  Well, if you just want to kill
people, yes.  But if you want to propulse a rocket, you might want to
use several explosions, so you'd better keep each bomb in a separate
object to be able to compute their cascading explosions.


-- 
__Pascal Bourguignon__                     http://www.informatimago.com/
The rule for today:
Touch my tail, I shred your hand.
New rule tomorrow.
From: David Steuber
Subject: Re: sharing variables between functions
Date: 
Message-ID: <87ek9tdsy0.fsf@david-steuber.com>
"G. Pontix" <···@freemail.gr> writes:

> I need to share some variables between several functions in LISP. These must
> be accessible by different groups of LISP functions and they are not
> necessarily constants (they may also represent e.g. state).
> 
> In FORTRAN, this was feasible with named common blocks (in FORTRAN 77), or
> with modules (in FORTRAN 90). I do not know how to accomplish this in LISP.

Other posters have already mentioned special variables (globals) and
packages.  When you talk about groups of variables holding state, I
think of CLOS classes with slots to hold state and generic functions
with applicable methods to work with the state.

As you are also talking about numerical work, Lisp is quite capable in
this area as well.  I've recently finished a fractal movie that I
produced using Lisp.  I've published the code, which is a mess because
it contains some half-baked stuff and experimental bits, which uses
CLOS to group together related state information.  I've even got a
closure and higher-order function or two in there, although they are
not written efficiently.  Frankly the code would need a lot of cleanup
if it were to be used heavily.

Nevertheless, it may serve as a useful example to you and perhaps
people will send me feedback on how some things can be done better.
The code is here:

http://www.david-steuber.com/Lisp/mset/mset.lisp.txt

And the movie made with it is here:

http://www.david-steuber.com/Lisp/mset/xenos-xoom/

If it's still working, the movie file itself is best fetched from a
torrent that was set up for it here:

http://www.ltn.lv/~jonis/xenos-xoom.mov.torrent

</shameless-self-promotion>

-- 
My .sig file sucks.  Can anyone recommend a better one?
From: G. Pontix
Subject: Re: sharing variables between functions
Date: 
Message-ID: <1121962969.675785@athnrd02>
David Steuber wrote:

> 
> "G. Pontix" <···@freemail.gr> writes:
> 
>> I need to share some variables between several functions in LISP. These
>> must be accessible by different groups of LISP functions and they are not
>> necessarily constants (they may also represent e.g. state).
>> 
>> In FORTRAN, this was feasible with named common blocks (in FORTRAN 77),
>> or with modules (in FORTRAN 90). I do not know how to accomplish this in
>> LISP.
> 
> Other posters have already mentioned special variables (globals) and
> packages.  When you talk about groups of variables holding state, I
> think of CLOS classes with slots to hold state and generic functions
> with applicable methods to work with the state.
> 
> As you are also talking about numerical work, Lisp is quite capable in
> this area as well.  I've recently finished a fractal movie that I
> produced using Lisp.  I've published the code, which is a mess because
> it contains some half-baked stuff and experimental bits, which uses
> CLOS to group together related state information.  I've even got a
> closure and higher-order function or two in there, although they are
> not written efficiently.  Frankly the code would need a lot of cleanup
> if it were to be used heavily.
> 
> Nevertheless, it may serve as a useful example to you and perhaps
> people will send me feedback on how some things can be done better.
> The code is here:
> 
> http://www.david-steuber.com/Lisp/mset/mset.lisp.txt
> 
> And the movie made with it is here:
> 
> http://www.david-steuber.com/Lisp/mset/xenos-xoom/
> 
> If it's still working, the movie file itself is best fetched from a
> torrent that was set up for it here:
> 
> http://www.ltn.lv/~jonis/xenos-xoom.mov.torrent
> 
> </shameless-self-promotion>
> 

Thank you very much for the code. I'll study it and see what I can learn;
looking at other people's code had been useful when I was studying Fortran.

I also need to express my sincere thanks to all people who replied to my
post. I really appreciate that this is a very friendly newsgroup. I hope I
learn enough so that I can contribute back some day :-)

Thanks again
-- Giorgos