Re: Building STk on HP-UX

From: Erick Gallesio <>
Date: Tue, 14 Feb 1995 11:34:48 +0000

> Basically, the code bound to, say, a button widget that is to be executed when
> the button is pressed, is evaluated in the global environment.
> I want to be able to control the environment in which it is evaluated; I'd
> like to be able to do, for instance
> (let* ((foo 1)
> (bar 2))
> (button "Frob" :command (lambda ()
> (frob foo bar))))
> When I try it I get
> *** Read from string error:
> bad # syntax: "#"
> because STk cannot deal with the "#[closure 0xfdo92c]" it gets back from Tk.
> My question is, how hard would it be to support closures as widget actions?
> If it's a GC problem (in that the lambda might get collected before it's
> called, because Tk doesn't cooperate in GC) then why can't a thin layer of
> glue code notice that this closure is being bound to that button, and hold
> onto a live pointer so it won't be collected? It seems to me (though I
> haven't dived into the code to see) that it would not be hard for the
> interpreter evaluating the "string" of code from Tk to notice that it starts
> "#[closure..." and do the right magic closure-invoking stuff. Yes? No?

This glue code exists and is accessible through the adress-of primitive.
Your code should be written:
         (let* ((foo 1)
                 (bar 2)
                (callback (lambda () (frob foo bar))))
              (button ".frob" :command (address-of callback)))

Note that you have to bind your closure before crating the button to avoid GC
problems (i.e. Tk-commands capture thir environment, so binding the closure
"callback" will protect the closure agains GC). This is explained in the
adress-of primitive documentation I think.

I admit that this is a little bit weird and I hope to remove this constraint
in a future release.

                -- Erick
Received on Tue Feb 14 1995 - 11:36:32 CET

This archive was generated by hypermail 2.3.0 : Mon Jul 21 2014 - 19:38:59 CEST