Arising from a discussion (on [Tcl chatroom] about the [denotational semantics] of Tcl, the concept of ''tcl-null'' was proposed. [MS] offers this pragmatic approximation of tcl-null: set cmds [info command] rename catch _catch rename rename _rename foreach c $cmds {_catch {_rename $c {}}} _rename _catch {} _rename _rename {} but notes that [namespace]s also have to be cleaned up. - [RS]: You can have that, and all of the above: a brain-dead interpreter that understands no command any more, with namespace delete :: '''tcl-null Game''' Starting with this as a base, the game is to come up with minimal subset of built-in commands which provide a useful (if not exactly usable) language from which many of the facilities of tcl can be built. [CMcC] Sat 23rd Sep 2006. One such set is [apply] [set] [uplevel] [list] [lindex] [return]. This resembles the minimal set of lisp functions necessary to construct classic lisp: (eval) (cond) (lambda) (quote) (car) and (cdr) from which McCarthy could construct/emulate classic-lisp. - [RS]: [list] is not needed in the set of fundamentals - the Tcl parser itself builds a list of the arguments before calling a command, so proc list args {return $args} The above set constructs [if] as: proc if {c t f} {uplevel [lindex [list $t $f] [uplevel expr $cond]]} The construction of [proc] or a near approximation is left as an exercise for the reader. :) [MS] says it can be done. I have no idea how. - [RS] Allowing for an extra [interp] command, [proc] is a special case of [apply]: proc f x {expr {$x*$x}} is equivalent to interp alias {} f {} apply {x {expr {$x*$x}}} [dgp] pointed out the need for [return] and also adds if your aim is to get back to the full Tcl built-in set, you'll need [trace] This raises the question of the aim of the tcl-null game. I think there are three possible games: 1. to construct a useful set 2. to construct a usable set 3. to construct the full Tcl built-in set. [RS] 2006-09-23: If we did not base all looping on recursion (which has its limits), one loop construct would be needed in the fundamental set. [while] can cover the functionality of [for] and [foreach] as well: foreach el $list {puts $el} can be rewritten as set i 0 while {$i<[llength $list]} { puts [lindex $list $i] incr i } Some more experiments: lappend list $el can be done, for the single element case, as set list "$list {$el}" Cast into a proc, that's (slightly buggy, with a leading " " when [Lappend]ing to {}): proc Lappend {_list args} { set it [uplevel 1 set $_list] uplevel 1 "set $_list {$it $args}" } [lindex] is not fundamental. Here is a replacement which uses a recursive helper function (which in turn uses ''[uplevel] 0'', the replacement for [eval], as I don't have [{*}] here): proc Lindex {list index} { uplevel 0 nth $index $list } proc nth {n {head {}} args} { if {$n==0} {return $head} if {$n>0} {uplevel 0 nth [expr {$n-1}] $args} } BTW, classic [lindex] (with only a single index) is redundant in Tcl itself: lindex $list $index could always be written as a simple special case of [lrange]: lrange $list $index $index [Lars H]: Not quite, RS -- you also have to remove a level of list-quoting. It's more like uplevel 0 {set ""} [lrange $list $index $index] ---- See also * [If we had no if] * [If we had no variables] (who needs [set] when we have [proc]?) * [Combinator engine] (build a Turing-complete language without variables, and without named functions, and without a lot of other things.) ---- [[ [Category Concept] ]]