[Xotcl] TIP #257: Object Orientation for Tcl

Gustaf Neumann neumann at wu-wien.ac.at
Wed Sep 28 22:57:54 CEST 2005


Hi everybody,

As others have pointed out the TIP is not easy to swallow and has to
be digested in multiple courses, here is some partly feedback:

 > Some changes will be necessary. Certain aspects of XOTcl syntax are
 > peculiar from a conventional OO point-of-view, and it is deeply
 > unfortunate that a very large number of methods are predefined in
 > the XOTcl base class.

It is common for the conventional OO view to
define common behavior for all Objects in the top-Level class, look
e.g. Ruby, Python, Smalltalk or Java. Certainly the common behavior
changes from language to language. The "deeply unfortunate"
does not seem appropriate.

Can you explain, more about the envisioned object system?
I am confused about the TIP. It says:

 > Standard Metaclasses
 > XOTcl defines two standard Metaclasses, xotcl::Object and 
xotcl::Class....

This is not true, only xotcl::Class is a meta-class.

 > The new core object system will ... be ... based on the metaclasses
 > oo::object and oo::class.

I am not sure whether there is a misconception about xotcl or about
metaclasses in general.  Since the TIP says:

 > meta-classes: These are subclasses of class, which permit more
 > advanced customization of class behaviour.

which is partly true (except, that "class" is a metaclass as well (at
least in xotcl) , furthermore, without a meta-class, one cannot create a 
class.

If the statement in the TIP is true (two basic meta-classes), some of
the class diagrams are wrong. Another consequence is that the proposed
object system can only create classes and no simple objects (every
instance will be able to create new instances).  This is quite
interesting, xotcl can achieve this currently via providing Class as
instmixin on Object. .... But most likely this was not intended.

 > filters: These are constraints (implemented in Tcl code, naturally)
 > on whether a method may be called

if this is intended to describe, what filters in xotcl are, this is
incorrect. If this is something different form xotcl, please explain.
This description sounds more like a "guard" in xotcl.

 > In XOTcl, every class and every object has an associated namespace.

mostly true. Strictly speaking, xotcl allocates namespaces on
demand. Namespaces are only allocated, when per-object procs or subcommands
(e.g. nested objects) are added, since we need namespaces with tcl's c
api as method repositories). If one uses objects with variables or
using inherited methods, no namespace is allocated.  So, the
vast majority of objects in real life applications have no tcl-namespace.
This lazy namespace allocates improves
object allocation speed and - more important - saves a lot of memory
(see space comparison of objects on the xotcl home page). Do you plan
to change this?

 >The namespace associated with a class ::myclass is 
::xotcl::classes::myclass;

This is as well only partly true. myclass has a lazy namespace like
objects for procs or subobjects. It has as well a
second namespace as method repository for its instances with the
mentioned name (the variable part of the namespace is not used).

Since this section is called differences to xotcl: how is this intended 
in oo::tcl?


 > Exported procs appear as object subcommands; non-exported procs do
 > not, but remain available as subcommands of the my command. In this
 > way, the object itself can still use them, but they need appear in
 > the object's interface only if desired.

you seem to mean this literally. even inside an object, you cannot call an
private (non-exported) method by
    [self] p-method
 but only by
    my method
why is this? i am not aware of any oo-language with such an
restriction. or is this a misinterpretation?

 > .. oo::define
i have argued my concerns in length in an another mail.

 >... names: export and unexport.

i would call these rather "protected" and "public". Tcl's namespace
exports are not about protection but about but about providing
forwarders.  One can call any tcl method of a namespace, no matter
whether this is exported or not. This is conceptually different to the
protection where some other object should not be able to call a
protected method .

The TIP says:

 > oo::object name
 > Constructs a new object called name of class
 > oo::object; the object is represented as a command in the current
 > scope. ... If name is the empty string, oo::object generates a name
 > automatically that is guaranteed to not clash with any existing
 > command name.
.... 

 > The new object has two predefined non-exported methods: eval and
 > variable. Other subcommands and other behaviour can be added using
 > oo::define
