|
View:
New views
20 Messages
—
Rating Filter:
Alert me
|
| < Prev | 1 - 2 | Next > |
|
|
Real (trivial) mixinsJust thought I'd put this out there, topic came up in #io today about
real mixins (not utilizing differential inheritance), so I set out to write them and realized that, it's extremely trivial. 5 lines of well structured code, or one line of still readable code. I'll put it in the former just because. :) It's presented below: Object asMixin := method( self slotNames foreach(name, call sender setSlot(name, self getSlot(name)) ) ) Enjoy. Regards, Jeremy Tregunna jeremy.tregunna@... |
|
|
Re: Real (trivial) mixinsI suppose a use case would be apropos. It'll be very bad, but design isn't what this is about. Consider the utility object "Math" containing an "add" method which, ironically enough, adds two numbers together. Math := Object clone do( add := method(n, m, n + m) ) Consider another object Foo, which mixes in this object: Foo := Object clone do( Math asMixin ) Now, we can run: Foo add(2, 3) // yields 5 Then, if we replace Math's add method, with this: Math add := method(n, m, n * m) And run Foo add(2, 3) again, we'll notice it still returns 5, while Math add(2, 3) returns 6 (since it's now doing multiplication instead of addition). On 15-Apr-09, at 12:40 PM, Jeremy Tregunna wrote: > Just thought I'd put this out there, topic came up in #io today about > real mixins (not utilizing differential inheritance), so I set out to > write them and realized that, it's extremely trivial. 5 lines of well > structured code, or one line of still readable code. I'll put it in > the former just because. :) It's presented below: > > Object asMixin := method( > self slotNames foreach(name, > call sender setSlot(name, self getSlot(name)) > ) > ) > > Enjoy. > > Regards, > > Jeremy Tregunna > jeremy.tregunna@... > > > > > > ------------------------------------ > > Yahoo! Groups Links > > > Regards, Jeremy Tregunna jeremy.tregunna@... |
|
|
Re: Real (trivial) mixinsOn Wed, 2009-15-04 at 12:43 -0400, Jeremy Tregunna wrote:
> And run Foo add(2, 3) again, we'll notice it still returns 5, while > Math add(2, 3) returns 6 (since it's now doing multiplication instead > of addition). Hmm.. can you explain a bit more -- *why* you would want to do this. It's useful to know that this is how Io behaves but it's not obvious to me why it's useful. There must be some "real world" example. Also, could you easily change the mixin design so that the change to Math would automatically propagate to Foo? I think it would be easy but I have not yet managed to collect enough tuits to start learning Io. tq -- --gh |
|
|
Re: Real (trivial) mixinsOn Wed, Apr 15, 2009 at 9:55 AM, Guy Hulbert <gwhulbert@...> wrote:
> Hmm.. can you explain a bit more -- *why* you would want to do this. Isolation. Use this method when/if you anticipate your parent(s) might change in the future, but you want to preserve their current behavior as a snapshot now. > It's useful to know that this is how Io behaves but it's not obvious to > me why it's useful. There must be some "real world" example. I would suggest studying CLU or Sather and how they use mixins for program composition. That will explain things far more effectively than executive and potentially contrived examples here. > Also, could you easily change the mixin design so that the change to > Math would automatically propagate to Foo? Simply clone Math, but do not invoke asMixin. -- Samuel A. Falvo II |
|
|
Re: Real (trivial) mixinsOn 15-Apr-09, at 1:04 PM, Samuel A. Falvo II wrote: > On Wed, Apr 15, 2009 at 9:55 AM, Guy Hulbert <gwhulbert@...> wrote: >> Also, could you easily change the mixin design so that the change to >> Math would automatically propagate to Foo? > > Simply clone Math, but do not invoke asMixin. An example: Foo := Object clone do(prependProto(Math); ...) Foo add(2, 3) == 5 // before replacing Math add Foo add(2, 3) == 6 // after replacing Math add with the multiplication example earlier Regards, Jeremy Tregunna jeremy.tregunna@... |
|
|
Re: Real (trivial) mixinsLe Wed, 15 Apr 2009 10:04:38 -0700,
"Samuel A. Falvo II" <sam.falvo@...> s'exprima ainsi: > > Hmm.. can you explain a bit more -- *why* you would want to do this. > > Isolation. Use this method when/if you anticipate your parent(s) > might change in the future, but you want to preserve their current > behavior as a snapshot now. I would rather ask the opposite question: in which (real world and/or theoretical) case can one expect the parent methods to change *and* wish this change to propagate to clones? Denis ------ la vita e estrany |
|
|
Re: Real (trivial) mixinsOn 15-Apr-09, at 1:29 PM, spir wrote: > Le Wed, 15 Apr 2009 10:04:38 -0700, > "Samuel A. Falvo II" <sam.falvo@...> s'exprima ainsi: > >>> Hmm.. can you explain a bit more -- *why* you would want to do this. >> >> Isolation. Use this method when/if you anticipate your parent(s) >> might change in the future, but you want to preserve their current >> behavior as a snapshot now. > > I would rather ask the opposite question: in which (real world and/ > or theoretical) case can one expect the parent methods to change > *and* wish this change to propagate to clones? Consider you're modeling a new drug, and some element changes in it. Would you not want that change to reflect against all instances thereof in your model? Regards, Jeremy Tregunna jeremy.tregunna@... |
|
|
Re: Real (trivial) mixinsOn Wed, Apr 15, 2009 at 10:29 AM, spir <denis.spir@...> wrote:
> I would rather ask the opposite question: in which (real world and/or theoretical) case can one expect the parent methods to change *and* wish this change to propagate to clones? I'm not sure why you're asking me this. This line of questioning is ultimately meaningless in a fully dynamic, prototypical model as Io, precisely because you ultimately have no control over whether or not it happens. It would make more sense in a language with statically delineated interfaces that, once the compilation unit is done with, remains static throughout the rest of the runtime. Consider if you're writing an application in Io, and you find two libraries (one written by me, one by Jeremy), which individually you find very useful in your work. You obviously have no express intent on tweaking Math. But suppose both my library and Jeremy's tweaks Math in some individually useful, but mutually exclusive, way as a private means of implementation. Presumably, YOUR code depends on Math's default behavior; you're unaware that either of our libraries tweaks Math without looking at the source code. What do you do? What do we do? Obviously, the best solution is for both of us to clone Math, convert them to a mixin, then tweak as appropriate. That way, our individual changes remain private to our respective libraries, without altering the public environment your code depends on. You might say, "But wait! You can just rely on Io's differential inheritance to isolate your changes!" Correct -- but it does NOT isolate YOUR changes from our expectations of Math. If you alter Math directly, then our libraries' understanding of Math's interface might change in an incompatible way. Again, this is a horribly contrived example, and is certainly not idiomatic. This is why I asked for those interested to investigate how CLU and/or Sather utilized mixins because their literature is more mature on the subject. -- Samuel A. Falvo II |
|
|
Re: Real (trivial) mixinsOn Wed, 2009-15-04 at 10:04 -0700, Samuel A. Falvo II wrote:
> > Also, could you easily change the mixin design so that the change to > > Math would automatically propagate to Foo? > > Simply clone Math, but do not invoke asMixin. Ah. Easy. Thanks (to everyone else as well). -- --gh |
|
|
Re: Real (trivial) mixinsI think you're getting caught up in this detail of Io's behaviour.
Mixins are very useful for collecting a set of behaviour in one package *that can be attached to types at will*. A favourite use of mine is to quickly turn things into -like types (e.g. list-like or dictionary-like types); in, say, Java you're stuck with rewriting all the functionality yourself (even if you state that your type "implements" a particular interface), while in python I can write a mixin that provides sorting if you'll just define get(index) and set(index) methods. For a real world example: I just wrote a couple python mixins that provide "name" and "description" functionality for classes in the textadventure I'm writing. Respectively they pull out the class's name and replace the underscores with spaces and titlecase the names, and pull a default item description from the docstring but allow you to override it (okay so maybe this last use is a bit contrived but I didn't want to tie myself to docstrings unneccessarily). The typical single-inheritence solution would be to make everything with descriptions and names inherheit from one superclass, which usually works for a while but webs you in more and more as the program gets built. If I changed the mixin I definitely would want everything that pulled from it to get the change since the mixin behaviour belongs to the mixin, it's just letting other things borrow. I must confess I've never actually thought of trying to do this, though. What a curious idea! -Nick On 15/04/2009, spir <denis.spir@...> wrote: > Le Wed, 15 Apr 2009 10:04:38 -0700, > "Samuel A. Falvo II" <sam.falvo@...> s'exprima ainsi: > >> > Hmm.. can you explain a bit more -- *why* you would want to do this. >> >> Isolation. Use this method when/if you anticipate your parent(s) >> might change in the future, but you want to preserve their current >> behavior as a snapshot now. > > I would rather ask the opposite question: in which (real world and/or > theoretical) case can one expect the parent methods to change *and* wish > this change to propagate to clones? > > Denis > ------ > la vita e estrany > |
|
|
Re: Real (trivial) mixinsWhat you're describing is an aspect. Note I didn't provide an
asAspect, because that would make absolutely no sense in the context of the one liner i posted initially. Aspects definitely need to be updated if something changes, mixins do not usually. In the case where they may need to be, just continue as normal, no need to use the asMixin method I provided. To me, I look at mixins that mix in behaviour to a specific case, unlikely to have interdependencies to other mixins. If the latter is the case, then I think of them as aspects, and flip my brain to AOP style. But who knows, maybe that's just me. On 15-Apr-09, at 2:07 PM, Nick Guenther wrote: > I think you're getting caught up in this detail of Io's behaviour. > Mixins are very useful for collecting a set of behaviour in one > package *that can be attached to types at will*. A favourite use of > mine is to quickly turn things into -like types (e.g. list-like or > dictionary-like types); in, say, Java you're stuck with rewriting all > the functionality yourself (even if you state that your type > "implements" a particular interface), while in python I can write a > mixin that provides sorting if you'll just define get(index) and > set(index) methods. > > For a real world example: I just wrote a couple python mixins that > provide "name" and "description" functionality for classes in the > textadventure I'm writing. Respectively they pull out the class's name > and replace the underscores with spaces and titlecase the names, and > pull a default item description from the docstring but allow you to > override it (okay so maybe this last use is a bit contrived but I > didn't want to tie myself to docstrings unneccessarily). The typical > single-inheritence solution would be to make everything with > descriptions and names inherheit from one superclass, which usually > works for a while but webs you in more and more as the program gets > built. > > If I changed the mixin I definitely would want everything that pulled > from it to get the change since the mixin behaviour belongs to the > mixin, it's just letting other things borrow. I must confess I've > never actually thought of trying to do this, though. What a curious > idea! > > -Nick > > On 15/04/2009, spir <denis.spir@...> wrote: >> Le Wed, 15 Apr 2009 10:04:38 -0700, >> "Samuel A. Falvo II" <sam.falvo@...> s'exprima ainsi: >> >>>> Hmm.. can you explain a bit more -- *why* you would want to do >>>> this. >>> >>> Isolation. Use this method when/if you anticipate your parent(s) >>> might change in the future, but you want to preserve their current >>> behavior as a snapshot now. >> >> I would rather ask the opposite question: in which (real world and/or >> theoretical) case can one expect the parent methods to change *and* >> wish >> this change to propagate to clones? >> >> Denis >> ------ >> la vita e estrany >> Regards, Jeremy Tregunna jeremy.tregunna@... |
|
|
Re: Real (trivial) mixinsHmm perhaps I'm missing something-
Does not the standard Proto behavior already make this easy (and sensible?) Why would I not just clone "Math" to "ScottMath", then create a modified-behavior "add" slot in ScottMath, and add ScottMath to the proto chain going forward? So, all my "add" calls would hit ScottMath, and everything else that I didn't redefine would just roll up to Math? -- Scott N Solmonson 408.718.6290 On Apr 15, 2009, at 11:07 AM, Nick Guenther wrote: > I think you're getting caught up in this detail of Io's behaviour. > Mixins are very useful for collecting a set of behaviour in one > package *that can be attached to types at will*. A favourite use of > mine is to quickly turn things into -like types (e.g. list-like or > dictionary-like types); in, say, Java you're stuck with rewriting all > the functionality yourself (even if you state that your type > "implements" a particular interface), while in python I can write a > mixin that provides sorting if you'll just define get(index) and > set(index) methods. > > For a real world example: I just wrote a couple python mixins that > provide "name" and "description" functionality for classes in the > textadventure I'm writing. Respectively they pull out the class's name > and replace the underscores with spaces and titlecase the names, and > pull a default item description from the docstring but allow you to > override it (okay so maybe this last use is a bit contrived but I > didn't want to tie myself to docstrings unneccessarily). The typical > single-inheritence solution would be to make everything with > descriptions and names inherheit from one superclass, which usually > works for a while but webs you in more and more as the program gets > built. > > If I changed the mixin I definitely would want everything that pulled > from it to get the change since the mixin behaviour belongs to the > mixin, it's just letting other things borrow. I must confess I've > never actually thought of trying to do this, though. What a curious > idea! > > -Nick > > On 15/04/2009, spir <denis.spir@...> wrote: >> Le Wed, 15 Apr 2009 10:04:38 -0700, >> "Samuel A. Falvo II" <sam.falvo@...> s'exprima ainsi: >> >>>> Hmm.. can you explain a bit more -- *why* you would want to do >>>> this. >>> >>> Isolation. Use this method when/if you anticipate your parent(s) >>> might change in the future, but you want to preserve their current >>> behavior as a snapshot now. >> >> I would rather ask the opposite question: in which (real world and/or >> theoretical) case can one expect the parent methods to change *and* >> wish >> this change to propagate to clones? >> >> Denis >> ------ >> la vita e estrany >> > > > ------------------------------------ > > Yahoo! Groups Links > > > |
|
|
Re: Real (trivial) mixinsOn Wed, Apr 15, 2009 at 9:24 PM, Scott Solmonson <scosol@...> wrote:
> So, all my "add" calls would hit ScottMath, and everything else that I > didn't redefine would just roll up to Math? I already explained this in my hypothetical example. What you're describing here is great, as long as you can trust Math to never, ever be tweaked by anyone else. If I redefine Math minus to actually perform multiplication, then your clone will inherit this errant behavior as well. -- Samuel A. Falvo II |
|
|
Re: Real (trivial) mixinsLe Wed, 15 Apr 2009 22:38:23 -0700,
"Samuel A. Falvo II" <sam.falvo@...> s'exprima ainsi: > On Wed, Apr 15, 2009 at 9:24 PM, Scott Solmonson <scosol@...> wrote: > > So, all my "add" calls would hit ScottMath, and everything else that I > > didn't redefine would just roll up to Math? > > I already explained this in my hypothetical example. What you're > describing here is great, as long as you can trust Math to never, ever > be tweaked by anyone else. > > If I redefine Math minus to actually perform multiplication, then your > clone will inherit this errant behavior as well. > Just an addition to try and be clear. The point in Jeremy's asMixin is to first inherit behaviour from a proto, while beeing independant of its possible future evolution. We could call it "free inheritance", while the standard is "linked inheritance": if ever any method changes in the proto, these changes will affect the children as well. I have a question on how Jeremy's method works: Object asMixin := method( self slotNames foreach(name, call sender setSlot(name, self getSlot(name)) ) ) As I understand it, the pseudo-clone gets a copy of the pseudo-proto's slot dictionary -- which is a set of named references to actual attribute objects. Right? So that additions and deletions on the proto won't affect the child. But what about changes on an already existing method? Is it possible to change a method while keeping its object ID (so that the child dict's reference would point to the modified method object)? Or on the contrary does a change on a method necessarily yield a brand new object with a different ID? Denis ------ la vita e estrany |
|
|
Re: Real (trivial) mixinsOn 16-Apr-09, at 4:09 AM, spir wrote: > Le Wed, 15 Apr 2009 22:38:23 -0700, > "Samuel A. Falvo II" <sam.falvo@...> s'exprima ainsi: > >> On Wed, Apr 15, 2009 at 9:24 PM, Scott Solmonson >> <scosol@...> wrote: >>> So, all my "add" calls would hit ScottMath, and everything else >>> that I >>> didn't redefine would just roll up to Math? >> >> I already explained this in my hypothetical example. What you're >> describing here is great, as long as you can trust Math to never, >> ever >> be tweaked by anyone else. >> >> If I redefine Math minus to actually perform multiplication, then >> your >> clone will inherit this errant behavior as well. >> > > Just an addition to try and be clear. The point in Jeremy's asMixin > is to first inherit behaviour from a proto, while beeing independant > of its possible future evolution. We could call it "free > inheritance", while the standard is "linked inheritance": if ever > any method changes in the proto, these changes will affect the > children as well. Not exactly. You'll note in my second e-mail, that I create two objects that descend from Object. I mix in the behaviour of the first object into the second. Foo didn't inherit from Math directly, Math's state was mixed into its already existing object. > I have a question on how Jeremy's method works: > > Object asMixin := method( > self slotNames foreach(name, > call sender setSlot(name, self getSlot(name)) > ) > ) > > As I understand it, the pseudo-clone gets a copy of the pseudo- > proto's slot dictionary -- which is a set of named references to > actual attribute objects. Right? Right. > So that additions and deletions on the proto won't affect the child. > But what about changes on an already existing method? Is it possible > to change a method while keeping its object ID (so that the child > dict's reference would point to the modified method object)? Or on > the contrary does a change on a method necessarily yield a brand new > object with a different ID? Correct me if I'm wrong, but I think what you're asking is something like this: Math getSlot("add") foo := 42 // setting an attribute on the method Foo getSlot("add") foo // returns the value 42 > The reason this happens is because I'm not doing a deep copy of everything on Math into Foo, that's just very expensive and difficult to implement in Io. Instead, what I am doing, is storing a reference to the original object, so that for the common case (replacing a method with something else), you still have a reference to the original object, not the modified object that was put in its place on Math. As a result, what ends up happening is your object id's are different if you replace Math add with some other implementation, comparing it to Foo add. Foo add always points to the original. But, if you modify Math add, so for instance, adding the "foo" slot to the actual method object, then Foo will also see that change. It's a way of hiding state that you can modify, passing it to descendants of the mixin and when you update it, have it change as well. Not necessarily a good thing, but I don't see it as a bad thing either since most people don't manipulate methods in this way (in fact, I think I'm the only one I know of that does, and only very rarely). What would be more common than attaching an attribute onto a method, is to set Math add() to have a cached value. Consider it a lazy macro for the moment, upon its first execution it does some big expensive calculation, then modifies itself setting its cachedResult to the value it calculated, so subsequent calls, are made in O(1) time rather than some other time complexity, saving you cycles, since all it does is a fetch into memory, checks an offset in a structure, and if it's not the nil sentinel, return it and abort execution. So in the case where you do something like this: Math add := method(n, m, r := n + m; self getSlot(call message name) setCachedResult(r); r) Foo := Object clone do(Math asMixin); Foo add(2, 3) // 6, actually went through the paces to get that value Foo add(5, 10) // 6 still, because 6 was cached on the add object. Even though you're not doing this on Math, Math's implementation of add is doing it, which you're mixing it in. Even if you were able to get the name of the receiver of a message, let's say you were for the moment, and you added that bit of logic to Math add() to check "If it's Math or a descendant of Math calling me, then set the cached result, otherwise, don't" then what happens in the above, is those two calls to add() on Foo, will yield 6 and 50 respectively. However, if in the middle you add a: Math add(2, 3) it'll return 6, set the cachedResult on the method object, then the second call to add() on Foo will yield 6, instead of 50. I hope this makes sense, as contrived as it is. > Denis Regards, Jeremy Tregunna jeremy.tregunna@... |
|
|
Re: Real (trivial) mixinsOn Thu, 2009-16-04 at 08:09 -0400, Jeremy Tregunna wrote:
> The reason this happens is because I'm not doing a deep copy of > everything on Math into Foo, that's just very expensive and difficult > to implement in Io. I think this answers the question I was originally trying to ask. [snip] > I hope this makes sense, as contrived as it is. It makes sense to me. It would be useful if it made it into the Io documentation somewhere ... I've saved a copy in case I get enough tuits to do something about it. -- --gh |
|
|
Re: Real (trivial) mixinsLe Thu, 16 Apr 2009 08:09:20 -0400,
Jeremy Tregunna <jeremy.tregunna@...> s'exprima ainsi: > > Just an addition to try and be clear. The point in Jeremy's asMixin > > is to first inherit behaviour from a proto, while beeing independant > > of its possible future evolution. We could call it "free > > inheritance", while the standard is "linked inheritance": if ever > > any method changes in the proto, these changes will affect the > > children as well. > > Not exactly. You'll note in my second e-mail, that I create two > objects that descend from Object. I mix in the behaviour of the first > object into the second. Foo didn't inherit from Math directly, Math's > state was mixed into its already existing object. Yes. Thank you for the precision. > > I have a question on how Jeremy's method works: > > > > Object asMixin := method( > > self slotNames foreach(name, > > call sender setSlot(name, self getSlot(name)) > > ) > > ) > > > > As I understand it, the pseudo-clone gets a copy of the pseudo- > > proto's slot dictionary -- which is a set of named references to > > actual attribute objects. Right? > > Right. > > > So that additions and deletions on the proto won't affect the child. > > But what about changes on an already existing method? Is it possible > > to change a method while keeping its object ID (so that the child > > dict's reference would point to the modified method object)? Or on > > the contrary does a change on a method necessarily yield a brand new > > object with a different ID? > > Correct me if I'm wrong, but I think what you're asking is something > like this: > > Math getSlot("add") foo := 42 // setting an attribute on the method > Foo getSlot("add") foo // returns the value 42 Exactly. That's it: I had no example in mind, but actually adding an attribute on a method is a kind of change that does not affect the method-object's ID (not sure of the correct terminology used in Io's community, but I guess 'ID' is clearly understood). So that the child, even if not cloned but "mixin-ed" instead, will see such changes. > The reason this happens is because I'm not doing a deep copy of > everything on Math into Foo, that's just very expensive and difficult > to implement in Io. Instead, what I am doing, is storing a reference > to the original object, so that for the common case (replacing a > method with something else), you still have a reference to the > original object, not the modified object that was put in its place on > Math. OK. So as a summary we have 4 types of method changes, not 3: * deletion * addition (new name) * replacement (same name) * "superficial" change (both name & ID unchanged) The latter case only will propagate to mixin descendants. Correct? > As a result, what ends up happening is your object id's are different > if you replace Math add with some other implementation, comparing it > to Foo add. Foo add always points to the original. But, if you modify > Math add, so for instance, adding the "foo" slot to the actual method > object, then Foo will also see that change. It's a way of hiding state > that you can modify, passing it to descendants of the mixin and when > you update it, have it change as well. Not necessarily a good thing, > but I don't see it as a bad thing either since most people don't > manipulate methods in this way (in fact, I think I'm the only one I > know of that does, and only very rarely). > What would be more common than attaching an attribute onto a method, > is to set Math add() to have a cached value. Consider it a lazy macro > for the moment, upon its first execution it does some big expensive > calculation, then modifies itself setting its cachedResult to the > value it calculated, so subsequent calls, are made in O(1) time rather > than some other time complexity, saving you cycles, since all it does > is a fetch into memory, checks an offset in a structure, and if it's > not the nil sentinel, return it and abort execution. So in the case > where you do something like this: > > Math add := method(n, m, r := n + m; self getSlot(call message name) > setCachedResult(r); r) > Foo := Object clone do(Math asMixin); > Foo add(2, 3) // 6, actually went through the paces to get that value > Foo add(5, 10) // 6 still, because 6 was cached on the add object. > Even though you're not doing this on Math, Math's implementation of > add is doing it, which you're mixing it in. Another use case: PEG parsing using packrat memoization (see wikipedia for info on these topics). The packrat trick is, once a pattern has matched a source string at a specific position, the result for this (pattern + pos) pair is cached so that it needs not beeing checked again. While not wonderfully accelerating (as such cases can only happen for choices, the gain depends on the choice complexity of the grammar); this ensures a linear parse time (function of source length). On a simple PEG parser, each 'pattern' can be represented by a func in code -- on which results could be cached in a dict of (pos:result) pairs. [...] > I hope this makes sense, as contrived as it is. Sure. > Jeremy Tregunna > jeremy.tregunna@... Denis ------ la vita e estrany |
|
|
Re: Real (trivial) mixinsLe Wed, 15 Apr 2009 12:40:07 -0400,
Jeremy Tregunna <jeremy.tregunna@...> s'exprima ainsi: > Just thought I'd put this out there, topic came up in #io today about > real mixins (not utilizing differential inheritance), so I set out to > write them and realized that, it's extremely trivial. 5 lines of well > structured code, or one line of still readable code. I'll put it in > the former just because. :) It's presented below: > > Object asMixin := method( > self slotNames foreach(name, > call sender setSlot(name, self getSlot(name)) > ) > ) > > Enjoy. One more general question. Some time ago I evoked the possibility of copying a proto's dict to its clones, instead of having a method lookup chain (don't remember how I did it, but probably similar to the above). An obvious advantage is the absence of method lookup along a sequence of protos, and its possible complicated issues (MRO): each object carries its own whole method dictionary. In fact, I had this solution in mind while trying to write a prototype simulation in python; couldn't find another (simple) way to implement "method sharing" at the object-level (instead of class). Now, I wonder whether this could not be the standard way of sharing behaviour between clones of the same proto, in another hypothetical prototype-based language (instead the current way used in Io). In the case discussed here, changes on the proto like deletion, addition or complete replacement of a method will not affect the clones. This is true between clones as well: they can evolve independently. Only superficial changes (that don't affect the method-object's ID), like changing an attribute on it, will be shared. The basic language design should be different: in Io, 'Object' tends to hold all what its clones may ever need. On the contrary, a language in which objects have their own complete dict should make Object as light as possible and implement additional features on specialized "interface-carriers" intended to be mixed-in. What do you think? > Regards, > > Jeremy Tregunna > jeremy.tregunna@... Denis ------ la vita e estrany |
|
|
Re: Real (trivial) mixinsOn 2009-04-16, at 7:33 AM, spir wrote: > The basic language design should be different: in Io, 'Object' tends > to hold all what its clones may ever need. On the contrary, a > language in which objects have their own complete dict should make > Object as light as possible and implement additional features on > specialized "interface-carriers" intended to be mixed-in. What do > you think? That's basically how class based languages (and some prototype based languages like Self) work. Some issues: 1. it's often useful to have inherited properties that you can change in one place instead of all instances 2. the model doesn't unify namespaces and objects |
|
|
Re: Real (trivial) mixinsLe Thu, 16 Apr 2009 15:47:46 -0700,
Steve Dekorte <steve@...> s'exprima ainsi: > > On 2009-04-16, at 7:33 AM, spir wrote: > > The basic language design should be different: in Io, 'Object' tends > > to hold all what its clones may ever need. On the contrary, a > > language in which objects have their own complete dict should make > > Object as light as possible and implement additional features on > > specialized "interface-carriers" intended to be mixed-in. What do > > you think? > > That's basically how class based languages (and some prototype based > languages like Self) work. > > Some issues: > 1. it's often useful to have inherited properties that you can change > in one place instead of all instances Yes. > 2. the model doesn't unify namespaces and objects This I don't understand. Denis ------ la vita e estrany |
| < Prev | 1 - 2 | Next > |
| Free embeddable forum powered by Nabble | Forum Help |