Standard documentation appears at http://www.purl.org/tcl/home/man/tcl8.4/TclCmd/interp.htm ---- Many newcomers to interps seem to understand them as a variant on object orientation, in that they provide a kind of encapsulation, inheritance, and ... The historical origin of interp was in "safe interpretation", that is, a mechanism for secure code evaluation. At a high level, this is what Java provides with its "sandbox", although far less flexibly and perhaps less securely. ---- [Jeffrey Hobbs] observes that, though several books ''mention'' interps, none really explains them adequately; they don't "go into enough detail for people to really understand what magic can be done. The power and flexibility of slave interpreters in Tcl is YA large advantage over other languages." (for more on Tcl's advantages, see "[How Tcl is special]") ---- [AK]'s [fmail] package nicely employs slave interpreters. ---- [Mark Roseman]'s 1996 paper [http://www.usenix.org/publications/library/proceedings/tcl96/roseman.html] on [TeamWave] explains specific interp benefits of encapsulation and security. In a conversation in mid-2001, Mark summarized, "But if you have what might be considered very coarse-grained objects that really could be conceptualized as self-contained applications, multiple Tcl interpreters are definitely an option to consider." ---- "[exit in slave interpreter]" covers a specific trickiness in interp management. ---- tkcon [http://tkcon.sourceforge.net/] is an enhanced Tk console built in pure Tcl/Tk. It makes use of slave interpreters to isolate the user environment from the tkcon environment, except through certain special commands. It makes use of many tricks with interpreter slaves. ---- Another occasionally hazardous way to think about interps is as a programming model for handling a very weak form of concurrency. Interps originated as "safe interpreters" in the [agent] work of such people as [Marshall T. Rose], ... [[Explain insights from http://groups.google.com/groups?hl=en&frame=right&th=d0e2fc9300bdbad ]] ---- '''interp alias''' can be used to do amazing things inside the same interpreter (see [Custom curry]): interp alias {} = {} expr interp alias {} -> {} set res -> [= $x+1] so assignment to a default variable can be sugared (see [Euro converter] for an application) [RS]. This tastes like sweet curry: proc curry {new old} {eval [list interp alias {} $new {}] $old} curry -> {set res} An example of very practical use, when interactively debugging: interp alias {} ? {} set errorInfo Then a simple question mark shows you the full error stack. ([RS]) Be aware that ''interp alias'' hides existing commands without complaining, so better check with ''[info] commands'' before that the name isn't taken yet. ---- Maybe this belongs on it's own page but... I've been playing around with sharing or linking variables between interpreters. I've got something that works in my very limited testing. I'll post it here because it may be useful to someone else and so I might get some feedback. -- [CLN] # shareVar.tcl -- # # Allow sharing (or linking) of variables between interpreters. # # # Copyright 2002 Pinebush Technologies, Inc. # # Exported procs: # sharevar::sharevar - Sets up link between interpreters # # Private procs: # sharevar::TraceVariable - Updates other interpreter when # variable is written. # # Example: # # Create a slave interpreter # interp create a # # # Share a variable (common name) # sharevar::sharevar {} foo a foo # # # Create a namespace to play with. # namespace eval X { # variable X # } # # # Share a variable (different name and namespace). # sharevar::sharevar {} X::X a x # # # Create another slave # interp create b # # # Share a variable between them # sharevar::sharevar a a b b # # # Global data: # None. # #----------------------------------------------------------------------- package provide sharevar 0.1 namespace eval ::sharevar { namespace export \ sharevar } #======================================================================= # Public procs #======================================================================= # sharevar::sharevar -- # # Make varName a shared variable in sourcePath and targetPath. # # Arguments: # sourcePath - First interpreter to link # sourceVar - Variable in sourcePath to link to # targetPath - Second interpreter to link # targetVar - Variable in targetPath to link to # # Results: # Updates to sourceVar in sourcePath will change targetVar in targetPath # and vice versa. # # If sourceVar exists, targetVar is set to its value. If sourceVar # does not exist, and targetVar does, sourceVar is set to # targetVar's value. # proc sharevar::sharevar { sourcePath sourceVar targetPath targetVar} { foreach fromInterp [list $sourcePath $targetPath] \ fromVar [list $sourceVar $targetVar] \ toInterp [list $targetPath $sourcePath] \ toVar [list $targetVar $sourceVar] \ { # Give the interpreter the sharing proc interp alias $fromInterp shareTraceVariable \ {} [namespace code TraceVariable] # Use that command when the variable is written. set traceCmd [list shareTraceVariable \ $fromInterp $fromVar $toInterp $toVar] interp eval $fromInterp \ [list trace variable ::$fromVar w $traceCmd] # WUZ - need to clean up later, remove trace } # Initial synchronization if { [interp eval $sourcePath info exists $sourceVar]} { TraceVariable $sourcePath $sourceVar $targetPath $targetVar } elseif { [interp eval $targetPath info exists $targetVar] && ! [interp eval $sourcePath info exists $sourceVar]} { TraceVariable $targetPath $targetVar $sourcePath $sourceVar } else { # Neither exists, first write will sync. } } # sharevar::sharevar # #======================================================================= # Private procs only below this line #======================================================================= # sharevar::TraceVariable -- # # React to change in one interpreter by updating the other. # # Arguments: # fromInterp - Interpreter where value changed # fromVar - Variable in fromInterp which changed # toInterp - Interpreter to update # toVar - Variable in toInterp to update # args - (IGNORED) Added by the variable trace # # Results: # toVar is updated # proc sharevar::TraceVariable { fromInterp fromVar toInterp toVar args } { puts stderr [info level 0] set value [interp eval $fromInterp set ::$fromVar] interp eval $toInterp [list set ::$toVar $value] } # sharevar::TraceVariable ---- Let's say some of this in a different way. interp aliases are indeed powerful, but they need not seem so mysterious as we sometimes allow them to be. [DKF] illustrates that they can serve as an elegant "light-weight" way to implement related [proc]-s in a unified fashion [http://groups.google.com/groups?q=telnet_interact+fan+group%3acomp.lang.tcl*&hl=en&selm=3CDA3DB7.E61A0016%40cs.man.ac.uk&rnum=1] . DKF is also the one who explained, "What aliases do, apart from moving between interps, is let you convert [[a b c]] into [[P Q R b c]]." "[Custom curry]" has more on the subject. ---- ''[DKF]:'' You can do some cool things with '''interp''' (and other Tcl commands) to do things like dynamic downloading of code over the 'net... package require Tk package require http pack [frame .f -container true] set i [interp create -safe] ::safe::loadTk $i -use [winfo id .f] proc http_source {interp base filename} { regsub {.*:/*} $filename {} trimmed set token [http::geturl $base$trimmed] set script [http::data $token] http::cleanup $token $interp eval $script } $i alias source http_source $i $YourBaseUrl $i expose exit; # WE DON'T MIND PEOPLE QUITTING THE APP! http_source $i $YourBaseUrl InitApp.tcl vwait forever The above code probably needs polishing up... :^) ---- [RS] has been playing with interps too: % interp create foo foo Sugar to avoid the word eval: % interp alias {} foo: foo eval foo: % foo: set bar 1 1 % foo: set bar 1 Oops - it still is an eval, so needs one list layer more: % foo: proc bar {x} {string toupper $x} wrong # args: should be "proc name args body" % foo: {proc bar {x} {string toupper $x}} % foo: bar hello HELLO By nature interps offer best encapsulation - their master can introspect them of course. On the other hand, they're probably more heavyweight than namespaces, and would have to repeat all package loading where required. ---- [Tcl syntax help] - [Arts and crafts of Tcl-tk programming] [Category Command]