From: MartinLemburg on
Hello,

I've took the following example from the wiki page http://wiki.tcl.tk/18440:

% info patchlevel
8.6b1.1
% package require TclOO
0.6.1
% oo::class create foo { constructor {} {next; puts foo} }
::foo
% oo::class create bar { constructor {} {next; puts bar} }
::bar
% oo::class create foobar { superclass foo bar; constructor {}
{next; puts foobar}}
::foobar
% oo::class create geek {constructor {} {next; puts geek}}
::geek
% oo::class create mongrel {superclass foobar geek; constructor {}
{next; puts mongrel}}
::mongrel
% [mongrel new] destroy
no next constructor implementation
% set errorInfo
no next constructor implementation
while executing
"next"
(class "::geek" constructor line 1)
invoked from within
"next"
(class "::bar" constructor line 1)
invoked from within
"next"
(class "::foo" constructor line 1)
invoked from within
"next"
(class "::foobar" constructor line 1)
invoked from within
"next"
(class "::mongrel" constructor line 1)
invoked from within
"mongrel new"

Removing the "next" calls in the non-inheriting classes lead to the
following result:
% oo::class create foo { constructor {} {puts foo} }
::foo
% oo::class create bar { constructor {} {puts bar} }
::bar
% oo::class create geek {constructor {} {puts geek}}
::geek
% oo::class create foobar { superclass foo bar; constructor {}
{next; puts foobar}}
::foobar
% oo::class create mongrel {superclass foobar geek; constructor {}
{next; puts mongrel}}
::mongrel
% [mongrel new] destroy
foo
foobar
mongrel

The result is unexpected for me. I expected something like:
% [mongrel new] destroy
foo
bar
foobar
geek
mongrel

So I miss the calls to the constructors of the classes "bar" and
"geek", which are always the 2nd super classes in the classes "foobar"
and "mongrel".

Is the chain of invocation via next broken? Or do I miss something?

-----

The reason I tested this is, that I wanted to have super classes with
constructors with different count of arguments and I looked for a way
to achieve the call of this super class constructors - with no
success.

-----

Any hints or suggestions?

Thanks in advance,

Martin
From: APN on
http://sourceforge.net/tracker/?func=detail&aid=2952145&group_id=10894&atid=110894

/Ashok

On Feb 15, 7:47 pm, "MartinLemburg(a)Siemens-PLM"
<martin.lemburg.siemens-...(a)gmx.net> wrote:
> Hello,
>
> I've took the following example from the wiki pagehttp://wiki.tcl.tk/18440:
>
>     % info patchlevel
>     8.6b1.1
>     % package require TclOO
>     0.6.1
>     % oo::class create foo { constructor {} {next; puts foo} }
>     ::foo
>     % oo::class create bar { constructor {} {next; puts bar} }
>     ::bar
>     % oo::class create foobar { superclass foo bar; constructor {}
> {next; puts foobar}}
>     ::foobar
>     % oo::class create geek {constructor {} {next; puts geek}}
>     ::geek
>     % oo::class create mongrel {superclass foobar geek; constructor {}
> {next; puts mongrel}}
>     ::mongrel
>     % [mongrel new] destroy
>     no next constructor implementation
>     % set errorInfo
>     no next constructor implementation
>         while executing
>     "next"
>         (class "::geek" constructor line 1)
>         invoked from within
>     "next"
>         (class "::bar" constructor line 1)
>         invoked from within
>     "next"
>         (class "::foo" constructor line 1)
>         invoked from within
>     "next"
>         (class "::foobar" constructor line 1)
>         invoked from within
>     "next"
>         (class "::mongrel" constructor line 1)
>         invoked from within
>     "mongrel new"
>
> Removing the "next" calls in the non-inheriting classes lead to the
> following result:
>     % oo::class create foo { constructor {} {puts foo} }
>     ::foo
>     % oo::class create bar { constructor {} {puts bar} }
>     ::bar
>     % oo::class create geek {constructor {} {puts geek}}
>     ::geek
>     % oo::class create foobar { superclass foo bar; constructor {}
> {next; puts foobar}}
>     ::foobar
>     % oo::class create mongrel {superclass foobar geek; constructor {}
> {next; puts mongrel}}
>     ::mongrel
>     % [mongrel new] destroy
>     foo
>     foobar
>     mongrel
>
> The result is unexpected for me. I expected something like:
>     % [mongrel new] destroy
>     foo
>     bar
>     foobar
>     geek
>     mongrel
>
> So I miss the calls to the constructors of the classes "bar" and
> "geek", which are always the 2nd super classes in the classes "foobar"
> and "mongrel".
>
> Is the chain of invocation via next broken? Or do I miss something?
>
> -----
>
> The reason I tested this is, that I wanted to have super classes with
> constructors with different count of arguments and I looked for a way
> to achieve the call of this super class constructors - with no
> success.
>
> -----
>
> Any hints or suggestions?
>
> Thanks in advance,
>
> Martin

