if 0 {Richard Suchenwirth 2004-05-27 - Transparent OO for Tcl, or TOOT for short, is a very amazing combination of Tcl's concept of transparent values, and the power of OO concepts. NEM represents objects as a list of length 3: the class name (so much for "runtime type information" :-), a "|" as separator and indicator, and the values of the object, e.g.
{class | {values of the object}}
With my short attention span, I didn't read all his code, and couldn't get its test to run because I have no dict command available, but still the idea kept haunting me of how I could go tooting too...
As a late night project, here's my little take on toot in a nutshell. Classes in C++ started out as structs, so I take a minimal struct as example, with generic get and set methods. }
namespace eval toot {namespace export get set} proc toot::struct {name members} { namespace eval $name {namespace import -force ::toot::*} #-- membership information is kept in an alias: interp alias {} ${name}::@ {} lsearch $members }
#-- The two generic accessor functions will be inherited by "struct"s
proc toot::get {class value member} { lindex $value [${class}::@ $member] }
if 0 {The set method does not change the instance (it couldn't, as it sees it only "by value") - it just returns the new composite toot object, for the caller to do with it what he wants:}
proc toot::set {class value member newval} { ::set pos [${class}::@ $member] list $class | [lreplace $value $pos $pos $newval] }
if 0 {For the whole thing to work, here's a simple overloading of unknown - see Let unknown know. It augments the current unknown code, at the top, with a handler for
{class | values} method args
patterns, which converts it to the form
::toot::(class)::(method) (class) (values) (args)
and returns the result of calling that form:}
proc know what {proc unknown args $what\n[info body unknown]}
#-- Now to use it (I admit the code is no easy reading):
know { set first [lindex $args 0] if {[llength $first]==3 && [lindex $first 1] eq "|"} { set class [lindex $first 0] return [eval ::toot::${class}::[lindex $args 1] \ $class [list [lindex $first 2]] [lrange $args 2 end]] } }
#-- Testing: we define a "struct" named foo, with two obvious members:
toot::struct foo {bar grill}
#-- create an instance as pure string value
set x {foo | {hello world}} puts [$x get bar] ;# -> hello (value of the "bar" member)
#-- Modify part of the foo, and assign it to another variable:
set y [$x set grill again] puts $y ;# -> foo | {hello again}
if 0 {Struct-specific methods can be just procs in the right namespace, as I've learned from GPS. The first and second arguments are the class (disregarded here, as the dash shows) and the value, the rest is up to the coder. This silly example demonstrates member access and some string manipulation: }
proc toot::foo::upcase {- values which string} { string toupper [lindex $values [@ $which]]$string } puts [$y upcase grill !] ;# -> AGAIN!
if 0 {These have just been my first steps into toot water - I think there's much more potential in there, offering both extreme power and simplicity... and fitting better into the Zen of Tcl than any other OO games I've played so far.
Neat, but wouldn't it be better to help NEM take his TOOT code further, so all the best ideas get to amplify each other? Assuming Neil is looking for input at this early stage of course - I have no idea... -jcw RS: We certainly should seek how to unify these attempts. It's just that after a long day of work, I wanted to build something little but cute from scratch, rather than worrying about integration... :)
NEM Neat indeed. And, yes I am looking for input. I intend to flesh toot out into a useable package as much as I can, but I am always open to suggestions. The idea has interesting potential, but could do with some refinement. The page I created was to demonstrate the idea, and I'm sure there will be many changes before it reaches maturity, so there is plenty of scope for experimentation. From getting the syntax right, to thinking about such things as efficiency (I've been playing with some code involving the K combinator to try and avoid copy-on-write, as much as possible). RS certainly has a knack for distilling ideas to their basic components, which is much appreciated. Much to think about here. I'm currently looking for papers on pure-functional object systems (as toot is at its heart - no side-effects), to see what others have done.