Scott Gargash schrieb:
I've been thinking along somewhat different lines, the classic "extra level of indirection" that solves all problems. What about using interpreter aliases as an indirection? What would happen if all objects were created as anonymous commands inside (say) the xotcl namespace, and the object name was just an alias to the anonymous object?
you can do this easily by your own in xotcl. redefine e.g. unknown for classes (or provide a mixin for create), and create objects via new and add the alias.
==================================== Class instproc unknown {name args} { set o [eval my new $args] ::interp alias {} $name {} $o return $name } ====================================
so, now we can test the aliased content. it behaves in many respects the same, but when it comes to refer to "self" or to namespaces one would notice a different behavior: ==================================== Class create Person -parameter {age} Person p1 -age 123
puts [p1 age] puts [p1 self] ====================================
As you noted, one can switch in such a universe the aliases to "move" objects quickly. ==================================== Object instproc move {newname} { foreach a [::interp aliases] { if {[::interp alias {} $a] eq [self]} {set oldname $a;break} } ::interp alias {} $newname {} [self] ::interp alias {} $oldname {} } p1 move p2
puts [p2 age] puts [p2 self] ====================================
most probably, an associative array to keep the aliases is more efficient than the loop through all aliases, once there are many objects.
Note, that "self" remains the same.
If you need this kind of behavior for certain kind of objects, you can certainly use a base-class RefObject or whatever, and subclass the application classes from it.... This kind of objects will vertainly need a destroy method to delete the alias as well.
-gustaf neumann
On 18 Mar 2006, at 02:48, Gustaf Neumann wrote:
so, now we can test the aliased content. it behaves in many respects the same, but when it comes to refer to "self" or to namespaces one would notice a different behavior:
Could this kind of system be used throughout XOTcl and thus have [self] return the alias too, instead of the actual instance? As mentioned, this could potentially solve the issue with object movement.
xotcl-bounces@alice.wu-wien.ac.at wrote on 03/18/2006 01:45:12 AM:
On 18 Mar 2006, at 02:48, Gustaf Neumann wrote:
so, now we can test the aliased content. it behaves in many respects the same, but when it comes to refer to "self" or to namespaces one would notice a different behavior:
Could this kind of system be used throughout XOTcl and thus have [self] return the alias too, instead of the actual instance? As mentioned, this could potentially solve the issue with object movement.
I was wondering the same thing. What would be the impact on XOTcl's implementation if an object's location in Tcl's namespace hierachy was invariant, and user access to the object was always indirected through an alias? I would guess that it's not worthwhile just for "move" functionality, but would this guarantee make any other things possible, easier, or more efficient?
Scott
Scott Gargash schrieb:
xotcl-bounces@alice.wu-wien.ac.at wrote on 03/18/2006 01:45:12 AM:
On 18 Mar 2006, at 02:48, Gustaf Neumann wrote:
so, now we can test the aliased content. it behaves in many respects the same, but when it comes to refer to "self" or to namespaces one would notice a different behavior:
Could this kind of system be used throughout XOTcl and thus have [self] return the alias too, instead of the actual instance? As mentioned, this could potentially solve the issue with object movement.
try it out, make up your mind. As shown, a few lines of code can already implement most of the work, "self" can be reimplemented in tcl as well with little effort to return the (or one of the) aliases. the xotcl regression test is already a good benchmark and testing base.
I was wondering the same thing. What would be the impact on XOTcl's implementation if an object's location in Tcl's namespace hierachy was invariant, and user access to the object was always indirected through an alias? I would guess that it's not worthwhile just for "move" functionality, but would this guarantee make any other things possible, easier, or more efficient?
I do not see much evidence of a speed increase when adding a layer of indirection for every object access.
if the goal of such a project is "everything should be the same as in xotcl now, but move should be faster", then i would estimate a man-month of work of somebody with some tcl/xotcl c-level experience (like uwe or me). without looking into the details, i would expect problems from instrospection (including call stack), namespace handling (namespace import/exports, namespace completion), dynamic aggregation (creation, cleanup, semantics, when e.g. an alias is moved), and most probably many more hurldes will show up when going into the details. In general, it is possible to have multiple aliases (references) pointing to a physical object, in some cases you are interested in the namespace of the reference(s), in others in the namespace of the object.
alltogether, it is certainly an interesting exercise considering such a strucure in general (therefore i wrote the simple example). However, one could go much further: Thinking loudly: Since xotcl objects/classes are tcl_objs pointing to a c-structure representing the object/classes in c, and the tcl_objs are refcounted refcounted, i would think there could be ways achieving the flexibiliy even without indirection. Currently, these tcl_objs are bound to a single tcl-command. The aliasing effect could be achived in theory by using these tcl_objs in multiple tcl commands. I would expect some deeper changes here: what happens, if a child object is added under one name of the object; will this be visible for another name of the same object as well? If we continue to see an object as a object tree, it should. i expect here the same problems with namespaces as indicated earlier with the namespace rename command.
-gustaf neumann
Scott
Xotcl mailing list Xotcl@alice.wu-wien.ac.at http://alice.wu-wien.ac.at/mailman/listinfo/xotcl
Gustaf Neumann neumann@wu-wien.ac.at wrote on 03/18/2006 01:39:35 PM:
I do not see much evidence of a speed increase when adding a layer of indirection for every object access.
Well, for example, it might be possible to get rid of namespaces in the implementation. If the access to the object is always through the reference and the true object was never visible, you might not have to create a new namespace (on demand or not) or ever move an existing object to make it a child of another object. The parent/subobject relationship could be inferred from the alias's location in the namespace, or even tracked in child/parent hash tables if you wanted to support object relationships beyond a tree (DAGs), but it would not be a property of the object's location. If objects never moved, everything could live in the same namespace, and just tracked via the object hashes. And is method dispatch done via a command lookup? If so, an invariant method location should allow command lookup to be elided.
Of course, since I'm the one who keeps asking "How do I do this?" questions, I'm probably completely wrong. BTW, does invocation via an alias have any overhead? I would guess not as it's (seems like) a string->Tcl_Obj mapping, the same as a native command lookup, but I don't know.
if the goal of such a project is "everything should be the same as in xotcl now, but move should be faster", then i would estimate a man-month of work of somebody with some tcl/xotcl c-level experience (like uwe or me). without looking into the details, i would expect problems from instrospection (including call stack), namespace handling (namespace import/exports, namespace completion), dynamic aggregation (creation, cleanup, semantics, when e.g. an alias is moved), and most probably many more hurldes will show up when going into the details.
I can't imagine it's a useful effort simply to optimize "move", and I'd also guess that some things might be faster, some would be slower, and some would be incompatible with such a design. It would have to have more payoff than speeding up "move" to to justify it.
In general, it is possible to have multiple aliases (references) pointing to a physical object, in some cases you are interested in the namespace of the reference(s), in others in the namespace of the object.
When would you need the namespace of the object? If all you have is the reference (the handle is truly opaque), you'd have no knowledge of the namespace of the object. Containment would have to be implemented instead of just inferred, but if it's implemented it could have new properties.
This is what I meant by making new things possible. As you say, if you have references you can have multiple references to the same object. Object hierarchies could be a directed graph instead of a tree. I can imagine cases where that would be useful. (I can also imagine cases where it's a bug...)
As an aside, I find Tcl's lack of true references to be one of its nagging flaws.
it is certainly an interesting exercise considering such a strucure in general (therefore i wrote the simple example).
Yes, this is just a thought experiment, not a proposal.
However, one could go much further: Thinking loudly: Since xotcl objects/classes are tcl_objs pointing to a c-structure representing the object/classes in c, and the tcl_objs are refcounted refcounted, i would think there could be ways achieving the flexibiliy even without indirection. Currently, these tcl_objs are bound to a single tcl-command. The aliasing effect could be achived in theory by using these tcl_objs in multiple tcl commands. I would expect some deeper changes here: what happens, if a child object is added under one name of the object; will this be visible for another name of the same object as well? If we continue to see an object as a object tree, it should. i expect here the same problems with namespaces as indicated earlier with the namespace rename command.
I agree. I think as long as the implementation and the interface for containment are the same (namespace aggregation), the renaming problem remains. The handle needs to be opaque to break the implementation dependency.
Scott
Scott Gargash schrieb:
Gustaf Neumann neumann@wu-wien.ac.at wrote on 03/18/2006 01:39:35 PM:
I do not see much evidence of a speed increase when adding a layer of indirection for every object access.
Well, for example, it might be possible to get rid of namespaces in the implementation.
thinking about getting rid of namespaces is a different theme, this can be done as well without "strongly aliased objects".
namespaces are pretty essential in tcl. every command name lookup works through a namespace. xotcl uses tcl-namespaces for methods (procs and instprocs), for variables, and for aggregations. certainly, this could be implemented differently, frequently we have to fight with namespaces, but the idea was to reuse concepts from tcl in xotcl. Using tcl-namespaces has many advantages as well: currently, we can rename tcl-procs or tcl-commands to make it methods in xotcl; or we can namespace-import procs/cmds from tcl as methods/instmethods etc. into xotcl with the standard tcl-commands.
If the access to the object is always through the reference and the true object was never visible, you might not have to create a new namespace (on demand or not)
i can't follow the argument.... what ist the relationship with the visibility? namespaces are used for various purposes: methods are tcl_procs or tcl-commands and have to "live" somewhere, in tcl they live in namespaces. one can certainly implement this differently as in tcl, as for example using hash-tables only, but this is not related to visibility. btw, if you never show the real name to the application developer, it will be hard to create multiple references other than by creating an alias of the alias.
or ever move an existing object to make it a child of another object. The parent/subobject relationship could be inferred from the alias's location in the namespace, or even tracked in child/parent hash tables if you wanted to support object relationships beyond a tree (DAGs), but it would not be a property of the object's location. If objects never moved, everything could live in the same namespace, and just tracked via the object hashes.
And is method dispatch done via a command lookup? If so, an invariant method location should allow command lookup to be elided.
whatever "same namespace" means (see above). note that we have multiple identical method names in procs/classes, they can't live in the same namespace. if the nesting relationship is realized via the namespaces of the aliases, these have to be created as well since they will most likely not exist. This way, they namespaces are moved out of the xotcl objects, but introduced at different places, where they are more complicated to manage. some interactions with namespaces will be even more complicated as they are now: you have to deal with cases, where e.g. someome deletes the alias (e.g. via "rename myreference {}") or deletes the namepace, where the alias lives in.
Of course, since I'm the one who keeps asking "How do I do this?" questions, I'm probably completely wrong. BTW, does invocation via an alias have any overhead? I would guess not as it's (seems like) a string->Tcl_Obj mapping, the same as a native command lookup, but I don't know.
an "interp alias" has a certain overhead, since it is an additional command invocation. Try the following; if you increment the loop counter in the for loop to e.g. 1000, you will get a "too many nested evaluations" error. you will see, the last test will be the slowest by far.
========================================================== proc t {cmd {txt ""}} { set n 100000 set ms [lindex [time [list time $cmd $n] 10] 0] puts "[format %7.4f [expr {$ms*1.0/$n}]]ms for $cmd ($txt)" }
proc x {} {set x 1} interp alias {} myset {} set interp alias {} myx {} x interp alias {} myx1 {} x
for {set i 1} {$i < 100} {incr i} { set i1 [expr {$i+1}] interp alias {} myx$i1 {} myx$i }
t {set x 1} "set" t {myset x 1} "myset"
t {x} "x" t {myx} "myx" t myx$i1 myx$i1 ==========================================================
It is however possible to implement zero-overhead aliases with the tcl c-api, at least in certain situations, when one does not care about someone else replacing commands on the fly with global effects. I have implemented such things by myself.
best regards -gustaf neumann
Thanks for your patience with me and my ignorance. I had inferred that XOTcl was using Tcl namespaces for storing object attributes (methods/variables/aggregations), but in my limited usage I didn't realize that that was (legally) being used to advantage (making plain tcl commands become xotcl methods via namespace import or the like). So far I've been assuming the only legal way to manipulate the object was through its handle (the object command).
Given my assumption, my thought was that you could cleanly substitute Tcl's namespace mechanism with a hash-table lookup (attribute name -> Tcl_Obj *) for finding object attributes. Since each object would have its own table, so there's no problem with name collisions (a attribute name is scoped by the object you access it through, i.e., each object has its own set of slots), and if an object can only be accessed through its handle, the handle is the only thing that needs to be exposed to the interpreter. None of the attributes would be visible to Tcl at all (Except to the extent XOTcl exposed them. You could still have traces and whatnot, but you'd have to use the object handle to access them). And if the objects were always accessed via a level of indirection, the raw object handle (the true command name) is uninteresting too, so all objects be created with autonames in the same namespace. And that this sort of an implementation (using a custom attribute lookup mechanism instead of leveraging Tcl's) might potentially have some performance wins and/or new feature possibilities.
But from your explanation, using Tcl namespaces to store object attributes is not just an implementation decision, it's really part of the interface, so my approach would break XOTcl in varied and uninteresting ways.
Scott
Gustaf Neumann neumann@wu-wien.ac.at wrote on 03/18/2006 06:52:25 PM:
Scott Gargash schrieb:
Gustaf Neumann neumann@wu-wien.ac.at wrote on 03/18/2006 01:39:35 PM:
I do not see much evidence of a speed increase when adding a layer of indirection for every object access.
Well, for example, it might be possible to get rid of namespaces in the implementation.
thinking about getting rid of namespaces is a different theme, this can be done as well without "strongly aliased objects".
namespaces are pretty essential in tcl. every command name lookup works through a namespace. xotcl uses tcl-namespaces for methods (procs and instprocs), for variables, and for aggregations. certainly, this could be implemented differently, frequently we have to fight with namespaces, but the idea was to reuse concepts from tcl in xotcl. Using tcl-namespaces has many advantages as well: currently, we can rename tcl-procs or tcl-commands to make it methods in xotcl; or we can namespace-import procs/cmds from tcl as methods/instmethods etc. into xotcl with the standard tcl-commands.
If the access to the object is always through the reference and the true object was never visible, you might not have to create a new namespace (on demand or not)
i can't follow the argument.... what ist the relationship with the visibility? namespaces are used for various purposes: methods are tcl_procs or tcl-commands and have to "live" somewhere, in tcl they live in namespaces. one can certainly implement this differently as in tcl, as for example using hash-tables only, but this is not related to visibility. btw, if you never show the real name to the application developer, it will be hard to create multiple references other than by creating an alias of the alias.
or ever move an existing object to make it a child of another object. The parent/subobject relationship could be inferred from the alias's location in the namespace, or even tracked in child/parent hash tables if you wanted to support object relationships beyond a tree (DAGs), but it would not be a property of the object's location. If objects never moved, everything could live in the same namespace, and just tracked via the object hashes.
And is method dispatch done via a command lookup? If so, an invariant method location should allow command lookup to be elided.
whatever "same namespace" means (see above). note that we have multiple identical method names in procs/classes, they can't live in the same namespace. if the nesting relationship is realized via the namespaces of the aliases, these have to be created as well since they will most likely not exist. This way, they namespaces are moved out of the xotcl objects, but introduced at different places, where they are more complicated to manage. some interactions with namespaces will be even more complicated as they are now: you have to deal with cases, where e.g. someome deletes the alias (e.g. via "rename myreference {}") or deletes the namepace, where the alias lives in.
Of course, since I'm the one who keeps asking "How do I do this?" questions, I'm probably completely wrong. BTW, does invocation via an alias have any overhead? I would guess not as it's (seems like) a string->Tcl_Obj mapping, the same as a native command lookup, but I don't know.
an "interp alias" has a certain overhead, since it is an additional command invocation. Try the following; if you increment the loop counter in the for loop to e.g. 1000, you will get a "too many nested evaluations" error. you will see, the last test will be the slowest by far.
========================================================== proc t {cmd {txt ""}} { set n 100000 set ms [lindex [time [list time $cmd $n] 10] 0] puts "[format %7.4f [expr {$ms*1.0/$n}]]ms for $cmd ($txt)" }
proc x {} {set x 1} interp alias {} myset {} set interp alias {} myx {} x interp alias {} myx1 {} x
for {set i 1} {$i < 100} {incr i} { set i1 [expr {$i+1}] interp alias {} myx$i1 {} myx$i }
t {set x 1} "set" t {myset x 1} "myset"
t {x} "x" t {myx} "myx" t myx$i1 myx$i1 ==========================================================
It is however possible to implement zero-overhead aliases with the tcl c-api, at least in certain situations, when one does not care about someone else replacing commands on the fly with global effects. I have implemented such things by myself.
best regards -gustaf neumann
ForwardSourceID:NT00007E9E
On 19 Mar 2006, at 00:12, Scott Gargash wrote:
When would you need the namespace of the object? If all you have is the reference (the handle is truly opaque), you'd have no knowledge of the namespace of the object. Containment would have to be implemented instead of just inferred, but if it's implemented it could have new properties.
I have only ever needed the namespace of an object which attaching traces to variables (f.ex. with Tk), but for that it is, unfortunately quite necessary.
As an aside, I find Tcl's lack of true references to be one of its nagging flaws.
Yes, this is a problem. If Tcl had proper references then we could do garbage collection for objects. The problem is that Tcl's principle of everything being a string kind of conflicts with references. References can be represented as strings, although not very useful strings, but they really aren't strings. I mean, if the string output for a reference is 0x123456, but I generated that through some other string operations (or, say we lose the original Tcl object through various operations) then that will no longer necessarily work as a reference if the original is gone.
This is particularly problematic as Tcl still has quite a habit of losing that original representation which naturally I hope will be reduced in the future.
xotcl-bounces@alice.wu-wien.ac.at wrote on 03/19/2006 04:08:40 AM:
On 19 Mar 2006, at 00:12, Scott Gargash wrote:
When would you need the namespace of the object?
I have only ever needed the namespace of an object which attaching traces to variables (f.ex. with Tk), but for that it is, unfortunately quite necessary.
I haven't used it yet, but doesn't the "trace" method handle this?
As an aside, I find Tcl's lack of true references to be one of its nagging flaws.
Yes, this is a problem. If Tcl had proper references then we could do garbage collection for objects. The problem is that Tcl's principle of everything being a string kind of conflicts with references. References can be represented as strings, although not very useful strings, but they really aren't strings. I mean, if the string output for a reference is 0x123456, but I generated that through some other string operations (or, say we lose the original Tcl object through various operations) then that will no longer necessarily work as a reference if the original is gone.
Amen, brother. For years I've tossed around thoughts on how to have references in Tcl, but I can't come up with a way to do it without breaking "everything is a string". And if that breaks, well, it's not Tcl anymore.
But I want lambdas. :)
This is particularly problematic as Tcl still has quite a habit of losing that original representation which naturally I hope will be reduced in the future.
Where do you see this happening? Do you mean losing the original representation via shimmering, or something else?
Scott
On 19 Mar 2006, at 14:09, Scott Gargash wrote:
xotcl-bounces@alice.wu-wien.ac.at wrote on 03/19/2006 04:08:40 AM:
On 19 Mar 2006, at 00:12, Scott Gargash wrote:
When would you need the namespace of the object?
I have only ever needed the namespace of an object which attaching traces to variables (f.ex. with Tk), but for that it is, unfortunately quite necessary.
I haven't used it yet, but doesn't the "trace" method handle this?
No. Some tk widgets map their values to Tcl variables. Other similar interfaces exist. It is handy to map them to an instance variable but for that it is necessary to have the namespaced version available. Of course you could always do it through globals, but that is just more messy.
But I want lambdas. :)
I think something similar was making its way into Tcl?
This is particularly problematic as Tcl still has quite a habit of losing that original representation which naturally I hope will be reduced in the future.
Where do you see this happening? Do you mean losing the original representation via shimmering, or something else?
I've seen it happen with scripts given to [after]. I was actually very surprised by this, but at some point I was witnessing those scripts becoming strings and thus losing the original Tcl_Objs inside them (the scripts were built as lists).
xotcl-bounces@alice.wu-wien.ac.at wrote on 03/19/2006 05:32:31 AM:
On 19 Mar 2006, at 14:09, Scott Gargash wrote:
xotcl-bounces@alice.wu-wien.ac.at wrote on 03/19/2006 04:08:40 AM:
On 19 Mar 2006, at 00:12, Scott Gargash wrote:
When would you need the namespace of the object?
I have only ever needed the namespace of an object which attaching traces to variables (f.ex. with Tk), but for that it is, unfortunately quite necessary.
I haven't used it yet, but doesn't the "trace" method handle this?
No. Some tk widgets map their values to Tcl variables. Other similar interfaces exist. It is handy to map them to an instance variable but for that it is necessary to have the namespaced version available.
Snit has a "myvar" method that returns the fully qualified name of a snit member variable. Perhaps something similiar (a method that returned a "reference" to an instance variable) would be useful in XOTcl?
Scott
On 19 Mar 2006, at 14:49, Scott Gargash wrote:
Snit has a "myvar" method that returns the fully qualified name of a snit member variable. Perhaps something similiar (a method that returned a "reference" to an instance variable) would be useful in XOTcl?
Yes, quite possibly, but of course then you need some namespace logic, at least internally. Still, it sounds like, whatever the implementation, that might be a good addition to XOTcl as it hides the implementation details.
Scott Gargash schrieb:
xotcl-bounces@alice.wu-wien.ac.at wrote on 03/19/2006 05:32:31 AM:
On 19 Mar 2006, at 14:09, Scott Gargash wrote:
xotcl-bounces@alice.wu-wien.ac.at wrote on 03/19/2006 04:08:40 AM:
On 19 Mar 2006, at 00:12, Scott Gargash wrote:
When would you need the namespace of the object?
I have only ever needed the namespace of an object which attaching traces to variables (f.ex. with Tk), but for that it is, unfortunately quite necessary.
I haven't used it yet, but doesn't the "trace" method handle this?
No. Some tk widgets map their values to Tcl variables. Other similar interfaces exist. It is handy to map them to an instance variable but for that it is necessary to have the namespaced version available.
Snit has a "myvar" method that returns the fully qualified name of a snit member variable. Perhaps something similiar (a method that returned a "reference" to an instance variable) would be useful in XOTcl?
well, without trying it out. variable_reference could look like:
Object instproc variable_reference name { my requireNamespace return [self]::$name }
in many situations, these fully qualified variable references are not needed, since e.g. the forwarder allows variable names to be used in scope of an object, such that e.g.
obj set x 100 obj lappend y 1 2 3
does the right thing (interpret variable references x and y in the obj scope), no matter whether obj has a object-specific namespace or not. It would be rather painful to write
obj lappend [obj variable_reference y] 1 2 3
These forwarders are registered during startup via:
foreach cmd {array append lappend trace eval unset} { ::xotcl::Object instforward $cmd -objscope }
-gustaf neumann
Snit has a "myvar" method that returns the fully qualified name of a snit member variable. Perhaps something similiar (a method that returned a "reference" to an instance variable) would be useful in XOTcl?
I use the following two global procs for that:
proc myproc {args} {linsert $args 0 [uplevel 1 self]} proc myvar {var} {return [uplevel 1 self]::$var}
The procs are global (not instprocs on "Object") because otherwise I would have to write "my myvar" or "my myproc". Now I can simply use them in the following way inside xotcl (inst)procs:
button $x -command [myproc show 1 2 3] ... trace add variable [myvar status] write [myproc statusevent] ... vwait [myvar done]
(Note: in fact the "uplevel" in the definition of myproc/myvar is not even necessary. It seems that [self] always refers to the last Xotcl object on the callstack.)
Koen
On 20 Mar 2006, at 12:10, Koen Danckaert wrote:
Snit has a "myvar" method that returns the fully qualified name of a snit member variable. Perhaps something similiar (a method that returned a "reference" to an instance variable) would be useful in XOTcl?
I use the following two global procs for that:
proc myproc {args} {linsert $args 0 [uplevel 1 self]} proc myvar {var} {return [uplevel 1 self]::$var}
The procs are global (not instprocs on "Object") because otherwise I would have to write "my myvar" or "my myproc". Now I can simply use them in the following way inside xotcl (inst)procs:
Aren't you forgetting the [requireNamespace] from the above code?
Koen Danckaert schrieb:
I use the following two global procs for that:
proc myproc {args} {linsert $args 0 [uplevel 1 self]} proc myvar {var} {return [uplevel 1 self]::$var}
as kristoffer noted (and as in my earlier version shows) it makes sense to add a requireNamespace to myvar. a slightly faster version of myproc is:
button $x -command [myproc show 1 2 3] ... trace add variable [myvar status] write [myproc statusevent]
you can use here as well
my trace add variable status write [myproc statusevent]
(Note: in fact the "uplevel" in the definition of myproc/myvar is not even necessary. It seems that [self] always refers to the last Xotcl object on the callstack.)
self returns the current object from the xtcl call stack. if one calls a pure tcl-proc or tcl-cmd from an xotcl method, the same xotcl callstack entry is still active. so [self] continues to return "the right" obejct.
therefore, a slightly faster version is:
proc myproc {args} {linsert $args 0 [self]}
seems as a good idea to add both methods to the xotcl distribution.
Shouldn't we use "mymethod" instead of myproc, this function will not only work for procs, but for instprocs and cmds as well....
-gustaf neumann
Gustaf Neumann wrote:
proc myproc {args} {linsert $args 0 [uplevel 1 self]} proc myvar {var} {return [uplevel 1 self]::$var}
as kristoffer noted (and as in my earlier version shows) it makes sense to add a requireNamespace to myvar.
I usually put the requireNamespace in the "init" method (when it's needed). But I agree that the overhead of putting it in myvar would be negligible.
trace add variable [myvar status] write [myproc statusevent]
you can use here as well
my trace add variable status write [myproc statusevent]
Ah, ok, I'm used to the forwarders for lappend/unset etc, but didn't notice about trace yet. I now see that there is one for vwait, too.
Shouldn't we use "mymethod" instead of myproc, this function will not only work for procs, but for instprocs and cmds as well....
I used myproc because the name "method" isn't used anywhere in XOTcl. But indeed, myproc seems to indicate that it only works for procs, which is wrong of course.
Koen
Koen Danckaert schrieb:
Gustaf Neumann wrote:
proc myproc {args} {linsert $args 0 [uplevel 1 self]} proc myvar {var} {return [uplevel 1 self]::$var}
as kristoffer noted (and as in my earlier version shows) it makes sense to add a requireNamespace to myvar.
I usually put the requireNamespace in the "init" method (when it's needed).
Same with me ...
But I agree that the overhead of putting it in myvar would be negligible.
the point is to make things more robust to beginners...
I used myproc because the name "method" isn't used anywhere in XOTcl.
well we have at least "info methods"; i am trying to use the following terminology: we have object specific methods - proc - forward - cmd and class defined methods - instproc - instforward - instcmd (e.g "create" of Class, or "destroy" of Object). when we call one of these, we have method invocations. If we do not distinguish between these variants, "method" seems the right term. "mymethod" is a little bit longer and not so crisp as "myproc".
I have added "::xotcl::mymethod" and "::xotcl::myvar" to my development version. i guess, you would you prefer to have these exported. Opinions?
-gustaf neumann
On 20 Mar 2006, at 14:46, Gustaf Neumann wrote:
I have added "::xotcl::mymethod" and "::xotcl::myvar" to my development version. i guess, you would you prefer to have these exported. Opinions?
On giving it some thought I think I actually prefer the version that would be part of Object. After all, it is that object's variable that we want. I don't use it that frequently so I don't mind writing a bit extra, for clarity's sake.
I'm also wondering what the name should be, to make it really clear. Is [my var] clear enough? or should it be [my normalisedVar]?
Kristoffer Lawson schrieb:
I have added "::xotcl::mymethod" and "::xotcl::myvar" to my development version. i guess, you would you prefer to have these exported. Opinions?
On giving it some thought I think I actually prefer the version that would be part of Object. After all, it is that object's variable that we want. I don't use it that frequently so I don't mind writing a bit extra, for clarity's sake.
i am open for everything.
I'm also wondering what the name should be, to make it really clear. Is [my var] clear enough? or should it be [my normalisedVar]?
"my var" is not a good option, "my varname" would be better,
furthermore, "my method" is already defined, getting a good name with method seems messy. how about:
my trace add variable status write [my callback statusevent]
-gustaf neumann
I have added "::xotcl::mymethod" and "::xotcl::myvar" to my development version. i guess, you would you prefer to have these exported. Opinions?
On giving it some thought I think I actually prefer the version that would be part of Object. After all, it is that object's variable that we want.
Well, in any case we're not adding new functionality here, we're just adding convenience procedures to write callbacks in a more concise and readable way. I believe this is best achieved by having 2 short and concise keywords. In my code, "myproc foo" (vs "my foo") indicates clearly that I'm not actually calling foo, just referring to it. This distinction would be less clear with "my callback foo".
So indeed, if these keywords would be predefined in xotcl, I would prefer to have them exported, otherwise they'd not be short and concise either :-)
I don't use it that frequently so I don't mind writing a bit extra, for clarity's sake.
I use it quite often. It's a very common construct in Tk and event-based scripts, I think. I've even customized my editor to highlight "myproc" and "myvar", such that they spring out immediately.
Koen
On 20 Mar 2006, at 18:13, Koen Danckaert wrote:
I have added "::xotcl::mymethod" and "::xotcl::myvar" to my development version. i guess, you would you prefer to have these exported. Opinions?
On giving it some thought I think I actually prefer the version that would be part of Object. After all, it is that object's variable that we want.
Well, in any case we're not adding new functionality here, we're just adding convenience procedures to write callbacks in a more concise and readable way. I believe this is best achieved by having 2 short and concise keywords. In my code, "myproc foo" (vs "my foo") indicates clearly that I'm not actually calling foo, just referring to it. This distinction would be less clear with "my callback foo".
I still think the original proposal does not actually describe what is going on. "My proc? What my proc? This is a proc, what's the matter with it?". Besides, splitting the functionality into a method means we can use it on other objects than our[selves].
This is more than just shorthand. It's also about hiding the details of method and variable implementation. It just feels cleaner to get a real variable reference through some procedural call, instead of building it up yourself based on namespace assumptions.
So indeed, if these keywords would be predefined in xotcl, I would prefer to have them exported, otherwise they'd not be short and concise either :-)
Yes, if the solution ends up being based on top-level commands, then exporting them sounds reasonable.
I don't use it that frequently so I don't mind writing a bit extra, for clarity's sake.
I use it quite often. It's a very common construct in Tk and event- based scripts, I think. I've even customized my editor to highlight "myproc" and "myvar", such that they spring out immediately.
It's only really necessary for variables which are linked to other systems as for callbacks you can generally do f.ex.:
after 100 [list [self] doStuff]
which is what I actually do. I mean, presumably the problem with using a method by its direct namespace is also that filters get avoided, or? (at least I think it was that way at some point in XOTcl's history). That, to me, would mean it's not a good method except for very specific cases.
xotcl-bounces@alice.wu-wien.ac.at wrote on 03/20/2006 12:29:57 PM:
On 20 Mar 2006, at 18:13, Koen Danckaert wrote:
I have added "::xotcl::mymethod" and "::xotcl::myvar" to my development version. i guess, you would you prefer to have these exported. Opinions?
On giving it some thought I think I actually prefer the version that would be part of Object. After all, it is that object's variable that we want.
I also think it should be methods. An object owns its methods/variables, you should have to ask the object for a reference. Just reach in from outside and grabbing a reference feels...rude.
Asking the object also gives it a chance to overload it. I can't imagine why, but an object might want to know that something has a reference to its internal state.
It's only really necessary for variables which are linked to other systems as for callbacks you can generally do f.ex.:
after 100 [list [self] doStuff]
which is what I actually do. I mean, presumably the problem with using a method by its direct namespace is also that filters get avoided, or? (at least I think it was that way at some point in XOTcl's history). That, to me, would mean it's not a good method except for very specific cases.
I would expect that [list [self] dostuff] is what [my &method doStuff] returns. Isn't that the desired behavior to return a list that when evaluated acts as though you have invoked the method on the object?
At least, that's what snit does with "mymethod". Although snit doesn't have nearly the same design space as XOTcl, so maybe it's not comparable.
Scott
Kristoffer Lawson schrieb:
It's only really necessary for variables which are linked to other systems as for callbacks you can generally do f.ex.:
after 100 [list [self] doStuff]
which is what I actually do. I mean, presumably the problem with using a method by its direct namespace is also that filters get avoided, or? (at least I think it was that way at some point in XOTcl's history). That, to me, would mean it's not a good method except for very specific cases.
please, check more carefully, what has been posted and discussed. Koen's original "myproc" (renamed to "mymethod") is NOT about prepending a namespace prefix to a method name, but is nothing more than a shortform for "list [self] ..."). In your example one would be able to register the callback to after with
after 100 [mymethod foo 1 2 3]
or by the method variant
after 100 [my callback foo 1 2 3]
Since the idiom [list [self] .... ] is used for registering callbacks, naming suggestions like "methodName" or variants with "namespace" are not appropriate.
i do not like the &-suggestions for the xotcl-core, since it looks like an operator, not like a name. The &-operator is not about fully qualifying a name, but about providing a reference in general.
i get the impression that adding these cmds/methods do not reduce significantly the clarity. myvar/myvarname makes sense for the snitters.
-gustaf neumann
xotcl-bounces@alice.wu-wien.ac.at wrote on 03/21/2006 02:28:15 AM:
i do not like the &-suggestions for the xotcl-core, since it looks like an operator, not like a name. The &-operator is not about fully qualifying a name, but about providing a reference in general.
What's the difference (in tcl) between a name and an operator or a name and a reference?
I'm not being sarcastic, you're making a distinction I don't see. The problem here is needing an external reference to an XOTcl member. In Tcl, that means you need the name of the variable.
i get the impression that adding these cmds/methods do not reduce significantly the clarity. myvar/myvarname makes sense for the snitters.
While that may be true for an experienced user, as a new user trying to use XOTcl I find the way XOTcl uses namespaces (created on demand) to be pretty confusing. Anything that keeps me from needing to understand that is a good thing. And leaving aside the new user issue, having a documented access mechanism for clients instead of knowledge of the implementation seems like a good thing.
Just my opinion.
Scott
Scott Gargash schrieb:
xotcl-bounces@alice.wu-wien.ac.at wrote on 03/21/2006 02:28:15 AM:
i do not like the &-suggestions for the xotcl-core, since it looks like an operator, not like a name. The &-operator is not about fully qualifying a name, but about providing a reference in general.
What's the difference (in tcl) between a name and an operator or a name and a reference?
I'm not being sarcastic, you're making a distinction I don't see.
i don't think, that you are expecting an detailed anwser. for example, a prefix operator is a syntactical construct you can put in front of some other syntactical construct to express some intention. One can for example put a "-" in front of a number to express that you want to use its negative value. Similary, one can put a "$" sign in front of every variable name in tcl to access the value of the variable. I would expect from a operator & to be as general, to work the same way, no matter whether the variable is global, on a stack frame, or in an object.
The problem here is needing an external reference to an XOTcl member. In Tcl, that means you need the name of the variable.
unfortunately this is currently not true in general. To reference e.g. a variable on some stack frame, you will need upvar or similar constructs. maybe someone writes a name resolver to achieve this, or implements a command to achieve this a some time. Maybe then someone decides to use & for such purposes.
i get the impression that adding these cmds/methods do not reduce significantly the clarity. myvar/myvarname makes sense for the snitters.
While that may be true for an experienced user, as a new user trying to use XOTcl I find the way XOTcl uses namespaces (created on demand) to be pretty confusing. Anything that keeps me from needing to understand that is a good thing. And leaving aside the new user issue, having a documented access mechanism for clients instead of knowledge of the implementation seems like a good thing.
Maybe i made the mistake to explain some details (that a normal user does not need to know) in order to dicuss the ease and feasability of some proposed constructs. xotcl tries to hide tcl-namespaces to a good deal, but sometimes they look through. as explained earlier, tcl-namespaces are simplifying xotcl in some respects, in other respects they are a burden.
i certainly agree that providing a standard way of accessing instvars helps, therefore i think we should add a command or method to xotcl to do so.
snit uses snit::myvar and snit::varname (just a second name for the same command) and snit::mymethod (the latter one as an alternative to [list somemagic somemethod someargs]). itcl uses itcl::code for the latter.
So, in order to stick to these names, using ::xotcl::myvar and ::xotcl::mymethod and exporting these seems as a good idea. Exporting can turn out to be a problem when someone uses snit and xotcl at the same time and needs to namespace import both for some reason. I am somewhat unhappy that these commands suggest some non-existing symmetry (myvar refers to an object-variable, while mymethod constructs a command from a method name, and the method name is not restricted to be defined within a command (or tcl-namespace)).
When using methodnames for the discussed functionality, we should invent new names, since [my myvar ... ] and [my mymethod ...] look somewhat strange. for ::xotcl::myvar, i think [my varname ...] is fine. for mymethod the naming is harder. What is an improvement over "[list [self] method args]"? "my code foo args", "my cmd foo args", "my invokecmd foo args", "my callbackcmd foo args", "my make_command_from_method_name foo args"
haveing listed these options, "::xotcl::mycmd" looks reasonale to me, since it constructs a tcl command and avoids the "[self]" in a similar way as "::xotcl::my".
More ideas, suggestions, comments? best regards -gustaf neumann
haveing listed these options, "::xotcl::mycmd" looks reasonale to me, since it constructs a tcl command and avoids the "[self]" in a similar way as "::xotcl::my".
I agree with this. "myvar" and "mymethod" are at the same level as "my", which has the advantage that there is a clear semantical distinction from "my". E.g. an easy explanation in a tutorial would be:
"my foo args" calls a method on the current object, "mycmd foo args" constructs the same command as a list but does not execute it.
This is more difficult to explain for the methodname variant, since it is clear that "my cmd foo args" actually _does_ execute a method.
The argument that "myvar/mycmd" can only be used for the current object, also holds for "my". In that case you have to use the non-shorthand notation.
Concerning the choice between myproc/mymethod/mycmd/mycode/... that I'll leave up to Gustaf ;-)
Koen
xotcl-bounces@alice.wu-wien.ac.at wrote on 03/20/2006 07:21:27 AM:
Kristoffer Lawson schrieb:
I'm also wondering what the name should be, to make it really clear. Is [my var] clear enough? or should it be [my normalisedVar]?
"my var" is not a good option, "my varname" would be better,
furthermore, "my method" is already defined, getting a good name with method seems messy. how about:
There's some semantic relationship between the two accessors, so it would be nice to have some overlap in their names. How about "my varname" and "my methodname"?
Scott
On 20 Mar 2006, at 18:41, Scott Gargash wrote:
xotcl-bounces@alice.wu-wien.ac.at wrote on 03/20/2006 07:21:27 AM:
Kristoffer Lawson schrieb:
I'm also wondering what the name should be, to make it really
clear.
Is [my var] clear enough? or should it be [my normalisedVar]?
"my var" is not a good option, "my varname" would be better,
furthermore, "my method" is already defined, getting a good name
with
method seems messy. how about:
There's some semantic relationship between the two accessors, so it would be nice to have some overlap in their names. How about "my varname" and "my methodname"?
How about, to make it totally obvious, "my varNamespace" and "my methodNamespace"? Readability and clarity is generally more important in programming than cutting a few keystrokes off and at least that would be easy for anyone reading the code to decipher.
xotcl-bounces@alice.wu-wien.ac.at wrote on 03/20/2006 02:26:26 PM:
On 20 Mar 2006, at 18:41, Scott Gargash wrote:
xotcl-bounces@alice.wu-wien.ac.at wrote on 03/20/2006 07:21:27 AM:
There's some semantic relationship between the two accessors, so it would be nice to have some overlap in their names. How about "my varname" and "my methodname"?
How about, to make it totally obvious, "my varNamespace" and "my methodNamespace"? Readability and clarity is generally more important in programming than cutting a few keystrokes off and at least that would be easy for anyone reading the code to decipher.
I agree with you about clarity vs. typing, but I'm still reluctant to entrench namespace. The fact that it's in a namespace is implementation, and part of the utility of this is to encapsulate that implementation. What's really happening is you're getting a valid external reference to a variable or method.
Hmm... "my &var" and "my &method"? Or is it too C++? "my varref" and "my methodref"?
Scott
One general observation about our discussion: it is often not clear, what "namespace" refers to, a "tcl namespace" or some kind of an abstract namespace. tcl-namespaces are different to what people understand e.g. in C++ under namespaces. a tcl-namespace consists essentially of a name (fully qualified and simple), three hash-tables, one for vars, one for child-tcl-namespaces, one for commands and some info for managing these (e.g. epoch-handling, namespace resolvers, state-handling during deletion...). see in tclInt.h for more details.
in many respects, tcl-namespaces contain much functionality useful for xotcl objects as well. Allthough tcl-namespaces are no perfect fit in many respects for xocl, it is certainly not useful to duplicate its functionality in xotcl without some very good reasons. i for my part would be happy to have a lower level interface to these functionalities, having e.g. the management for cmds different from the management of the vars, but this would be a deeper change in the tcl-internals, requireing many interface changes.
Kristoffer Lawson schrieb:
On 19 Mar 2006, at 14:09, Scott Gargash wrote:
xotcl-bounces@alice.wu-wien.ac.at wrote on 03/19/2006 04:08:40 AM:
On 19 Mar 2006, at 00:12, Scott Gargash wrote:
When would you need the namespace of the object?
I have only ever needed the namespace of an object
you mean, you needed to use the explicit "requireNamespace", since namespaces are used all over in tcl as discussed in depth. as soon you define e.g. a child object or a proc for an object, a tcl-namespace is automatically added.
which attaching
traces to variables (f.ex. with Tk), but for that it is, unfortunately quite necessary.
I haven't used it yet, but doesn't the "trace" method handle this?
actually, the xotcl trace method does not require an object-specific namespace for variable traces. one can add a trace to an xotcl instvar, alhough this is not in a tcl-namespace.
Where do you see this happening? Do you mean losing the original representation via shimmering, or something else?
I've seen it happen with scripts given to [after]. I was actually very surprised by this, but at some point I was witnessing those scripts becoming strings and thus losing the original Tcl_Objs inside them (the scripts were built as lists).
There are unfortunately many cases, where this happens, even for careful programmers, avoiding obvous cases of shimmering. Unfortunately this tend to happen often in complex situations: i was recently caught be such a behavior in connection with ttrace (demand loading for naviserver/aolserver based on tcl's unknown mechanism), which is by itself quite complex, and it happend only in recursive cases (while resolving one unknown command, another unknown was triggered). I have seen it happen as well with after or other callbacks.
-gustaf neumann
/ http://www.fishpool.com/~setok/
Xotcl mailing list Xotcl@alice.wu-wien.ac.at http://alice.wu-wien.ac.at/mailman/listinfo/xotcl
On 19 Mar 2006, at 15:53, Gustaf Neumann wrote:
One general observation about our discussion: it is often not clear, what "namespace" refers to, a "tcl namespace" or some kind of an abstract namespace. tcl-namespaces
OK, for the records when I've talked of namespaces I have meant Tcl namespaces :-)
Kristoffer Lawson schrieb:
On 19 Mar 2006, at 14:09, Scott Gargash wrote:
xotcl-bounces@alice.wu-wien.ac.at wrote on 03/19/2006 04:08:40 AM:
On 19 Mar 2006, at 00:12, Scott Gargash wrote:
When would you need the namespace of the object?
I have only ever needed the namespace of an object
you mean, you needed to use the explicit "requireNamespace", since namespaces are used all over in tcl as discussed in depth. as soon you define e.g. a child object or a proc for an object, a tcl-namespace is automatically added.
Yes, exactly. But also, from my point of view the implementation could have been anything, tcl namespace or not, except for that particular case which sometimes comes up.
xotcl-bounces@alice.wu-wien.ac.at wrote on 03/19/2006 06:53:50 AM:
One general observation about our discussion: it is often not clear, what "namespace" refers to, a "tcl namespace" or some kind of an abstract namespace.
I've been guilty of this. I wondered what would happen if XOTcl's objects used their own concept/implementation of an abstract namespace (or scope) instead of using Tcl namespaces.
(The answer seems to be that it would be a lot of work and it would break XOTcl...)
That said, I think it would be good if, in general, non-XOTcl accesses to an XOTcl object's attributes didn't assume the way Tcl's namespaces are used, but instead there were object methods that would construct appropriately qualified names for an instance's attributes.
i for my part would be happy to have a lower level interface to these functionalities, having e.g. the management for cmds different from the management of the vars, but this would be a deeper change in the tcl-internals, requireing many interface changes.
Does Tip #257 provide a opening for having that discussion with the Tcl Core Team? If there's willingness to add OO support to Tcl, does that also imply a willingness to at least consider extending the C API to better support it as well?
Scott