Subject: Re: Equivalent of C's "global/static" variables
From: rpw3@rpw3.org (Rob Warnock)
Date: Wed, 18 Jan 2006 01:36:06 -0600
Newsgroups: comp.lang.lisp
Message-ID: <z-adnUcxXvR7clDenZ2dnUVZ_sCdnZ2d@speakeasy.net>
Duane Rettig  <duane@franz.com> wrote:
+---------------
| Brian Downing <see-signature@lavos.net> writes:
| > bradb <brad.beveridge@gmail.com> wrote:
| >> I am currently, in Lisp, surrounding both functions with a let:
| >> (let ((p1 nil) (p2 nil))
| >> (defun update (x y) ...)
| >> (defun draw ()...))
| >
| >> Are there downsides to encapsulating multiple functions with a LET?
| >
| > Most implementations will not let you compile UPDATE and DRAW if the
| > LET was not itself compiled.
| 
| Yes, this is because the standard specifies undefined behavior for
| some non-null lexical environments, especially the kind which a
| LET form usually creates.
| 
| >  This is a bit of a pain from a REPL.
+---------------

But it *can* be done, even with CMUCL, albeit indirectly (see below).

+---------------
| >  CMUCL at least says
| > "#<Interpreted Function UPDATE {480245C1}> was defined in a non-null
| > environment."
| 
| This message, however, suggests a bug in CMUCL - [not allowing MACROLET]
...
| ...should in fact work.  Perhaps they've fixed it now, but the versions
| of cmucl I try out from time to time don't handle this; apparently
| they refuse to compile any interpreted function within a non-null
| lexical environment (which is not what the spec allows).
+---------------

As was suggested in another branch, if the LET itself were compiled
then everything should "just work". So perhaps we CMUCL REPL users
should add the following macro to our toolboxes:  ;-}  ;-}

    cmu> (defmacro compile* (&body body)
	   `(funcall (compile nil (lambda () ,@body))))

    COMPILE*
    cmu> (compile*
	   (let ((p1 nil) (p2 nil))
	     (defun update (x y) (setf p1 x p2 y))
	     (defun draw () (list p1 p2))))
    ; Converted UPDATE.
    ; Converted DRAW.
    ; Compiling LAMBDA NIL: 
    ; Compiling Top-Level Form: 

    DRAW
    cmu> (describe *)

    DRAW is an internal symbol in the COMMON-LISP-USER package.
    Function: #<Closure Over Function DRAW {58A06521}>
    Function arguments:
      There are no arguments.
    Its defined argument types are:
      NIL
    Its result type is:
      LIST
    On Tuesday, 1/17/06 11:22:34 pm PST it was compiled from:
    #(#'(LAMBDA # #))
    Its closure environment is:
    0: #<Value Cell NIL {58A0650F}>
    1: #<Value Cell NIL {58A06507}>
    cmu> (draw)

    (NIL NIL)
    cmu> (update 11 22)

    22
    cmu> (draw)

    (11 22)
    cmu> (describe 'draw)

    DRAW is an internal symbol in the COMMON-LISP-USER package.
    Function: #<Closure Over Function DRAW {58A06521}>
    Function arguments:
      There are no arguments.
    Its defined argument types are:
      NIL
    Its result type is:
      LIST
    On Tuesday, 1/17/06 11:22:34 pm PST it was compiled from:
    #(#'(LAMBDA # #))
    Its closure environment is:
    0: #<Value Cell 22 {58A0650F}>
    1: #<Value Cell 11 {58A06507}>
    cmu> 


-Rob

-----
Rob Warnock			<rpw3@rpw3.org>
627 26th Avenue			<URL:http://rpw3.org/>
San Mateo, CA 94403		(650)572-2607