You wrote:
Object instproc insert_mixin {mixin_list} { my mixin [append mixin_list " " [my info
mixin]]
}
with names like mixinappend, mixinprepend for mixins,
filters,
instmixins, instfilters we would introduce a large number
of
methods, which do more or less the same.
Yes. That is certainly a problem.
what do you people think about the following "interceptor" method: it is more verbous, but much more powerful as
well; it
allows appending/prepending/inserting at a certain
position and
deletion of all kinds of interceptors:
Hm...
One minor niggle is the use of the term 'interceptor'. The term is quite overloaded. First, this instproc manages two kinds of 'interceptor' interfaces for an object: mixins and filters. Second, the proc itself is an interceptor -- it traps calls to manage the mixin and filter lists. Third, as you have written this proc, it manages both mixins and filters, which makes them appear more similar than they really are.
That said, I do think you are on to something. The core problem is that both filters and mixins are a list of classes, and there are no good primitives to manage that list in a natural manner. It would be nice if [my info mixin] and [my info filter] were mutable with list commands, but...
So, for the sake of argument, let us assume that there are two new instprocs - one to manage the list of filters, and one to manage the list of mixins (again, better naming ideas greatly appreciated):
Object instproc mixin_list args { set op [lindex $args 0] set classes [lrange $args 1 [llength $args]]
switch -exact $op { append { my mixin [concat [my info mixin] $classes] } prepend { my mixin [concat $classes [my info mixin]] } set { my mixin $classes } get { my info mixin } delete { ... } } }
Class A Class B Class C
A a a mixin_list append B a mixin_list prepend C a mixin_list get ================ ::C ::B
Adding new primitive operations (like a mixin_list length; a mixin_list sort; a mixin_list contains classname; etc.) is simple and obvious. I haven't played with filters yet, but this idiom should work well there, too.
I'll leave it to you to determine whether this method should work use instmixin for Classes, and mixin for Objects.
-- Adam
Just a random thought, not totally paying attention to this thread:
Is there a reason why the filter/mixin lists could not just be normal object/class variables? Seems XOTcl already has plenty of flexibility to deal with these. E.g.:
instead of:
Object mixin ....
do:
Object set mixins [list ... ]
or something like that (not completely familiar with the current syntax). The old methods could be setup to just be wrappers around these new variables. Or is there some reason why these lists are treated specially?
Cheers,
Neil.
On 19 May 2004, at 16:03, Adam Turoff wrote:
<discussion on how to handle mixins/filters>
Neil Madden wrote:
Just a random thought, not totally paying attention to this thread:
Is there a reason why the filter/mixin lists could not just be normal object/class variables? Seems XOTcl already has plenty of flexibility to deal with these. E.g.:
instead of:
Object mixin ....
do:
Object set mixins [list ... ]
or something like that (not completely familiar with the current syntax). The old methods could be setup to just be wrappers around these new variables. Or is there some reason why these lists are treated specially?
mixins and filters are no variables.
Its similar in tcl, where you have [info commands] and not a magic $commands variable as you might have in other languages.
Using traces it should be possible to provide such an interface if anyone really wants it.
Michael
On Wed, 19 May 2004, Michael Schlenker wrote:
Its similar in tcl, where you have [info commands] and not a magic $commands variable as you might have in other languages.
Using traces it should be possible to provide such an interface if anyone really wants it.
So what is so problematic about just getting a list, manipulating it and then setting it back? Seems like a lot of copied effort for what is basically just list manipulation.
Kristoffer Lawson wrote:
On Wed, 19 May 2004, Michael Schlenker wrote:
Its similar in tcl, where you have [info commands] and not a magic $commands variable as you might have in other languages.
Using traces it should be possible to provide such an interface if anyone really wants it.
So what is so problematic about just getting a list, manipulating it and then setting it back? Seems like a lot of copied effort for what is basically just list manipulation.
Yep. I refer to Adam and Neil who both wanted to have mutable objects instead of accessor functions. Its the usual problem with mutable list objects and the tradional value based list operations in Tcl.
For the typically short list of mixins and filters its mostly a reduction of some characters to type, not more.
But i think Adam is right in his direction that it would probably more natural to add the Mixin to the head of the list instead of the tail.
So what to do? a) keep it as it is and use tradtional Tcl list semantics to make changes b) add a primitive to prepend a Mixin c) add something so the Mixin List is applied in the inverse direction, from last to first
I think option b) isn't the right thing to do. c) is attractive but has semantic consequences. a) is do nothing
Michael
On 19 May 2004, at 17:07, Michael Schlenker wrote:
Kristoffer Lawson wrote:
On Wed, 19 May 2004, Michael Schlenker wrote:
Its similar in tcl, where you have [info commands] and not a magic $commands variable as you might have in other languages.
Using traces it should be possible to provide such an interface if anyone really wants it.
So what is so problematic about just getting a list, manipulating it and then setting it back? Seems like a lot of copied effort for what is basically just list manipulation.
Yep. I refer to Adam and Neil who both wanted to have mutable objects instead of accessor functions. Its the usual problem with mutable list objects and the tradional value based list operations in Tcl.
Woah there! I said nothing about mutable objects/values. Mutable variables are all that is needed, and they exist already (in fact, you have to go an extra step to get immutable variables). The idea is to reuse things like [lappend], [linsert], [lreplace] etc, without creating lots of [mixin_append], [mixin_replace] etc etc. That's the duplication of effort.
Neil.
Neil Madden wrote:
On 19 May 2004, at 17:07, Michael Schlenker wrote:
Kristoffer Lawson wrote:
On Wed, 19 May 2004, Michael Schlenker wrote:
Its similar in tcl, where you have [info commands] and not a magic $commands variable as you might have in other languages.
Using traces it should be possible to provide such an interface if anyone really wants it.
So what is so problematic about just getting a list, manipulating it and then setting it back? Seems like a lot of copied effort for what is basically just list manipulation.
Yep. I refer to Adam and Neil who both wanted to have mutable objects instead of accessor functions. Its the usual problem with mutable list objects and the tradional value based list operations in Tcl.
Woah there! I said nothing about mutable objects/values.
You talked about adding instance variables which are mutable objects by definition, while Adam talked about mutable objects directly.
Mutable variables are all that is needed, and they exist already (in fact, you have to go an extra step to get immutable variables).
Of course, mutability is what variables are all about... ;-)
The idea is to reuse things like [lappend], [linsert], [lreplace] etc, without creating lots of [mixin_append], [mixin_replace] etc etc. That's the duplication of effort.
You can reuse them, correct me if I'm wrong:
set mixins [$obj info mixins] # use standard list operations as you like set mixins [linsert $mixins 0 $newMixin] lappend mixins $anotherMixin $obj mixin $mixins
Where is the huge benefit of a magic instance variable containing the list of mixins? I just don't see the benefit, but i see that you would add a magic variable name to objects where none existed before.
Either the interface gets cluttered with commands (prepend append llength whatever) or the existing commands are reused which leads to slightly longer code but smaller interfaces.
Michael
On 19 May 2004, at 21:05, Michael Schlenker wrote:
Woah there! I said nothing about mutable objects/values.
You talked about adding instance variables which are mutable objects by definition, while Adam talked about mutable objects directly.
What do you mean here? Variables are mutable, yes. They're not "objects" though (they're neither XOTcl objects, or even Tcl_Objs (values) - I assume they're normal Tcl namespaced variables, but XOTcl might implement them differently). I'm proposing a change of interface that's all. At present we have a "special" variable (the mixin list) which is hidden behind the [$obj mixin] and [$obj info mixin] commands. All I am saying is to bring that variable into the limelight to be an actual instance variable of the object, and use the usual methods to alter it. It's always been mutable, just not in place.
(By "immutable" I would be referring to something like a "final" variable in Java - you can assign to it once, but never again.)
Mutable variables are all that is needed, and they exist already (in fact, you have to go an extra step to get immutable variables).
Of course, mutability is what variables are all about... ;-)
Not in all languages! C.f. prolog, various rule interpreters etc. Of course, that's probably an abuse of the term "variable", but I digress... :^)
The idea is to reuse things like [lappend], [linsert], [lreplace] etc, without creating lots of [mixin_append], [mixin_replace] etc etc. That's the duplication of effort.
You can reuse them, correct me if I'm wrong:
set mixins [$obj info mixins] # use standard list operations as you like set mixins [linsert $mixins 0 $newMixin] lappend mixins $anotherMixin $obj mixin $mixins
Where is the huge benefit of a magic instance variable containing the list of mixins? I just don't see the benefit, but i see that you would add a magic variable name to objects where none existed before.
Well, you have magic variables now - they're just hidden behind the [$obj info mixins]/[$obj mixin]. The difference I was proposing was to get rid of these special methods, and replace them with a regular instance variable:
$obj lappend mixinlist $somemixin $obj set mixinlist [linsert [$obj set mixinlist] 0 $newMixin] etc
Just a trade off between altering the list in the "standard" way using the normal variable methods, or via a set of additional mixin-specific methods (the mixin_prepend etc that were proposed). Note this has nothing to do with mutable values vs accessor methods: the only way you can get/set an instance variable is via [$obj set] so it's already hidden behind accessor functions (oh, there's the instvar stuff, but I've never really looked at that).
Yes, it would add a "magic" variable name, but remove some "magic" methods. I was just seeing what appeared to be a proposal to mirror all of the variable manipulation commands with special ones to deal with mixins, which seemed a bit of a waste.
Cheers,
Neil.
On Wed, 19 May 2004, Michael Schlenker wrote:
Either the interface gets cluttered with commands (prepend append llength whatever) or the existing commands are reused which leads to slightly longer code but smaller interfaces.
Personally I'd vote for smaller interfaces if the benefit is not huge. Less maintenance and clutter and replication of functionality.
On 19 May 2004, at 16:37, Michael Schlenker wrote:
Neil Madden wrote:
Just a random thought, not totally paying attention to this thread:
Is there a reason why the filter/mixin lists could not just be normal object/class variables? Seems XOTcl already has plenty of flexibility to deal with these. E.g.:
instead of:
Object mixin ....
do:
Object set mixins [list ... ]
or something like that (not completely familiar with the current syntax). The old methods could be setup to just be wrappers around these new variables. Or is there some reason why these lists are treated specially?
mixins and filters are no variables.
No, but a list of them can be put in a variable.
Its similar in tcl, where you have [info commands] and not a magic $commands variable as you might have in other languages.
The reason for this is that commands are not first class, but are instead implemented as a handle - you never get a first class command value in Tcl (currently, see recent TIPs though), so you'd have nothing to store in the variable (just another name, which has to be resolved somewhere). This leads to a duplication of manipulator commands for vars and commands:
set var value -> proc name ... / interp alias set var -> info args/info default/info body unset var -> rename cmd {}
etc, etc. This duplication of commands is what appears to be happening for mixins/filters too. However, we are not storing mixins themselves in this scheme, but the handles to them - which are in fact, first-class. The fact that these handles are themselves command names, which are already handled specially by Tcl, allows us to resolve them without an infinite recursion.
There was another post about pre-processing which is done on mixin lists (resolving names, removing duplicates etc). This is a better argument, as it points out that wrappers would be needed anyway, so looks like duplication of methods is unavoidable (at least, not without more thought).
Cheers,
Neil.
On Wednesday 19 May 2004 17:03, Adam Turoff wrote:
what do you people think about the following "interceptor" method: it is more verbous, but much more powerful as
Hm...
One minor niggle is the use of the term 'interceptor'. The term is quite overloaded. First, this instproc manages two kinds of 'interceptor' interfaces for an object: mixins and filters. Second, the proc itself is an interceptor -- it traps calls to manage the mixin and filter lists. Third, as you have written this proc, it manages both mixins and filters, which makes them appear more similar than they really are.
what you said is certainly true. I have suggested the term with a mindset that these two are "additional kind of interceptors normally not supported by other languages" (similiar to the section "Message Interception Techniques" in the tutorial).
Your concern seems to be mostly the "name" interceptor. The commands have to do with what's sometimes is called "write introspection" in analogy to "read introspection", where you query some properties and relations of created artefacts. The former lets you change some properties/relations.
The normal xotcl interface to (stack-independet) introspection is the info command. The pattern to change things is
set old [X info PROPERTY] X PROPERTY [modify $old]
where property is for example mixin, instmixin, filter, instfilter. The same pattern works with some more properties such as "superclass", or to some extend "class" as well. Some of the read-introspectable tcl properties such as [info body ...] or [info args] or [info default] could be made writable as well, but the benefit compared to a proc command would be relative small.
I am not a big friend of magic variables as base mechanism, since otcl did not let me allow to use "class" or "proc" as names of instance variables. Methods are better since they can be easily refined.
Look at the following study; it does not have the switch ugliness with different arglists, it is extensible and interceptible:
Object introspection introspection proc get {obj prop} {$obj info $prop} introspection proc set {obj prop value} {$obj $prop $value} introspection proc add {obj prop value {pos 0}} { $obj $prop [linsert [$obj info $prop] $pos $value] } introspection proc delete {obj prop value} { set old [$obj info $prop] set p [lsearch -glob $old $value] if {$p>-1} {$obj $prop [lreplace $old $p $p]} else { error "$value is not a $prop of $obj ($old)" } } introspection proc unknown {m args} { puts "method '$m' unknown for [self]" puts " valid commands are: {[lsort [my info procs]]}" }
we can define a filter to see the consequences of our doings:
introspection proc i-filter {obj args} { set r [next] if {[string compare $args ""] && [my isobject $obj]} { set prop [lindex $args 0] puts "$prop of $obj = [$obj info $prop]" } return $r } introspection filter i-filter
now we can try it out:
Object o1 introspection add o1 mixin A introspection add o1 mixin B introspection add o1 mixin C end introspection delete o1 mixin *A introspection delete o1 mixin *A
well, we can shuffle the arguments in a little reflector instproc:
Object instproc introspection {cmd prop args} { eval introspection $cmd [self] $prop $args } o1 introspection add mixin A
and we have an "... introspection get ..." and friends again and get an error message for a
o1 introspection cancel mixin A
.... but: i am not so happy about the name "introspection" in "introspection set" and "introspection add" as well, since it requires familiarity with "write introspection" which is not only a "*spection" in the sense of "looking into", but destructive.
suggestions? -gustaf neumann
Hello,
my 2 cents: I liked the earlier proposal with the "interceptor" method better than this delegator,because it is more XOTcl style. I think it is important to have one kind of interface; we always use methods on the object itself, not methods that delegate. That's also the reason why I don't think the magic variable should be introduced: it is simply not Tcl style to have magic variables. Even though both ideas are appealing, I think sticking to Tcl/XOTcl style is important. I agree with the critic on the term interceptor: the interfaces for filters and mixins should be distinct: they are different concepts. BTW, superclass lists could make use of the same interface: obviously here the term interceptor is not appropriate.
what about just extending the usually interfaces with new arguments, such as:
A mixin X A mixin add Z 3 A mixin add Y end A mixin delete Y A instmixin add T 1 A superclass B A superclass add C
--uwe
-----Ursprüngliche Nachricht----- Von: xotcl-admin@alice.wu-wien.ac.at [mailto:xotcl-admin@alice.wu-wien.ac.at]Im Auftrag von Gustaf Neumann Gesendet: Freitag, 21. Mai 2004 20:09 An: Adam Turoff Cc: xotcl@alice.wu-wien.ac.at Betreff: Re: [Xotcl] Mixins in XOTcl
On Wednesday 19 May 2004 17:03, Adam Turoff wrote:
what do you people think about the following "interceptor" method: it is more verbous, but much more powerful as
Hm...
One minor niggle is the use of the term 'interceptor'. The term is quite overloaded. First, this instproc manages two kinds of 'interceptor' interfaces for an object: mixins and filters.
Second, the
proc itself is an interceptor -- it traps calls to manage the mixin and filter lists. Third, as you have written this proc, it manages both mixins and filters, which makes them appear more similar than they really are.
what you said is certainly true. I have suggested the term with a mindset that these two are "additional kind of interceptors normally not supported by other languages" (similiar to the section "Message Interception Techniques" in the tutorial).
Your concern seems to be mostly the "name" interceptor. The commands have to do with what's sometimes is called "write introspection" in analogy to "read introspection", where you query some properties and relations of created artefacts. The former lets you change some properties/relations.
The normal xotcl interface to (stack-independet) introspection is the info command. The pattern to change things is
set old [X info PROPERTY] X PROPERTY [modify $old]
where property is for example mixin, instmixin, filter, instfilter. The same pattern works with some more properties such as "superclass", or to some extend "class" as well. Some of the read-introspectable tcl properties such as [info body ...] or [info args] or [info default] could be made writable as well, but the benefit compared to a proc command would be relative small.
I am not a big friend of magic variables as base mechanism, since otcl did not let me allow to use "class" or "proc" as names of instance variables. Methods are better since they can be easily refined.
Look at the following study; it does not have the switch ugliness with different arglists, it is extensible and interceptible:
Object introspection introspection proc get {obj prop} {$obj info $prop} introspection proc set {obj prop value} {$obj $prop $value} introspection proc add {obj prop value {pos 0}} { $obj $prop [linsert [$obj info $prop] $pos $value] } introspection proc delete {obj prop value} { set old [$obj info $prop] set p [lsearch -glob $old $value] if {$p>-1} {$obj $prop [lreplace $old $p $p]} else { error "$value is not a $prop of $obj ($old)" } } introspection proc unknown {m args} { puts "method '$m' unknown for [self]" puts " valid commands are: {[lsort [my info procs]]}" }
we can define a filter to see the consequences of our doings:
introspection proc i-filter {obj args} { set r [next] if {[string compare $args ""] && [my isobject $obj]} { set prop [lindex $args 0] puts "$prop of $obj = [$obj info $prop]" } return $r } introspection filter i-filter
now we can try it out:
Object o1 introspection add o1 mixin A introspection add o1 mixin B introspection add o1 mixin C end introspection delete o1 mixin *A introspection delete o1 mixin *A
well, we can shuffle the arguments in a little reflector instproc:
Object instproc introspection {cmd prop args} { eval introspection $cmd [self] $prop $args } o1 introspection add mixin A
and we have an "... introspection get ..." and friends again and get an error message for a
o1 introspection cancel mixin A
.... but: i am not so happy about the name "introspection" in "introspection set" and "introspection add" as well, since it requires familiarity with "write introspection" which is not only a "*spection" in the sense of "looking into", but destructive.
suggestions?
-gustaf neumann
Univ.Prof. Dr.Gustaf Neumann Abteilung für Wirtschaftsinformatik WU-Wien, Augasse 2-6, 1090 Wien _______________________________________________ Xotcl mailing list - Xotcl@alice.wu-wien.ac.at http://alice.wu-wien.ac.at/mailman/listinfo/xotcl