No registered users in community xowiki
in last 10 minutes
in last 10 minutes
Re: [Xotcl] TIP #257: Object Orientation for Tcl
From: Gustaf Neumann <neumann_at_wu-wien.ac.at>
Date: Wed, 28 Sep 2005 22:57:54 +0200
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
Date: Wed, 28 Sep 2005 22:57:54 +0200
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