Updated 2008-07-16 12:25:20 by LV

Richard Suchenwirth 2007-09-28 - Since Tcl 8.5 gives us the apply command, it is possible to remodel part (or even all?) of the proc functionality in its terms, in a devilish cascade of interp alias and apply:
 interp alias {} proc {} \
    apply {{name argl body} {interp alias {} $name {} apply [list $argl $body]}}

We define an alias named proc, which overrides the built-in command, to apply to a {name argl body} triplet a codelet that defines an alias name to apply to the argl the body. Whew...

Testing (should print 49/a-b-c, did for me):
 proc square {x {y ""}} {if {$y eq ""} {set y $x}; expr {$x*$y}}
 proc foo args {join $args -}

 puts [square 7]/[foo a b c]

Tcl 8.4 implementation posted by kruzalex
   proc apply {fun args} {
     if {[llength [lindex [info level 0] 1]] != 2} {
       error "cant interpret \"[lindex [info level 0] 1]\" as an anonymous function"
     }
     bind_vars [lindex [info level 0] 1 0] [lrange [info level 0] 2 end]
     eval [lindex [info level 0] 1 1]
   }
   proc bind_vars {argl args} {
     set counter 0
     foreach item $argl {
	   set var $item
	   set val [eval lindex $args $counter]
	   if {[llength $var]==2} {
	   set vars [split $var]
	   if {[lindex $vars 1] eq {""}} {
	   uplevel 1 [list set [lindex $vars 0] ""]
       } else {
	   uplevel 1 [list set [lindex $vars 0] [lindex $vars 1]]
       }
       } else {
       uplevel 1 [list set $var $val]
       }
       incr counter
     }
   }
   interp alias {} proc {} \
   apply {{name argl body} {interp alias {} $name {} apply [list $argl $body]}}

   proc square {x {y ""}} {if {$y eq ""} {set y $x}; expr {$x*$y}}
   puts [square 7]

See also If we had no if - If we had no variables