From: Donal K. Fellows on
On 15 Feb, 14:47, "MartinLemburg(a)Siemens-PLM"
<martin.lemburg.siemens-...(a)gmx.net> wrote:
> I've took the following example from the wiki page http://wiki.tcl.tk/18440:
>
>     % info patchlevel
>     8.6b1.1
>     % package require TclOO
>     0.6.1

You're using an old version of the code there. If you're not going to
use 8.6b1 itself (or 8.6b2, but that doesn't exist yet) then you
should make sure you're up to date with the HEAD. Indeed, the tip of
TclOO has been known as 0.6.2 since the end of November.

> So I miss the calls to the constructors of the classes "bar" and
> "geek", which are always the 2nd super classes in the classes "foobar"
> and "mongrel".
>
> Is the chain of invocation via next broken? Or do I miss something?

I suspect this relates to the fix for Bug 1998244. What to do about it
(if anything) I don't know yet.

> The reason I tested this is, that I wanted to have super classes with
> constructors with different count of arguments and I looked for a way
> to achieve the call of this super class constructors - with no
> success.

You're talking about having a class that derives from two independent
classes? In an ontological sense, that's a bit dodgy; if the two
classes don't know about each other, how can they possibly pass the
right arguments to each other's constructor? There's got to be some
shared context for it to even make sense, and that's probably best
done through a common superclass. (In that case, you can use option-
value pairs as arguments, have each of the "independent" classes strip
out the arguments it understands and pass the rest on, and have the
common superclass moan about any that get through that it doesn't
handle itself.)

If this isn't a suitable solution, please provide more information
about the real situation that needs this sort of technique. Be
prepared to have me ask why delegating to a contained object is an
insufficient scheme, but if you've got a real case, I'd love to hear
it. I've never encountered a real one that made sense.

Donal.
From: MartinLemburg on
Hi Donal,

thanks for your detailed answer!

First - where could I get a binary distribution of the most current
version?

I ask, because I usually build starpacks using the base-kits from the
most current ActiveTcl distribution.
I have no "build" environment for tcl sources, so I'm not able to
fetch something from a CVS or SVN repository and to build it on my
own.

Second - I changed my coding, so my second "base" class is now used
via aggregation.

I working on a Microsoft RC file parser rebuilding the structures
found there using Tk (BWidget) widgets and tcl msgcats.
Some of the RC file structures are not only resources but
widget( collection)s, too.
So I thought to make a "union" of both base classes Resource and
Widget - that's all.
I can live with the changes, but I would have thought it would be
"easy" to use multiple inheritance and hoped it would be possible -
without tricks - to invoke constructors or methods from base class(es)
more easier and more transparent.

In C++ I often use "_super::.+" or "${BaseClass}::.+", which does not
ASAIK open a new stack frame and allows to delegate to base class
methods with a specified set of arguments, while TclOO's next has IMHO
a "intransparent" call chain.

It is not clear which method will called first - especially with
multiple inheritance, multiple mixins. And this call sequence is not
guaranteed to be "stable". And the called methods are not to be
specified.
So I can't delegate to two or more base class constructors with
different sets of arguments without doing tricks like using "option"
sets - you mentioned this.

Why not introducing this C++ like call delegation?

Introducing a command "super" standing next to "self" and "next" would
be that problematic.
And if there are more than one super/base class, than a "[$
{BaseClass}::(constructor|\w+) .+]" usage should be allowed.

