On 5 Aug 2010, at 20:59, Gustaf Neumann wrote:
you have lost all means to pass a value for "animal", except when you pass it to init (i know "new-with" is different). One can can certainly say, the first argument passed to init is the "animal", then default handling is ugly (in the general case) and you have to deal with ugly positional arguments. This technique does not scale: What, if one inherits additional parameters from a superclass (of Foo), or when the superclass is extended? If every argument to init corresponds to a parameter, one has to extend the signature of the involved init methods. Adding arguments is not really an option when the parameters are provided via mixins, or when the object-class and class-class relationships can changed dynamically. Another issue is passing arguments of init to superclasses via next. If the inits of the superclasses have different signatures, the code becomes error prone.
Gustaf, I'm not sure what you're getting at as that is exactly what [new-with] is for. With that I can do parameterisation outside of [init]. The idea is that then it is completely explicit that that is what I wish to do, and it has a fixed argument within which that takes place. So I use [new] when I do not need parameterisation (so I don't have to give an empty argument for [new-with]), and then [new-with] when I want parameterisation. Thus both cases are safe and explicit.
To reiterate: [new-with] is a script executed within the Object's environment (with [eval]) before [init] is called. Its job is to configure the object. It thus does mostly the same job as the normal parameterisation, but with a different approach.
The only reason for [new-with] is that I could not come up with another way to make absolutely explicit what the intention of an argument is, without bad data causing issues. That is why I was rambling with the list of suggestions, with different solutions. Each option could be made to work, so just a matter of taste.
I ended up with [new] and [new-with] for my own code for now, but offered the other options in my mind for discussion.
My hypothesis is, that arguments for init are the poor men's approach for object parameterization, if one has nothing better.
Indeed, which is why I did not want to take them away. Perhaps this experiment of mine won't work well in practise. In particular, passing values from variables into the [new-with] script might end up being a nuisance. But for now it gave me peace of mind.
Arguments to contructors come more often into discussion when porting c++ style programs to xotcl, rather than from intrinsics needs when coding in xotcl.
You may be right and that I should be using parameterisation more. Of course even then you do need to be careful what you pass.
*Class create* Stack {
*:method init* {} { *set* :things "" }
*:method* push {thing} { *set* :things [*linsert* ${:things} 0 $thing] *return* $thing }
*:method* pop {} { *set* top [*lindex* ${:things} 0] *set* :things [*lrange* ${:things} 1 end] *return* $top } }
Hm, am I right in assuming the *s are just something funny when you copy-pasted from your editor, or is the plan actually to have it look like that? I can feel a few eyebrows being raised if so! :-)