...

 > When an attempt is made to invoke an unknown method on any object,
 > the core then attempts to pass all the arguments (including the
 > command name) to the public unknown method of the object. If no such
 > method exists, an error message is generated. Instances of the core
 > oo::object class do not have an unknown method by default.

 > oo::class has the methods "create", "new" and "unknown"
 >

just to be sure:
  oo::object is an instance of ::oo::class and has superclass
  oo::object (please make this in the TIP more explicit; please define
  instance-of relationships in the suggested class hierarchy to be
  clear about what is an instance of what?)

This raises a lot of questions:

  - why you want to create an direct instance of oo::object. I would
     think, you won't.

  - why has oo::define a "variable" method (i assume a new name for
     xotcl "instvar") when it has no set, append, etc, which are part
     of "struct"; i would assume that oo::object is designed so
     minimal that it cannot contain variables. i wonder, whether it
     makes sense to call "oo::object" object at all.

  - while we are on this topic: is it intended that an oo::class
     instance cannot contain variables (oo::class has no class
     variables)?

  - why is the description of what i believe is the behavior of the
     method unknown of oo::class part of the description of object?
     (what happens when you call "oo::object somename")

  - why is there an alternate way to specify "new" (via empty strings)
     in the core? let users do this (e.g. via mixins) if they want it.

  - why has oo::object no unknown. even namespaces  have it
     nowadays.  if i interpete correctly and one calls on an instance
     o1 of oo::object with the method "bar", then some built-in
     magic calls "o1 unknown bar"; if this is not defined, then
     "o1 unknown unknown bar" is called and the loop is detected?  if
     the system calls internally "o1 unkown", then it is certainly
     part of the interface and should be defined and documented in
     oo::object.

 - i did not see a "class" method; intended?

 - what is the exact sequence of steps during object creation. i am
     not sure what you have in mind: how is the class assigned, when
     and how are the configuration parameters evaluated (since you
     dropped the configure method "deliberately")

I would suggest to drop the following sentence, which confuses me,
since i would assume that the xotcl linearization should be left as it
is.

 > Inheritance will follow the XOTcl pattern (except with a somewhat
 > different class hierarchy, of course)

i am running out of time now, two simple questions: 

 >next The next command allows methods to invoke the implementation of
 > the method with the same name in their superclass (as determined by
 > the normal inheritance rules; if a per-object method overrides a
 > method defined by the object's class, then the next command inside
 > the object's method implementation will invoke the class's
 > implementation of the method). The arguments to the next command are
 > the arguments to be passed to the superclass method; this is in
 > contrast to the XOTcl next command, but other features in Tcl 8.5
 > make this approach viable and much easier to control. The current
 > stack level is temporarily bypassed for the duration of the
 > processing of the next command; this is in contrast to the XOTcl
 > version of the next command, but it allows a method to always
 > execute identically with respect to the main calling context.

I try to extract the differences to "next" in xotcl,

  - one difference is that one has now to specify the argument list (i
     don't see the advantage)
  - "executing in the same callframe" seems a problem to me. what
     happens with upvar, uplevel, debuggers? some of the information
     like the current class are kept on the stack. How will this be
     realized? after next the calling proc continues in the original
     frame. how will this work?

why is next changed? have i interpreted something wrong?

 > It is an error to invoke the next command when there is no
 > superclass definition of the current method.

What is a superclass definition of a method? Should i read this as "an
error is issued when next is called on non-shadowed methods"? This
would make it quite ugly to write generic interceptors, since all next
calls have to be wrapped in "catch"es.

concerning self: when i see correctly,
 - a few subcommands were folded into complexer ones returning more
   information (e.g. "self caller" is essentially "[list [self
   calllingobject] [self callingclass] [self callingproc]]") which
   makes it slower to produce and consume this info, especially, when
   only a part of this is needed. These infos are mostly used in
   speed sensitive situations such as filters or debuggers or tracecs,
   which call these commands frequently.

 - a few subcommands are removed (info for transparency
   for interceptors, isnextcall). Why is this? Is your plan to drop this?

 - a few new subcommands "self object" (equivalent to "self", why is
   this needed?) and "self namespace" (2 comments about "self
   namespace": self returns in general information about incovation
   records on the callstack, so this subcommand should not be there;
   why is this needed at all, when objects are namespaces?)

best regards
-gustaf neumann


More information about the Xotcl mailing list