Third - is there a good introduction or tutorial in using TclOO?
I don't mean the wiki pages, nor I want to study sources.
Or ... is it possible to upgrade the TclOO man pages to contain an
introduction into the capabilities and the philosophy (e.g. mixin's)
additional to the normal "syntax" explanations?

Thanks and best regards,

Martin

On 15 Feb., 17:25, "Donal K. Fellows"
<donal.k.fell...(a)manchester.ac.uk> wrote:
> On 15 Feb, 14:47, "MartinLemburg(a)Siemens-PLM"
>
> <martin.lemburg.siemens-...(a)gmx.net> wrote:
> > I've took the following example from the wiki pagehttp://wiki.tcl.tk/18440:
>
> >     % info patchlevel
> >     8.6b1.1
> >     % package require TclOO
> >     0.6.1
>
> You're using an old version of the code there. If you're not going to
> use 8.6b1 itself (or 8.6b2, but that doesn't exist yet) then you
> should make sure you're up to date with the HEAD. Indeed, the tip of
> TclOO has been known as 0.6.2 since the end of November.
>
> > So I miss the calls to the constructors of the classes "bar" and
> > "geek", which are always the 2nd super classes in the classes "foobar"
> > and "mongrel".
>
> > Is the chain of invocation via next broken? Or do I miss something?
>
> I suspect this relates to the fix for Bug 1998244. What to do about it
> (if anything) I don't know yet.
>
> > The reason I tested this is, that I wanted to have super classes with
> > constructors with different count of arguments and I looked for a way
> > to achieve the call of this super class constructors - with no
> > success.
>
> You're talking about having a class that derives from two independent
> classes? In an ontological sense, that's a bit dodgy; if the two
> classes don't know about each other, how can they possibly pass the
> right arguments to each other's constructor? There's got to be some
> shared context for it to even make sense, and that's probably best
> done through a common superclass. (In that case, you can use option-
> value pairs as arguments, have each of the "independent" classes strip
> out the arguments it understands and pass the rest on, and have the
> common superclass moan about any that get through that it doesn't
> handle itself.)
>
> If this isn't a suitable solution, please provide more information
> about the real situation that needs this sort of technique. Be
> prepared to have me ask why delegating to a contained object is an
> insufficient scheme, but if you've got a real case, I'd love to hear
> it. I've never encountered a real one that made sense.
>
> Donal.

From: Donal K. Fellows on
On 16 Feb, 07:55, "MartinLemburg(a)Siemens-PLM"
<martin.lemburg.siemens-...(a)gmx.net> wrote:
> First - where could I get a binary distribution of the most current
> version?
>
> I ask, because I usually build starpacks using the base-kits from the
> most current ActiveTcl distribution.

The current version of TclOO for Tcl 8.5 in the ActiveState teapot is
up to date (apart from one small but nasty issue with destructor
execution which is unfixable because it required a small change to Tcl
to provide the necessary hook). Make sure you're using version 0.6.2.

(And I'm getting very close to taking on doing release management
myself just so that we can get Tcl 8.6b2 out the door, and I utterly
*hate* doing release management!)

> In C++ I often use "_super::.+" or "${BaseClass}::.+", which does not
> ASAIK open a new stack frame and allows to delegate to base class
> methods with a specified set of arguments, while TclOO's next has IMHO
> a "intransparent" call chain.

I understand. The problem is that I really want to have unified
semantics for constructors and other methods, and that means a single
system for traversing the call chain. (There's also no unified syntax
for naming methods, but that's of lesser concern.) Where there is no
unified way of handling a variable number of arguments, that makes
doing constructors quite difficult. OTOH, I want to be able to support
positional arguments anyway (it helps a lot with simpler uses) and
putting a magical default "consume all arguments and don't complain"
constructor in oo::object just covers up real problems. It's tricky.

The itcl package that's built on top of TclOO *does* permit the sort
of superclass implementation selection that you're talking about.

> It is not clear which method will called first - especially with
> multiple inheritance, multiple mixins. And this call sequence is not
> guaranteed to be "stable". And the called methods are not to be
> specified.

All I can guarantee is that if class B inherits from class A, then A's
implementation of the method/constructor will be further along the
linearized chain of implementations than B's. Anything else just gets
too complicated!

> Why not introducing this C++ like call delegation?

Principally, because I suspect that those cases where people demand it
are actually cases where inheritance is being misused. Inheritance is
not for modeling rôles (that's what mixins are for) so where you've
got multiple inheritance you really need to be thinking in terms of a
class that is naturally a specialization of both its superclasses.
I've yet to see a satisfying example of this, and I (probably) won't
do anything about this until someone demonstrates a proper motivating
example.

So far, the only concrete example that anyone's tried involved widget
classes, and that turned out to be an abuse because the child class
was really not very much like one of the parent classes in that a
dialog widget isn't subject to normal geometry management rules, etc.

> Third - is there a good introduction or tutorial in using TclOO?

Not yet. I understand that Clif Flynt is working on an update to his
book and he's threatened to pester me for help with writing the
chapter(s?) on TclOO.

> Or ... is it possible to upgrade the TclOO man pages to contain an
> introduction into the capabilities and the philosophy (e.g. mixin's)
> additional to the normal "syntax" explanations?

Yes, it's very possible. But I'm too close to the implementation (and
have too much training in object theory too) to see what tutorial
material needs to be there. I need people to propose material, to tell
me what they don't understand, to help me grasp the detail of what to
add. Help me help you!

Donal.