Richard Suchenwirth 2007-04-29 - Of course not. Before 8.5, the concept of
dict - a pure-value key->value mapping - isn't even supported by the
Tcl core (though an extension is available for 8.4).
But playing with
Picol, and as usual pondering how to make things simpler, the following two-third-baked ideas occurred to me:
- A callframe (the set of variables local to a proc, or globals in a namespace) could be done as a dict
- A namespace itself needs one dict for commands, one for its child namespaces, and a callframe. As dicts can be nested, these could all go into one dict again.
- An interpreter again needs as minimum a namespace, and a dict of its slave interpreters
- Variable values can be dicts already, or "scalars" (by which I here mean non-dict values, but they could be lists). Stressing it a bit, a scalar could be implemented as a one-element dict with NULL key.
(Not surprisingly, one finds that the Tcl library uses the same Tcl_HashTable mechanism for all of these things. The entries in some of these hash tables are rather far from being Tcl_Objs, though.)One consequence of this could be to expose more of the internals to the scripting side. For instance, if _C is the commands dict of the current namespace, and _V the same for variables,
dict keys $::_C ;# info commands
dict keys $::_V ;# info globals
so generic
dict routines could replace the more specific ones.
Further phantasizing,
dict set ::_C foo {call MyFooImpl}
could do the registering of a C-coded command, where the generic
call command locates the given symbol in symbol tables, prepares objc/objv and.. calls it.
In a similar vein,
proc definitions can from 8.5 be replaced with
apply {argl body} lambda, so
proc square x {expr {$x * $x}}
could be replaced by
dict set ::_C square {apply {x {expr {$x * $x}}}}
and
info args,
info body could just retrieve the appropriate field from the
apply argument...
What do y'all think?
CL thinks, briefly, "Yes", and looks forward to making time in May 2007 to reply in more detail.
NEM likes it too, but wonders how
call itself is implemented? A special form?
RS Just a C command :) which, by some voodoo currently unknown to me, like in
ffidl but simpler, somehow searches the available symbol tables and assumes a standard signature int(f)(TclInterp* itp, int objc, TclObj* objv ...)
NEM But I mean, if calling a C-coded command is done via the "call" command, then how do we actually invoke the call command itself?
call call call ... MyActualCommand
It surely needs some special treatment?
RS Yes,
call might be an "axiom", and thus special-cased in implementation. I first only thought of exposing commands from extensions, but it might be possible to bootstrap an interpreter with only
call and
dict as initial commands, from a script that registers the others...
DKF: I currently fail to see why
dict would need special treatment. You'd just bootstrap with direct use of
call until such time as you've got
dict in place.
RS: Well, the bootstrapping script would consist of commands like
dict set ::_C append {call TclAppendCmd}
as I currently envision it... but yes, the first command could be
call TclDictCmd set ::_C dict {call TclDictCmd}
:^)
Afterthought:
interp alias in its simple form (two {}s) also seems to be functionally covered by the ::_C dict, e.g.
interp alias {} append {} call TclAppendCmd
Or, put the other way round, the ::_C mapping should cover C commands (with
call), Tcl procs (with
apply), and aliases.