Re: A different design for closures (was: What does Tcl lack?)
From: antirez (antirez_at_remove.gmail.remove.com)
Date: 02/23/05
- Next message: David N. Welton: "Re: What does Tcl lack?"
- Previous message: Miroslaw Osys: "Re: What does Tcl lack?"
- In reply to: Bruce Stephens: "Re: What does Tcl lack?"
- Next in thread: antirez: "Re: A different design for closures"
- Reply: antirez: "Re: A different design for closures"
- Reply: antirez: "Re: A different design for closures"
- Reply: Robert Seeger: "Re: A different design for closures"
- Messages sorted by: [ date ] [ thread ] [ subject ] [ author ]
Date: Wed, 23 Feb 2005 08:47:46 GMT
Bruce Stephens wrote:
> sigzero@gmail.com writes:
>
> [...]
>
>
>>So what exactly does Tcl lack? I am not talking "OO" stuff, because
>>I can take or leave that. Fundamentally in the Tcl language itself
>>is more of what I am asking about.
>
>
> Closures, mostly. And if it had closures, then lambda. And
> presumably proper lexical scoping would then make sense. That's not
> in 8.5, and I'd guess the changes that seem to me to be necessary
> would be too radical for closures ever to get into Tcl, so I'm not
> holding my breath for them to appear in 9.
From time to time there is this discussion about adding closures to
Tcl, but usually the idea is to make they similar to languages like
Scheme, i.e. closures with lexical scoping. My opinion is that this is
very hard to do with Tcl, and even not in the spirit of the language.
In a Tcl program, what part of a procedure body is a variable is not
defined until execution, for example:
set a 10
closure {x} {
incr a
}
Then I define 'incr' to be like 'puts', and 'a' is no longer a variable.
It was already suggested that in Tcl closures should not have any kind
of creation-time resolution rule, but that the context where they are
defined should be captured as a whole, and used when the closure is
running to resolve "unbound symbols" (that are better referred as
variables and procedures not otherwise defined during execution in
Tcl slang). Still there is the problem that to similuate the lexical
scoping you have to take *references* to the shared environment, so that:
set a 10
set foo [closure {x} {
incr x
}]
set bar [closure {x} {
incr x
}]
$foo ;# -> 11
$bar ;# -> 12
foo and bar will share the same 'a'.
I think this is a all to complex and UnTclish, so I tried to design a
new semantic for closures.
The semantic is based on a single command [closure], that can set/get
closure variables in the scope of the current procedure, together with
a minimal change in the [proc] and [lambda] command (I know we don't
have lambda... but still there is a way Tcl users already think about
it and should change).
Bisically, to set a closure variable, there is to write the following
command:
closure set x 10
this will set 'x' inside the closure of the current procedure. This 'x'
will be persistent accross different calls of this procedure, and all
this environment will be destroied once the procedure itself is
destroied. The procedure can test for the existence of a closure
variable with [closure exists x], can get the value with [closure get x]
and so on.
The change required to the [proc] command, is that it can take an
optional further argument, that's a Tcl list of key/value pairs used
to inizialize the closure at procedure creation time.
so:
proc foo {} { .... } {x 10 y 20}
will create the procedure foo with x=10 and y=20 inside the closure.
The same for lambda.
The following is an example of procedure that returns a progressive
integer number every time it's called:
proc counter {} {
if {![closure exists x]} {
set x 0
}
set x [closure get x]
closure set x [expr $x+1]
return $x
}
Of course it's better to use the optional argument
of proc and write it as:
proc counter {} {
set x [closure get x]
closure set x [expr $x+1]
return $x
} {x 0}
Of course for this to be very useful, lambda it's needed.
This version of lambda, like proc, should accept the optional
argument to initialize the closure. This is an example:
proc createAdder {x} {
lamba {y} {expr $y+[closure get $x]} [list x $x]
}
set f [createAdder 5]
$f 10 ;# -> 15
I think that this design can do everything lexical scoping is able to
do, but with a command-based interface that plays better with Tcl.
This kind of closures will be added into the Jim interpreter, a
small footprint Tcl interpreter I'm writing. This interpreter is already
working and I'll be happy to send a preview tar.gz to interested
people (the license is the APACHE2, so it's possible to use Jim in
commercial projects if needed).
Regards,
Salvatore
- Next message: David N. Welton: "Re: What does Tcl lack?"
- Previous message: Miroslaw Osys: "Re: What does Tcl lack?"
- In reply to: Bruce Stephens: "Re: What does Tcl lack?"
- Next in thread: antirez: "Re: A different design for closures"
- Reply: antirez: "Re: A different design for closures"
- Reply: antirez: "Re: A different design for closures"
- Reply: Robert Seeger: "Re: A different design for closures"
- Messages sorted by: [ date ] [ thread ] [ subject ] [ author ]
Relevant Pages
|