Dear German,
> Granted, I am not experienced in objects, although a couple of years
> ago I went back to a local community college for a nice Java course
> where I learned about OO and concepts like Inheritance and
> Encapsulation. So, needless to say, I was able to understand itcl
> right away and I am having the hardest time understanding xotcl.
> So, I gather that xotcl seems more versatil (and hence more
> powerfull?)...is [incr tcl] good enough?
> [incr tcl] seems easy (to me, with my Java knowledge) to grasp and
> program. How does xotcl compare?
itcl is more or less the a mapping of the basic concepts of C++ to
Tcl. If you are familiar with C++ and Java, there is not much new
to learn.
The basic object model of XOTcl is different. While the object model
of C++ is class based and says_ "look at the classes, and you know
exactly what your objects are", the basic object model of XOTcl is
instance based, and the relation between objects and classes (and
between classes) are relations in the sense of associations.
This basic concept has the following consequences in XOTcl:
- all state is kept in objects (instance variables)
- classes are objects (can contain variables), with two additional
properties
* classes are manager objects controlling the life-cycle of
their instances (allocate, init, destroy), classes know their
instances and vice versa
* classes provide methods (behavior) for their instances
- the relation between an instance and its class is a relation that
can be changed any time, objects can be re-classed (when an
instance of a car crashes hard against a tree, its class and
behavior changes)
- The relation between classes can be changes as well
(e.g. the superclass relation can be changed)
In XOTcl, everything can be changed dynamically, everything is defined
incrementally, while in itcl, one needs a complete class
definition/declaration. Look at the following example:
Class create C
C create c1
The first statement creates a class named C, the second statement
creates an instance of this class named c1.
Now, we define a specify a specific behavior for class C:
C instproc foo {} {
puts "hello world"
}
This method can be used for instance c1:
c1 foo
What have we done now? Firstly, we have created an object c1, and
later, we provided a method for its class C. Every XOTcl statement can
change the behavior of existing objects. This might sound scary for
someone seeking protection in OO. However, this flexibility is
essentially the same that Tcl provides.
----
Let us look at the classical Stack example, and see a few variants of
the theme.
Firstly we define a stack very similar style as an ensemble in Tcl 8.5
(a namespace, where the name of the namespace is a command).
We define an object s0, which is a namespace containing a few Tcl
procs (push, pop) and the Tcl variable things:
Object create s0
s0 set things ""
s0 proc push {thing} {
my instvar things
set things [concat [list $thing] $things]
return $thing
}
s0 proc pop {} {
my instvar things
set top [lindex $things 0]
set things [lrange $things 1 end]
return $top
}
Now we can use the stack s0
s0 push a
s0 push b
s0 push c
puts "[s0 pop] [s0 pop] [s0 pop]"
The last statement prints "c b a". This example showed, how to define
object-specific behavior.
----
In many situations, we want to have many stacks, therefore we define a
class Stack generalizing from the basic behavior:
Class create Stack
Stack instproc init {} {
my set things ""
}
Stack instproc push {thing} {
my instvar things
set things [concat [list $thing] $things]
return $thing
}
Stack instproc pop {} {
my instvar things
set top [lindex $things 0]
set things [lrange $things 1 end]
return $top
}
This class Stack can be used as follows
Stack create s1
s1 push a
s1 push b
s1 push c
puts "[s1 pop] [s1 pop] [s1 pop]"
So far, there is nothing special in this Stack
definition in XOTcl.
Now the Stack s1 is empty.
What happens, when we do one more pop?
puts [s1 pop]
This statement returns an empty string. This means that the definition
is unsafe, since it can't distinguish between a pop of an previously
pushed empty element and a pop with the empty stack.
----
Let us define Safety by a separate class
Class create Safety
Safety instproc init {} {
my set count 0
next
}
Safety instproc push {thing} {
my incr count
next
}
Safety instproc pop {} {
if {[my set count] == 0} then { error "stack empty!" }
my incr count -1
next
}
The class Safety maintains a counter to keep track the number of
stacked elements (certainly, there are other ways to implement Safety
as well).
What's new is that we can mix in Safety into the Stack definition
Stack s2 -mixin Safety
s2 push a
s2 push b
s2 push c
puts "[s2 pop] [s2 pop] [s2 pop]"
puts [s2 pop]
If we run these statements, an error is generated. What have we done?
We have now an unsafe stack s1 and a safe stack s2. The s2 has safety
mixed in. Safety is a per-object mixin for object s2. The per-object
mixin shadows (overloads) the methods of the stack. Every method
in Safety has a "next" statement, that invokes the shadowed methods.
Certainly, it is possible to remove Safety dynamically (or after some
testing), or to provide other mixins for tracing, etc. Mixins are a
powerful means to compose behavior.
----
Well, this was only the first glimpse at XOTcl. XOTcl distinguished
between per-object mixins and per-class mixins, it provides filters to
catch arbitrary calls), all these relations can be altered on the
fly. Since most things can change at arbitrary times, XOTcl has some
self-awareness to figure out its current state and relations (through
introspection).
One can say for sure that XOTcl is more flexible and dynamic than
itcl. Whether this flexibility is wanted or not, is a question that a
programmer has to decide. XOTcl is not a means to constrain a
programmer such he can do "only the right things" (no programming
language can avoid bad programs) but a means to empower a programmer
to do complex things quite easy.
>
> I'm just having a hard time separating Objects and Classes, each with
> its own definitions and methods, etc. By the way, the soccer team
> example did not include anything on Objects, everything was
> Classes...so, I was up for a surprise when they started to talk about
> Objects in the same way they did about Classes. The following
> statements hit the nail right on the head for me:
Does the text above help? Please let me know when you find sentences or
concepts hard to understand and
not explained enough. Any suggestions are welcome.
-gustaf neumann