if 0 {[Richard Suchenwirth] 2005-03-16 - Here's a little experiment in [OO] using the [Jim] feature that procs and [lambda]s can have a "closure" (a set of static variables) associated. (Note that this code does not run on regular Tcl interpreters - use [Jim] instead!) This way, the only physical location of an object is its lambda - rename it away as destructor. No namespaces needed (or possible in Jim ;^) Jim's lambdas are just [proc]s with a generated name, but they will be garbage-collected when no longer used. Here's a "constructor" the hard (bare-bones) way:} proc Account args { lambda {method args} {{balance 0}} {eval Account'$method $args} } if 0 {Alternatively, if you want to use more than one class, here's factoring out the generic part. It also adds an introspection method for the names of instance vars. Other methods that all classes shall have, can be placed here too:} proc class {name instvars} { proc $name args \ [list lambda {method args} $instvars "eval $name'\$method \$args"] proc $name'vars {} [list return [lmap i $instvars {lindex $i 0}]] } #-- Let's re-create a first class, the usual bank account, with one instance variable: class Account { {balance 0} } #-- Bare-bone methods ([proc]s) need to [upvar] the instance vars they need: proc Account'deposit amount { upvar 1 balance balance set balance [+ $balance $amount] } #-- Here's a wrapper to implicitly do those [upvar]s in methods: proc method {class name argl body} { proc $class'$name $argl "foreach i \[\[self] vars] {upvar 1 \$i \$i} \n$body" } #-- Methods can be written slicker now: method Account see {} {set balance} method Account withdraw amount { if {($balance-$amount)<0} {error "can only withdraw $balance"} set balance [- $balance $amount] puts now:[[self] see] } if 0 {"Who am I?" is a deep philosophical question. Inside methods, it's easily answered:} proc self {} {lindex [info level -2] 0} if 0 {Now testing: set a [Account] puts a:$a $a deposit 100 puts "deposit 100 -> [$a see]" $a withdraw 40 catch {$a withdraw 1000} res puts $res shows on stdout a:.00000000000000000000> deposit 100 -> 100 now: 60 can only withdraw 60 Conclusion: For years, I wondered what exactly [closures] are. After seeing their simplicity and power in this example, I strongly advocate that Tcl adopts them too, for [proc]s. ---- [SS] Very nice! It seems to me a very natural hack to try to implement objects via closures. Also your way to do the dispatch is impressive ;) ---- [Arts and crafts of Tcl-Tk programming] | [Category Object Orientation] | [Category Jim] }