Version 5 of Let's think about "callspaces"

Updated 2004-12-28 10:49:29 by lwv

This is a thought experiment about a refinement for Tcl... -jcw

Unix has pipes, and named pipes. The first represents the concept of pushing data in sequence into one end, and getting it out again at the other end. I.o.w. a FIFO, very useful for inter-process communication, particularly due to its convenient syntax in command shells (interactive and in scripts). The second item - named pipes - is a method that Unix supports that provides a file system name interface to a particular pipe data structure. Applications can open it, add or read data, and then close it. It provides a path-like interface to pipes, rather than the generic unnamed pipe.

Tcl, like many other languages, has namespaces - a way to keep state in variables/arrays under a path-like prefix.

What if we had an unnamed equivalent of namespaces?

The idea is that such a mechanism would represent the call stack. There are a number of OO extensions which already map namespaces to objects. This makes it easy to access all object-state as namespace variables. Let's just for the sake of brevity call the unnamed equivalent of a namespace a "callspace".

A callspace is like a stack frame. When a proc is called, a new callspace is created, all arguments are imported and given appropriate names, and the body of the proc is executed in the context of that callspace. On return, the callspace is discarded again. Local variables in a proc are simply the variables in the corresponding callspace. And upvar is a way to access the caller's callspace, no more no less. The "info level" command could be re-written.

In fact, a callspace is a namespace. It just isn't created in the usual way, it comes and goes with each proc call. A deeply nested proc call corresponds to a deeply nested series of callspace, I mean namespace, children.

What of callspaces did have some generated name?

Callspaces could be children of say the namespace "::proc". If we invent names for these callspaces, all sorts of things could be simplified. For example, uplevel would be quite similar to "namespace eval <the-unique-name-of-the-callspace> <cmd>".

If callspaces existed, Tcl would have access to its call stack. It might one day become possible to persist a call stack, and continue it later, or elsewhere, or even replay it like a repeatable snapshot. Generators and continuations could be implemented by playing tricks with the Tcl call stack. There are probably some deep issues with the fact that currently the Tcl and C call stack are deeply intertwined. But if this can be resolved, there is no reason why a proc could not "rename its callspace" (i.e. playing very strange tricks with call sites and callers), which is the sort of voodoo one needs to implement full continuations.

Another analogy, similar to this callspace proposal for Tcl, is the Linux "/proc" filesystem, which adds a lot of introspection and control to Linux. File descriptor 1 can be reached via "/proc/[pid]/fd/1", for example. Lots of kernel details are available and can even be adjusted via a plain text interface. It's hard to overstate the impact the /proc pseudo filesystem has had on system development and tools, IMO.

Speaking of pseudo filesystems: the whole concept of namespaces (and callspaces) and that of Tcl's VFS could be revisited. There is a considerable overlap conceptually between the two. Or to put it differently: there is a lot of simplification still waiting to happen, again IMO. But that's a different story...

It is not clear whether exposing callspaces to Tcl in some form would necessarily be incompatible with Tcl as it is today. Nor is it a given that such a change would impact performance badly.

Category Concept