Re: Is there ever a good reason to create globals in Lisp?

"Pascal J. Bourguignon" <[email protected]>
Newsgroups gmane.lisp.clisp.devel
Organization InformatiMago.
Message-ID <[email protected]>
"Yves S. Garret" <[email protected]> writes:

> I wouldn't say I "worry" about it.  The concept of not having global
> vars at all (well, unless there's a damn good reason, avoid at all
> costs like the 'goto') has been drilled down into my skull ever since
> I finished my first C++ programming class in college.
>
> From a design perspective, this makes sense.  Fewer global vars are a
> good thing.  They can give you quirky behavior unless you're super
> careful.  I was more curious when you guys design Lisp apps, how you
> treat global variables (yes, classes, functions, etc. are global as
> well, but this is not exactly the same thing) in Lisp.  Even in
> imperative and OO languages globals have a time and place (but very
> seldom and there has to be a damn good reason why).  Do professional
> Lisp developers actively embrace them?  Stay away from them like you
> would in other programming languages?  Or is there some other
> middle-ground that I'm not aware of.
>
> The example that you provide is exactly where I could see how things
> could go very wrong in terms of undefined behavior :-) .  How are
> global variable regarded in Lisp?


I reiterate, there's no dogmatism.  They're a tool, and as any tool,
they can be put to good use, or to bad use.

But I repeat, one good use is that they allow easy access to data from
the REPL.  You can store some data from the inners of a function to a
global variable, so that when it's done you can inspect that data from
the REPL:

  (defvar *data*)

  (defun f (n p)
    (push p *data*)
    (if (zerop n) 
       p
       (f (1- n) (* n p))))

  (f 14 1)
  --> 87178291200

  *data*
  --> (87178291200 87178291200 43589145600 14529715200 3632428800
       726485760 121080960 17297280 2162160 240240 24024 2184 182 14 1)


This goes also for dynamic binding.  While it would be in general better
to use dynamic binding, ie.:

    (defun f () (let ((*global* local-value)) (g)))

for debugging purposes it may be good to use:

    (defun f () (setf *global* local-value) (g))

So that when f is ran, you can call and debug independently g (or h or
other inner functions), with *global* bound to local-value.  When
debugging is done, you revert to the dynamic binding LET so that F
doesn't change its global binding.


Notice how dynamic binding actually mitigates the globalness of the
variable.

   (defvar *global* '())

   (defun g () (print *global*))
   
   (defun f ()
      (let ((*global* (cons 42 *global*)))
         (g))
      (values))

   (f)
   *global* --> ()

with a dynamic binding LET, the global value of the *global* variable is
not changed, just masked temporarily.  This is important also with
threads, where one can give a set of dynamic bindings which will be
local to the thread.



-- 
__Pascal Bourguignon__                     http://www.informatimago.com/
A bad day in () is better than a good day in {}.

------------------------------------------------------------------------------
Live Security Virtual Conference
Exclusive live event will cover all the ways today's security and 
threat landscape has changed and how IT managers can respond. Discussions 
will include endpoint security, mobile security and the latest in malware 
threats. http://www.accelacomm.com/jaw/sfrnl04242012/114/50122263/
_______________________________________________
clisp-devel mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/clisp-devel
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.