massimo wrote:
> Hi,
>
> If I have a global:
> (defparameter *test* (function-name))
<g> I was going to ask why function-name was in parens then realized you
meant that the way I use <>s:
(defparameter *test* <function-name>)
or sometimes I just
(defparameter *test* 'my-function)
>
> and few other functions that use *test* to perform other operations with
> it. I would like to make a lexical closure so i can get rid of the
> global *test*, which is not very clean and safe option.
Why is not clean and/or safe? Anyway, I am puzzled, you are hardcoding
other functions to look at the *test* globale to find out what function
to call. I guess elsewhere you modify *test* during runtime? You cannot
pass the test function as a parameter? if not, you need a global.
Closures have nothing to do with that.
>
> How would I define the closure and then still use test from other
> functions?
Like I said, you may be ascribing powers to closures they do not have.
Or do you mean...
> How do I group multiple functions that share the same
> variable under 1 closure??
(let ((test-function :undefined))
(defun set-test-xxx (fn-name)
(setf test-function fn-name))
(defun get-test-xxx ()
(assert (not (eq test-function :undefined)))
test-function))
hth, ken
--
Cells: http://common-lisp.net/project/cells/
"Have you ever been in a relationship?"
Attorney for Mary Winkler, confessed killer of her
minister husband, when asked if the couple had
marital problems.
massimo wrote:
> ok.
>
> so if i have this global *test*, which is used in other functions, how
> can i get rid of the global and use lexical variable using let??
>
> (defparameter *test* (another-function-call))
>
> this is your solution:
>
> (let ((*test* (another-function-call))
> ;; processing
> ;; calls to other functions referencing *game*>
> ) ;; end of let
No this was my solution:
(let ((test-function :undefined))
(defun set-test-xxx (fn-name)
(setf test-function fn-name))
(defun get-test-xxx ()
(assert (not (eq test-function :undefined)))
test-function))
And that is wildly different from what you offered as my solution (I am
not pissed, I just mean "this is not a quibble, you are waaaay off if
that is how you remember what I wrote"). What you offered binds *test*,
which is still a special variable unless you delete the defparameter,
and i that case you should not bracket the name with asterisks. I
created a local variable over which two functions closed.
Let's just go with my solution. Then...
>
>
> how would I use closure to include all functions that use *test*?
> let's say that this is one of the function that uses *test*:
>
> (defun function-name ()
> <do-something-with> *test*)
...this gets rewritten:
(defun function-name ()
(<do-something-with (get-test-xxx)))
By the way, I asked but you have not answered: why is the global a
problem? For example, you might say "I want to handle dozens of games at
once." But if you do not answer anything, it makes it a little hard to help.
I think, btw, that we are headed for The Unspeakable Glory of Special
Variables:
(defun process-game (game)
(let ((*game* game))
<various amounts of code to process the game,
including calls to functions that reference *game*>))
Now all your functions referencign game, when visited in a /dynamic/
call tree, are guaranteed to be referencing the same game. You can even
poll a socket, decide to handle a different game, and then call
'process-game on that game instance. During that call, all functions
will see the second game instance, and once the nested (recursive) call
to process-game ends and the call tree working on game one resumes
(wherever it got interrupted by the polling) all references to *game*
will again return game one.
Yes, global variable in most languages are Evil. But CL has a way to let
you have the benefit (not having to pass some key, prominent value all
over the place) without the hazards/hassles.
ken