Hallo
By building some Xotcl Class System I have following problem. Consider the example
% Class A A % A proc test {} { puts "method test" } % Class B -superclass A B % B test test %
I would expect by calling B test to invoke A proc test and not to create new instance of B. I know this bahavior from Smalltalk. It is very usefull for building special creating method on class side or some method that not need a instance
For Example (getter for a system constant)
Class A A proc getSystemPath {} { return \usr }
Class B -superclass A B proc getConfigFile {} { return [file join [[self] getSystemPath] System.cfg] } This would create new Instance of B with name getSystemPath Now I have to write: B proc getConfigFile {} { return [file join [A getSystemPath] System.cfg] } or implement proc search on class side by myself
This was rather simple example but there are many examples in smalltalk libraries for reasonable use of this bahavior.
Is there a chance to change it in next version? It would make my system easier and cleaner
mfG =========================================
Artur Trzewik http://www.xdobry.de
=========================================
On Sunday 22 April 2001 14:02, Artur Trzewik wrote:
Hallo
By building some Xotcl Class System I have following problem. Consider the example
% Class A A % A proc test {} { puts "method test" } % Class B -superclass A B % B test test %
I would expect by calling B test to invoke A proc test and not to create new instance of B. I know this bahavior from Smalltalk. It is very usefull for building special creating method on class side or some method that not need a instance
we discussed internally this topic about forteen day ago internally. the point is that - "proc" is by its idea an object specific method - the way to provide methods for other objects (in the general sense) in xotcl is primarily the instproc mechanism; - the preferred way to provide methods for classes are meta classes
one can use meta-classes, or even if you want to stick with "Class" class creation, you can combine metaclasses with instmixins to achieve a similar behavior: ========================================================== Class M M instproc mt {} {puts "method meta test" } Class instmixin M
Class A Class B -superclass A B mt ==========================================================
in other cases, it is appropriate to search for some base-class an to call its proc via delegation. The per-object-philosopy (for the "eyes" of one object only) is something which can be desireable in some situations.
a possible solution is to distinguish between - proc - instproc - classproc where the last one is like a proc, which is intherited to subclasses. The danger i see there is the XOTcl becomes a kind of new version of CLOS, which allows a very elementary configuration of all aspects of the language with tons of "modifiable language elements"
aside the basic question of conceptual cleanness of what procs are supposed to be is the question of negative effects and compatibility. Currently, calling a proc is very fast, the necessity to search for another proc will cause some speed penalty. for other effects, check the following incomplete list of further aspects:
- method chaining between procs (of classes), - [self] of a proc is not alway the object, on which it is called, - inheritable procs in per-object or per-class mixins
My feeling is that the number of occurances, where this inheritable procs are needed, is rather small (maybe it is my programming style). The issues involved are quite complex. in most (all) there is a not-so-conveniant, but quite-clean solution for the problem. But my opinion is quite undecided.
What is the opinion of the community? Do you need/want such an extended "inheritable proc" or a new language-consttruct? Did you face this problem already, and if yes, was it hard/inelegant to solve?
best regards -gustaf
On Tue, 24 Apr 2001, Gustaf Neumann wrote:
What is the opinion of the community? Do you need/want such an extended "inheritable proc" or a new language-consttruct? Did you face this problem already, and if yes, was it hard/inelegant to solve?
Personally I've never had the need for it (per-object procs were fine). Usually I'd always want to keep a language as simple as possible. Of course if I had a need for such a structure then maybe I would change my stance, but until it becomes very common I'm probably content with the current system.
- ---------- = = ---------//--+ | / Kristoffer Lawson | www.fishpool.fi|.com +-> | setok@fishpool.com | - - --+------ |-- Fishpool Creations Ltd - / | +-------- = - - - = --------- /~setok/
On Tue, 24 Apr 2001, Kristoffer Lawson wrote:
On Tue, 24 Apr 2001, Gustaf Neumann wrote:
What is the opinion of the community? Do you need/want such an extended "inheritable proc" or a new language-consttruct? Did you face this problem already, and if yes, was it hard/inelegant to solve?
Personally I've never had the need for it (per-object procs were fine). Usually I'd always want to keep a language as simple as possible. Of course if I had a need for such a structure then maybe I would change my stance, but until it becomes very common I'm probably content with the current system.
We should also mention: the structure can be build quite easily in XOTcl by overloading the "unknown" method. That is, unknown traverses the class procs, before trying to forward to create ... in this light, the question is, whether that has to be the standard mechanism. Despite the fact that I also came up with the same issue some weeks ago, I would tend to say now: who requires it, should customize unknown. But I'm not completely sure yet.
--uwe
On Tuesday 24 April 2001 20:25, Kristoffer Lawson wrote:
On Tue, 24 Apr 2001, Gustaf Neumann wrote: Personally I've never had the need for it (per-object procs were fine). Usually I'd always want to keep a language as simple as possible. Of course if I had a need for such a structure then maybe I would change my stance, but until it becomes very common I'm probably content with the current system.
well, here is a quite a short and simple solution that might be sufficient for most situations:
==================================================================================== Class InheritClassProc InheritClassProc instproc unknown {m args} { foreach c [[self] info heritage] { if {[info command ${c}::$m] != ""} {return [eval $c $m $args]} } next } Class instmixin InheritClassProc ====================================================================================
one can add a ...if {![.. ismetaclass ...]} to avoid its call on the creation of classes. To test it in the originally posted problem, the following example calls for "B test ..." the proc of A, and creates a new object for "B test".
================================================== Class A A proc test {x y} { expr {$x*$y} } Class B -superclass A puts result=[B test 47 11] puts result=[B test1] ==================================================
If you have a speed sensitive program, or you do not want to globber the space of object names, i would recommend to invoke the create method explizitly like "B create test1", or to create an instance of B named "test", use "B create test"
best regards -gustaf
Halo
The problem is more complicated than I have expected. It is true, proc are not good for this purposes. Classproc are very good idea but it would complicate the model.
It is really a program style not to use class methods. If you come from C++ or Java (brr...) you will seldom use it. Smalltalk-programmers will miss it (there are many smalltalk based languages) A main usage is individual instance creation (such as Factory Patterns in C++ or type based polymorphismus) for example
MyClass createFromXML "...xml string" MyClass createFromFooObject myObject
C++ programmers will write
class MyClass { public: MyClass(XMLNode node); MyClass(FooClass myObject); };
It is difficult to simulate it in xotcl by using C++ way
MyClass instproc init {aThing} { if {[Object isobject $aThing] && [$aThing istype FooClass]} { [self] initFromFooObject $aThing } else { ....... } }
Perhaps Xotcl need inheritable class methods because it is not typed. It can be very usefull to delegate some tasks to another class method by implementing factories as class methods.
At now I implement databased persistence for Xotcl objects. I use class methods for create instances, query database or code mapping rules.
Class DBPersistence Class MyClass -super DBPesistence
so I will do (100 is the database Id)
MyClass createFormId 100
or
MyClass getAllFor {name="destroy" and type not null}
I have noticed that Xotcl Philosophy is to use Metaclasses
Class DBPersistent -superclass Class DBPersistent MyClass
until now I have not programed any Metaclasses (maybe it is time to do it)
InheritClassProc instproc unknown {m args} { foreach c [[self] info heritage] { if {[info command ${c}::$m] != ""} {return [eval $c $m $args]} } next } Class instmixin InheritClassProc
The solution do not do what I expect See this example. It demostrate how inheritable class method can be used
Class TkWidget TkWidget proc testMe {} { set toplevel [toplevel [Object autoname .toplevel]] set inst [[self] create [Object autoname twidget] ${toplevel}.test] pack $toplevel.test return $inst } Class TkText -superclass TkWidget TkText instproc init {win} { text $win } Class TkEntry -superclass TkWidget TkEntry instproc init {win} { puts "window $win" entry $win } TkEntry testMe
I will try to use metaclasses for my problems. It can be good to take a look on other new objectbased languages ruby, self, python. How do these languages handle class methods?
=========================================
Artur Trzewik http://www.xdobry.de
=========================================
On Wednesday 25 April 2001 20:51, Artur Trzewik wrote:
Halo
The problem is more complicated than I have expected. It is true, proc are not good for this purposes. Classproc are very good idea but it would complicate the model.
It is really a program style not to use class methods. If you come from C++ or Java (brr...) you will seldom use it. Smalltalk-programmers will miss it (there are many smalltalk based languages) A main usage is individual instance creation (such as Factory Patterns in C++ or type based polymorphismus) for example
MyClass createFromXML "...xml string" MyClass createFromFooObject myObject
C++ programmers will write
class MyClass { public: MyClass(XMLNode node); MyClass(FooClass myObject); };
i would recommend to use "-methods" to tag the type; at the place, where you create instances of myclass, you will most probably know the kind of argument you are passing:
Class MyClass MyClass instproc xml value { ;# convert xml value to internal rep ... } MyClass instproc obj value { ;# convert obj to internal rep ... } ... MyClass o1 -xml "...xml string" MyClass o2 -obj myObject
InheritClassProc instproc unknown {m args} { foreach c [[self] info heritage] { if {[info command ${c}::$m] != ""} {return [eval $c $m $args]} } next } Class instmixin InheritClassProc
The solution do not do what I expect See this example. It demostrate how inheritable class method can be used
Class TkWidget TkWidget proc testMe {} { set toplevel [toplevel [Object autoname .toplevel]] set inst [[self] create [Object autoname twidget] ${toplevel}.test] pack $toplevel.test return $inst } Class TkText -superclass TkWidget TkText instproc init {win} { text $win } Class TkEntry -superclass TkWidget TkEntry instproc init {win} { puts "window $win" entry $win } TkEntry testMe
i see; what you want is not delegation to the class, where the proc is defined (in this case the call to [self] in testMe would return "TkWidget"), but you want to evaluate the method testMe in the context of the calling class ([self] in testMe will return "TkEntry")
Fortunately, we have a questionable feature in xotcl, which allows this currently, but notice that you have limited interception capabilities. it is possible to call a proc directly, bypassing the xotcl dispatcher. ################################################################## Class InheritClassProc InheritClassProc instproc unknown {m args} { foreach c [[self] info heritage] { if {[info command ${c}::$m] != ""} { return [eval ${c}::$m $args] } } next } Class instmixin InheritClassProc ###################################################################
a casual reader will hardly notice the difference, but instead of calling '$c $m $args', a call to '${c}::$m $args' is performed.
if i look at your program, the main reason for using the class proc seems to be to call "pack" **after** init without the need to write it into TkEntry or TkText. You can also use filters or an instmixin to achieve the same behavior:
========================================================================== Class TkPacker TkPacker instproc init args { set r [next] pack [[self] set name] return $r }
Class TkWidget -instmixin TkPacker TkWidget instproc init {} { [self] instvar toplevel set toplevel [toplevel [Object autoname .toplevel]] [self] set name ${toplevel}.[string trimleft [self] :] } Class TkText -superclass TkWidget TkText instproc init {win} { next text [[self] set name] } Class TkEntry -superclass TkWidget TkEntry instproc init {} { next entry [[self] set name] } TkEntry a ==========================================================================
This version has the advantage that you get more predictable widet names.
I will try to use metaclasses for my problems. It can be good to take a look on other new objectbased languages ruby, self, python. How do these languages handle class methods?
this is not an easy question; the language of this list which is closest to XOTcl is ruby, which has a single construct named "def" to define a proc or instproc (in xotcl terms). within a class definition, def Classname.methodname defines a class method. there is no word about inheritence of class procs in the documentation.
self is quite different, since self does not have classes, but traits and mixins, which provide a bundle of methods through specially marked "parent" slots. since there are not classes, class methods can't be defined. As i see it, one needs can define two slots for traits, one defined as a parent slot (which will provide methods for the "instances", and another slot for a separate object, that can be reached via delegation, which will have the counterpart of a proc. Two objects can share a trait, therefore it is possible to define something like inherited class procs by "manually" assigning the appropriate slot to all involved objects. This is like defining per object mixins to all effected classes. therefore, the short answer is no, there is no direct language support for this behavior.
python has a rather week oo support. it has no distinction between instproc and proc, all methods are defined by "def". python has no class methods. the trick to achieve a similar behavior in python is to define a "module" and to define in the module a function outside the scope of a class. Therefore: there is no way get inheritance.
hope this helps -gustaf