Re: Objects, finally (try 1)
Dan Sugalski <[EMAIL PROTECTED]> writes: > At 11:52 AM + 1/27/03, Piers Cawley wrote: >>Dan Sugalski <[EMAIL PROTECTED]> writes: >> >>> At 9:24 PM + 1/21/03, Piers Cawley wrote: Dan Sugalski <[EMAIL PROTECTED]> writes: > Hrm, interesting. Single symbol table for methods and attributes, > though that's not too surprising all things considered. That may make > interoperability interesting, but I was already expecting that to some > extent. Isn't that, essentially what Perl 6 will have too? >>> >>> Nope. Attributes and methods will be very separate. Attributes are >>> class-private, more or less, so they won't be in the symbol >>> table. >> >>How private? > > Well... not *that* private. From the bytecode level all this stuff'll > be available, though I hadn't given much thought to the introspection > end of things. > >> We are still going to be able to write some kind of >>serializing tool that won't require tons of per class overloads aren't >>we? (I'd like such a serializing tool to work at the Parrot level with >>possible callbacks into object methods). > > We probably won't need to do that, since all the knowledge necessary > to serialize should be built into individual PMC classes, but yeah, it > should be reasonably doable assuming that particular classes don't > have odd internal structures that aren't otherwise available. I'm actually quite keen on providing an C<< Object::printOn( $a_stream ) >> type method which can be overridden in weird cases (for instance in Objects that are actually Proxies for something in an external library would need to override the method). I've been working on the 'serialization' problem while writing Pixie so I'm getting some fairy definite ideas about how it should be done :) -- Piers
Re: Objects, finally (try 1)
At 11:52 AM + 1/27/03, Piers Cawley wrote: Dan Sugalski <[EMAIL PROTECTED]> writes: At 9:24 PM + 1/21/03, Piers Cawley wrote: Dan Sugalski <[EMAIL PROTECTED]> writes: > Hrm, interesting. Single symbol table for methods and attributes, though that's not too surprising all things considered. That may make interoperability interesting, but I was already expecting that to some extent. Isn't that, essentially what Perl 6 will have too? Nope. Attributes and methods will be very separate. Attributes are class-private, more or less, so they won't be in the symbol table. How private? Well... not *that* private. From the bytecode level all this stuff'll be available, though I hadn't given much thought to the introspection end of things. We are still going to be able to write some kind of serializing tool that won't require tons of per class overloads aren't we? (I'd like such a serializing tool to work at the Parrot level with possible callbacks into object methods). We probably won't need to do that, since all the knowledge necessary to serialize should be built into individual PMC classes, but yeah, it should be reasonably doable assuming that particular classes don't have odd internal structures that aren't otherwise available. -- Dan --"it's like this"--- Dan Sugalski even samurai [EMAIL PROTECTED] have teddy bears and even teddy bears get drunk
Re: Objects, finally (try 1)
Dan Sugalski <[EMAIL PROTECTED]> writes: > At 9:24 PM + 1/21/03, Piers Cawley wrote: >>Dan Sugalski <[EMAIL PROTECTED]> writes: >> > Hrm, interesting. Single symbol table for methods and attributes, >>> though that's not too surprising all things considered. That may make >>> interoperability interesting, but I was already expecting that to some >>> extent. >> >>Isn't that, essentially what Perl 6 will have too? > > Nope. Attributes and methods will be very separate. Attributes are > class-private, more or less, so they won't be in the symbol > table. How private? We are still going to be able to write some kind of serializing tool that won't require tons of per class overloads aren't we? (I'd like such a serializing tool to work at the Parrot level with possible callbacks into object methods). -- Piers
Re: Objects, finally (try 1)
At 8:16 PM +0530 1/23/03, Gopal V wrote: If memory serves me right, Erik Bågfors wrote: > Ruby needs to call the missing_method method (if I remember correctly). So if "foo" doesn't exist, it would be good to be able to override callmethods behavior and make it call missing_method. like I said , the compiler designer can put that explicitly in the generated code ... You don't actually need instructions to do that. Also the explicit generation might prove to be better to handle all the quirks future languages might encounter Or hiding it in the objects themselves, so we can make sure the expense of generality is only in place for those objects or classes that need it, rather than for everyone. My interest here is to obtain a clear and fast way to call stuff for static compiled languages. :) Fair enough, though that would argue for embedding the functionality in the objects and not the generated code, as AUTOLOAD searching should be done for a method call on a perl object regardless of whether the language making the method call supports it. If your C# code calls a method on a perl object it gets, that method resolution should be done with perl semantics, not C# semantics. -- Dan --"it's like this"--- Dan Sugalski even samurai [EMAIL PROTECTED] have teddy bears and even teddy bears get drunk
Re: Objects, finally (try 1)
At 1:46 PM -0500 1/22/03, Christopher Armstrong wrote: On Wed, Jan 15, 2003 at 01:57:28AM -0500, Dan Sugalski wrote: At 9:37 PM -0500 1/14/03, Christopher Armstrong wrote: >But who knows, maybe it could be made modular enough (i.e., more >interface-oriented?) to allow the best of both worlds -- I'm far too >novice wrt Parrot to figure out what it'd look like, unfortunately. It'll actually look like what we have now. If you can come up with something more abstract than: callmethod P1, "foo" that delegates the calling of the foo method to the method dispatch vtable entry for the object in P1, well... gimme, I want it. :) Just curious. Exactly how overridable is that `callmethod'? Completely. It ultimately delegates finding the method to the PMC via its vtable, so you can then do whatever you want. We're going to provide some convenience functions and predefined functionality so everyone doesn't have to reimplement the same stuff over and over. Delegating to the PMC also means that perl objects or ruby objects will behave the way they should regardless of what language's code is using them. I'm not really expecting too much in the way of different behaviour between the languages, but the differences that are there should be respected. -- Dan --"it's like this"--- Dan Sugalski even samurai [EMAIL PROTECTED] have teddy bears and even teddy bears get drunk
Re: Objects, finally (try 1)
At 8:42 AM +0100 1/23/03, Erik Bågfors wrote: On Wed, 2003-01-22 at 19:46, Christopher Armstrong wrote: On Wed, Jan 15, 2003 at 01:57:28AM -0500, Dan Sugalski wrote: > At 9:37 PM -0500 1/14/03, Christopher Armstrong wrote: > >But who knows, maybe it could be made modular enough (i.e., more > >interface-oriented?) to allow the best of both worlds -- I'm far too > >novice wrt Parrot to figure out what it'd look like, unfortunately. > > It'll actually look like what we have now. If you can come up with > something more abstract than: > > callmethod P1, "foo" > > that delegates the calling of the foo method to the method dispatch > vtable entry for the object in P1, well... gimme, I want it. :) Just curious. Exactly how overridable is that `callmethod'? I don't really know anything about the vtable stuff in Parrot, but is it possible to totally delegate the lookup/calling of "foo" to a function that's bound somehow to P1? Or does the "foo" entry have to exist in the vtable already? Sorry for the naive question :-) Oh, and if you just want to point me at a source file, I guess I can try reading it :-) Python basically requires that each step in the process be overridable. (1. look up attribute 2. call attribute, at least in `callmethod's case). Ruby needs to call the missing_method method (if I remember correctly). So if "foo" doesn't exist, it would be good to be able to override callmethods behavior and make it call missing_method. This'll be core functionality if languages want to use it. Perl has a similar function, AUTOLOAD, that gets called if you make a nonexistent method call. It sounds like we need generic pre and post method call handler functionality as well, which should be interesting to design. -- Dan --"it's like this"--- Dan Sugalski even samurai [EMAIL PROTECTED] have teddy bears and even teddy bears get drunk
Re: Objects, finally (try 1)
At 10:10 PM +0530 1/23/03, Gopal V wrote: If memory serves me right, Erik Bågfors wrote: But if I write a library in ruby that depends on the missing_method method it will not be usable from other languages, since those languages doesn't call missing_method if the method they try to call doesn't exist. Hmm... that's twisting language features with virtual machine instructions. Actually that's a gray area as far as I can see ... we'll have to go on with `n' number of methods for `n' languages for member resolution ... Grey? Heck, take a step back, lots of parrot is done up in neon paisley. :-P > Of course, in real life I don't think that's a problem because I haven't seen much use of missing_method. Unfortunately I use a lot of __getattr__ for my python code (especially GUI) ... Perl also makes heavy use of this in some of the more interesting modules. > Also, having a instruction would be faster which of course is more fun :) Yes... But this not only makes it ugly (as an instruction) , but slow as well ? . Like you said only a small number of people use this feature , does it make sense to slow down the rest ? . And how does hacker ZZ add a new language with a different member lookup without getting his patches inside Parrot ?.. That's why the smarts isn't in the opcode function, but rather in the vtable method lookup function. That way you only pay the cost if the feature is used. This can also work to the advantage of languages that need this feature, as it means that classes that don't have to have a fallback method lookup can use a faster lookup function that doesn't need to do a second trace to look for missing functions. Anyway I'm not *against* implementing this , I'm just questioning the *need* to implement this ... Just a question for the philosophers ... The philosophers, alas, got drunk and started fighting over the one fork at the table. Very messy. -- Dan --"it's like this"--- Dan Sugalski even samurai [EMAIL PROTECTED] have teddy bears and even teddy bears get drunk
Re: Objects, finally (try 1)
If memory serves me right, Erik Bågfors wrote: > But if I write a library in ruby that depends on the missing_method > method it will not be usable from other languages, since those languages > doesn't call missing_method if the method they try to call doesn't > exist. Hmm... that's twisting language features with virtual machine instructions. Actually that's a gray area as far as I can see ... we'll have to go on with `n' number of methods for `n' languages for member resolution ... > Of course, in real life I don't think that's a problem because I haven't > seen much use of missing_method. Unfortunately I use a lot of __getattr__ for my python code (especially GUI) ... > Also, having a instruction would be faster which of course is more fun > :) Yes... But this not only makes it ugly (as an instruction) , but slow as well ? . Like you said only a small number of people use this feature , does it make sense to slow down the rest ? . And how does hacker ZZ add a new language with a different member lookup without getting his patches inside Parrot ?.. Anyway I'm not *against* implementing this , I'm just questioning the *need* to implement this ... Just a question for the philosophers ... Gopal -- The difference between insanity and genius is measured by success
Re: Objects, finally (try 1)
On Thu, 2003-01-23 at 15:46, Gopal V wrote: > > Ruby needs to call the missing_method method (if I remember correctly). > > So if "foo" doesn't exist, it would be good to be able to override > > callmethods behavior and make it call missing_method. > > like I said , the compiler designer can put that explicitly in the > generated code ... You don't actually need instructions to do that. > Also the explicit generation might prove to be better to handle all > the quirks future languages might encounter Sure, there is only one problem with that. I don't know if it's a real problem or not. But if I write a library in ruby that depends on the missing_method method it will not be usable from other languages, since those languages doesn't call missing_method if the method they try to call doesn't exist. Of course, in real life I don't think that's a problem because I haven't seen much use of missing_method. Also, having a instruction would be faster which of course is more fun :) > My interest here is to obtain a clear and fast way to call stuff for > static compiled languages. :) But the really interesting thing about parrot is that it is primarily made for very dynamic languages. Personally I think it's quite ok if C# is a little bit slower under parrot than under mono/dotgnu/MS.NET, as long as the dynamic languages are as fast or faster than they are now. /Erik -- Erik Bågfors | [EMAIL PROTECTED] Supporter of free software | GSM +46 733 279 273 fingerprint: A85B 95D3 D26B 296B 6C60 4F32 2C0B 693D 6E32
Re: Objects, finally (try 1)
If memory serves me right, Erik Bågfors wrote: > > :-) Python basically requires that each step in the process be > > overridable. (1. look up attribute 2. call attribute, at least in > > `callmethod's case). would this be more of what you need ? obj.__dict__["foo"].__call__(); /me again shows up and says that the compiler designer can do this with ease ... Or in this case the interpreter designer can implement an ``InvocationExpression'' in anyway they want ... I think Jython would be a fine example of how this could be done (though speed suffers on a hash lookup without engine support ?). > Ruby needs to call the missing_method method (if I remember correctly). > So if "foo" doesn't exist, it would be good to be able to override > callmethods behavior and make it call missing_method. like I said , the compiler designer can put that explicitly in the generated code ... You don't actually need instructions to do that. Also the explicit generation might prove to be better to handle all the quirks future languages might encounter My interest here is to obtain a clear and fast way to call stuff for static compiled languages. :) Gopal -- The difference between insanity and genius is measured by success
RE: Objects, finally (try 1)
Christopher Armstrong: # On Wed, Jan 15, 2003 at 01:57:28AM -0500, Dan Sugalski wrote: # > At 9:37 PM -0500 1/14/03, Christopher Armstrong wrote: # > >But who knows, maybe it could be made modular enough (i.e., more # > >interface-oriented?) to allow the best of both worlds -- # I'm far too # > >novice wrt Parrot to figure out what it'd look like, unfortunately. # > # > It'll actually look like what we have now. If you can come up with # > something more abstract than: # > # > callmethod P1, "foo" # > # > that delegates the calling of the foo method to the method dispatch # > vtable entry for the object in P1, well... gimme, I want it. :) # # Just curious. Exactly how overridable is that `callmethod'? Extremely. callmethod maps to a function with a signature something like opcode_t * MyPMCClass_callmethod(Parrot_Interp interpreter, PMC* self, char* name) Which returns a pointer to the method's entry point, so that we don't have C-level recursion for every method call. (It's also allowed to just perform the call itself and return NULL, so you can call into C efficiently.) The trick is to override MyPMCClass's callmethod to provide whatever semantics you want to have. We're currently bickering over whether you can cache pmc->vtable->callmethod's return value or not, but it looks like either way it should be easily updatable. # Python basically requires that each step in the process be # overridable. (1. look up attribute 2. call attribute, at least in # `callmethod's case). I'm not sure exactly how this would be implemented but...um...I'm sure you *could* do it. ;^) Dan: with the various AUTOLOAD-esque features, can we reasonably expect to be able to have One True Object PMC? --Brent Dax <[EMAIL PROTECTED]> @roles=map {"Parrot $_"} qw(embedding regexen Configure) >How do you "test" this 'God' to "prove" it is who it says it is? "If you're God, you know exactly what it would take to convince me. Do that." --Marc Fleury on alt.atheism
Re: Objects, finally (try 1)
On Wed, 2003-01-22 at 19:46, Christopher Armstrong wrote: > On Wed, Jan 15, 2003 at 01:57:28AM -0500, Dan Sugalski wrote: > > At 9:37 PM -0500 1/14/03, Christopher Armstrong wrote: > > >But who knows, maybe it could be made modular enough (i.e., more > > >interface-oriented?) to allow the best of both worlds -- I'm far too > > >novice wrt Parrot to figure out what it'd look like, unfortunately. > > > > It'll actually look like what we have now. If you can come up with > > something more abstract than: > > > > callmethod P1, "foo" > > > > that delegates the calling of the foo method to the method dispatch > > vtable entry for the object in P1, well... gimme, I want it. :) > > Just curious. Exactly how overridable is that `callmethod'? I don't > really know anything about the vtable stuff in Parrot, but is it > possible to totally delegate the lookup/calling of "foo" to a function > that's bound somehow to P1? Or does the "foo" entry have to exist in > the vtable already? Sorry for the naive question :-) Oh, and if you > just want to point me at a source file, I guess I can try reading it > :-) Python basically requires that each step in the process be > overridable. (1. look up attribute 2. call attribute, at least in > `callmethod's case). Ruby needs to call the missing_method method (if I remember correctly). So if "foo" doesn't exist, it would be good to be able to override callmethods behavior and make it call missing_method. /Erik -- Erik Bågfors | [EMAIL PROTECTED] Supporter of free software | GSM +46 733 279 273 fingerprint: A85B 95D3 D26B 296B 6C60 4F32 2C0B 693D 6E32
Re: Objects, finally (try 1)
On Wed, Jan 15, 2003 at 01:57:28AM -0500, Dan Sugalski wrote: > At 9:37 PM -0500 1/14/03, Christopher Armstrong wrote: > >But who knows, maybe it could be made modular enough (i.e., more > >interface-oriented?) to allow the best of both worlds -- I'm far too > >novice wrt Parrot to figure out what it'd look like, unfortunately. > > It'll actually look like what we have now. If you can come up with > something more abstract than: > > callmethod P1, "foo" > > that delegates the calling of the foo method to the method dispatch > vtable entry for the object in P1, well... gimme, I want it. :) Just curious. Exactly how overridable is that `callmethod'? I don't really know anything about the vtable stuff in Parrot, but is it possible to totally delegate the lookup/calling of "foo" to a function that's bound somehow to P1? Or does the "foo" entry have to exist in the vtable already? Sorry for the naive question :-) Oh, and if you just want to point me at a source file, I guess I can try reading it :-) Python basically requires that each step in the process be overridable. (1. look up attribute 2. call attribute, at least in `callmethod's case). Thanks. -- Twisted | Christopher Armstrong: International Man of Twistery Radix | Release Manager, Twisted Project -+ http://twistedmatrix.com/users/radix.twistd/
RE: Objects, finally (try 1)
All~ Regarding MM dispatch, I implemented a version of this for a class of mine once. The version I have is in C++, and heavily uses templating to provide compile time type checks where appropriate. Despite these differences, however, I think that the system of caching methods and the system of finding the appropriate method could be easily adapted. http://www.cs.swarthmore.edu/~bulnes/PL/lab1/index.html If anyone finds that interesting or has corrections for me, please send them. Boots - "Computer Science is merely the post-Turing decline of Formal Systems Theory." -??? > -Original Message- > From: Dan Sugalski [mailto:[EMAIL PROTECTED]] > Sent: Wednesday, January 22, 2003 2:55 AM > To: Piers Cawley > Cc: Christopher Armstrong; [EMAIL PROTECTED] > Subject: Re: Objects, finally (try 1) > > > At 9:24 PM + 1/21/03, Piers Cawley wrote: > >Dan Sugalski <[EMAIL PROTECTED]> writes: > > > Hrm, interesting. Single symbol table for methods and attributes, > >> though that's not too surprising all things considered. That may make > >> interoperability interesting, but I was already expecting that to some > >> extent. > > > >Isn't that, essentially what Perl 6 will have too? > > Nope. Attributes and methods will be very separate. Attributes are > class-private, more or less, so they won't be in the symbol table. > Methods, OTOH, will be, as they aren't really private at all. > > I've been thinking about how to handle methods, as we need a > mechanism everyone can share--you need a method cache for good > performance, and the last thing I want to have to deal with is a > dozen method caches for a dozen different language implementations, > especially as everyone's guaranteed to get the first version wrong. > (Plus, of course, there's MM dispatch to deal with, which needs to be > global as well) > -- > Dan > > --"it's like this"--- > Dan Sugalski even samurai > [EMAIL PROTECTED] have teddy bears and even >teddy bears get drunk
Re: Objects, finally (try 1)
At 9:24 PM + 1/21/03, Piers Cawley wrote: Dan Sugalski <[EMAIL PROTECTED]> writes: > Hrm, interesting. Single symbol table for methods and attributes, though that's not too surprising all things considered. That may make interoperability interesting, but I was already expecting that to some extent. Isn't that, essentially what Perl 6 will have too? Nope. Attributes and methods will be very separate. Attributes are class-private, more or less, so they won't be in the symbol table. Methods, OTOH, will be, as they aren't really private at all. I've been thinking about how to handle methods, as we need a mechanism everyone can share--you need a method cache for good performance, and the last thing I want to have to deal with is a dozen method caches for a dozen different language implementations, especially as everyone's guaranteed to get the first version wrong. (Plus, of course, there's MM dispatch to deal with, which needs to be global as well) -- Dan --"it's like this"--- Dan Sugalski even samurai [EMAIL PROTECTED] have teddy bears and even teddy bears get drunk
Re: Objects, finally (try 1)
Dan Sugalski <[EMAIL PROTECTED]> writes: > At 3:06 PM -0500 1/15/03, Christopher Armstrong wrote: >>On Wed, Jan 15, 2003 at 01:57:28AM -0500, Dan Sugalski wrote: >>> At 9:37 PM -0500 1/14/03, Christopher Armstrong wrote: >>> >But who knows, maybe it could be made modular enough (i.e., more >>> >interface-oriented?) to allow the best of both worlds -- I'm far too >>> >novice wrt Parrot to figure out what it'd look like, unfortunately. >>> >>> It'll actually look like what we have now. If you can come up with >>> something more abstract than: >>> >>>callmethod P1, "foo" >>> >>> that delegates the calling of the foo method to the method dispatch >>> vtable entry for the object in P1, well... gimme, I want it. :) >> >>> I'll add "define method dispatch more" to the list o' stuff for the >>> next edit of the proposal. >> >>I'll help you along by offering this explanation of how instance >>methods work in Python. (sorry if you're already familiar with this >>stuff, but it's in my best interest to make sure you are ;-)) >> >>When you say something like `o.foo()', it translates into these steps: >> >> 1) LOAD_NAME 'o' >> 2) LOAD_ATTR 'bar' >> 3) CALL_FUNCTION >> >>#2 has extra magic. What I mean is, when you LOAD_ATTR a function from >>a *class*, you just get back a plain old `unbound method'. When you >>LOAD_ATTR from an *instance*, and (after failing to find an instance >>attribute) the attribute is found on its class, you get a `bound >>method', which basically means that Python has "curried" that method >>so the first argument is automatically passed -- that first argument >>is the instance which you LOAD_ATTRd from. This is why you see all >>those python methods with the first argument being `self', and rarely >>see code which explicitly passes that first argument. >> >>Now, like I said, this magic is done in LOAD_ATTR, not CALL_FUNCTION, >>so you can take that bound method object and do whatever you want with >>it before calling it. >> >>Here's an interesting code snippet which also demonstrates the fact >>that methods are just attributes. > > Hrm, interesting. Single symbol table for methods and attributes, > though that's not too surprising all things considered. That may make > interoperability interesting, but I was already expecting that to some > extent. Isn't that, essentially what Perl 6 will have too? It's just that the sigil will be taken to be part of the symbol. Thus a method's symbol will be &method (method?). Presumably one would first check with the object for a matching symbol and then search up the class tree until something comes up (which could then be cached back on the object, though that would require some smarts on the object's binding to the method so that Parrot could distinguish between cached methods and 'custom' methods (hopefully the binding would also contain information about where a cached method was found so that SUPER:: type dispatch could be done dynamically instead of using the current hack based on the package in which the C<< $self->SUPER::method() >> call was compiled (what me? On a hobby horse? Never!))) Hmm... was that a paragraph or an S-expression? -- Piers
RE: Objects, finally (try 1)
At 3:03 PM -0800 1/15/03, Jonathan Sillito wrote: Sounds like we want objects *and* classes to support: static_attribs - which are defined at compile time and accessed by offset probably stored in an array. dynamic_attribs - which come and go at run time and are generally accessed by name and likely stored in a hash. Yep. I've pretty much decided that classes are objects, so the one falls out of the other there. We can deal with the dynamism fairly simply, though there are issues of efficiency, as I have the feeling that supporting the dynamic case well (which is reasonably rare, relatively speaking) will make all cases, or at least all method calls, slower. I think. Need to ponder this more. -- Dan --"it's like this"--- Dan Sugalski even samurai [EMAIL PROTECTED] have teddy bears and even teddy bears get drunk
Re: Objects, finally (try 1)
At 8:54 PM + 1/15/03, Nicholas Clark wrote: On Wed, Jan 15, 2003 at 01:00:59AM -0500, Dan Sugalski wrote: At 8:53 PM -0800 1/14/03, Adriano wrote: >I think what Jonathan asked for was an operator for returning a >method (as an object) which can be invoked later with some arguments >(or even applied with a partial list of arguments for currying). >This would be a lot more useful than a yes-or-no answer about the existence >of a method. I thought about this--it's what the find_method vtable method was for in the first place. Unfortunately, as was pointed out to me, there's no good way to cache the result, since it could potentially be wrong by the time the method is actually called. We could potentially get around this if we put in place a notification framework to invalidate these method handles, but that means we have to have a fair amount of infrastructure in place to do that. (Though, honestly, I do really like the idea, as it means we can be faster by default and just pay the price when things change, but there's that pesky code that needs writing and systems that need designing to support it...) How much infrastructure do you need? I thought perl5 cached method lookup, but had a global (per interpreter) generation count, which went up by one every time you (re)defined a method. So for parrot you return a "thingy" that is initially implemented as the direct pointer, a generation count, plus enough other stuff to redo the search. If at the time of calling the generation count is the same, wehay, go for it. Otherwise redo the search there and then, and update. What I don't want is to check every time. I want method invalidation to be done only on demand, so the common case (multiple use without intervening redefinition) is as fast as possible. If we do implicit handles we'll need a good infrastructure with defined semantics to make sure those handles get either invalidated or rejigged when changes are made, plus we need them to support the cases where there is no real method and we're faking it all. I think I know what needs to be designed, and what semantics we need, and I'm pretty sure I know how to fake it until the structure's done, too, so after I dig through the rest of the aftermath here it'll be time to start writing. :) -- Dan --"it's like this"--- Dan Sugalski even samurai [EMAIL PROTECTED] have teddy bears and even teddy bears get drunk
Re: Objects, finally (try 1)
At 3:06 PM -0500 1/15/03, Christopher Armstrong wrote: On Wed, Jan 15, 2003 at 01:57:28AM -0500, Dan Sugalski wrote: At 9:37 PM -0500 1/14/03, Christopher Armstrong wrote: >But who knows, maybe it could be made modular enough (i.e., more >interface-oriented?) to allow the best of both worlds -- I'm far too >novice wrt Parrot to figure out what it'd look like, unfortunately. It'll actually look like what we have now. If you can come up with something more abstract than: callmethod P1, "foo" that delegates the calling of the foo method to the method dispatch vtable entry for the object in P1, well... gimme, I want it. :) I'll add "define method dispatch more" to the list o' stuff for the next edit of the proposal. I'll help you along by offering this explanation of how instance methods work in Python. (sorry if you're already familiar with this stuff, but it's in my best interest to make sure you are ;-)) When you say something like `o.foo()', it translates into these steps: 1) LOAD_NAME 'o' 2) LOAD_ATTR 'bar' 3) CALL_FUNCTION #2 has extra magic. What I mean is, when you LOAD_ATTR a function from a *class*, you just get back a plain old `unbound method'. When you LOAD_ATTR from an *instance*, and (after failing to find an instance attribute) the attribute is found on its class, you get a `bound method', which basically means that Python has "curried" that method so the first argument is automatically passed -- that first argument is the instance which you LOAD_ATTRd from. This is why you see all those python methods with the first argument being `self', and rarely see code which explicitly passes that first argument. Now, like I said, this magic is done in LOAD_ATTR, not CALL_FUNCTION, so you can take that bound method object and do whatever you want with it before calling it. Here's an interesting code snippet which also demonstrates the fact that methods are just attributes. Hrm, interesting. Single symbol table for methods and attributes, though that's not too surprising all things considered. That may make interoperability interesting, but I was already expecting that to some extent. The bound method call thing we can do as a curried function, so I'm not that concerned about it in general, but it does definitely imply that we need to build in currying support to the core rather than leaving it to the compilers to do, though there's no reason that the functionality can't be left to the python opcode backwards-compatibility set and more explicit logic built into the python front end, but... Hrm. I appreciate the heads up here. -- Dan --"it's like this"--- Dan Sugalski even samurai [EMAIL PROTECTED] have teddy bears and even teddy bears get drunk
RE: Objects, finally (try 1)
At 9:38 AM -0800 1/15/03, Jonathan Sillito wrote: I realize this will vary from language to language, but generally we will need a PMC that encapsulates a method (and responds to the invoke vtable method like Sub, or maybe the Sub PMC could do?). This python code is interesting: a = A() a.f()# output: A.f() x = a.f # get the method, a limited form of currying x() # output: A.f() setattr(A, "f", g) # replace A's f with g a.f()# output: g() x() # output (still): A.f() !!! Which shows that the dispatch (i.e. selecting which method to call) can happen before the invocation. Right, which argues for a method fetch. Which is cool, we need it, I'll make sure it gets in the list. I've been arguing for things that will be generally of use to the compiler and interpreter though--things that will be useful for emitted code inferred from what the user's written, hence the confusion. The interpreter itself can't do that sort of explicit caching without a lot of infrastructure to support it. Though, as I dig through the mail, I'm realizing more and more that we *must* do the explicit caching layer, and if we want to take full advantage of it we need to expose it to the compilers rather than keeping it secret, though it may be fairly inefficient to start with. Damn. -- Dan --"it's like this"--- Dan Sugalski even samurai [EMAIL PROTECTED] have teddy bears and even teddy bears get drunk
RE: Objects, finally (try 1) [x-adr][x-bayes]
At 11:44 AM -0600 1/15/03, Garrett Goebel wrote: From: attriel [mailto:[EMAIL PROTECTED]] >> > >I think what Jonathan asked for was an operator for >> > >returning a method (as an object) which can be invoked >> > >later with some arguments (or even applied with a >> > >partial list of arguments for currying). >> > > >> > >This would be a lot more useful than a yes-or-no >> > >answer about the existence of a method. > > Exactly. 'Yes' might be valid one moment, and invalid the > next. Not a very useful operation... Returning a coderef > on the other hand is useful. Er. How could "Is it possible to call this method" become invalid, but the fptr remains valid? I'm not sure that I follow that ... Perhaps I'm misunderstanding Dan's meaning when he talks of invalidating method handles. Yep. (Horse, meet stick. Stick, meet horse. Prepare to be thumped again) I'm not talking about user-level code. I had originally figured that would just walk through the symbol tables and inheritance trees and find the method there and grab it, with no vtable involvement at all--code of the form: $foo = Bar->can("baz"); doesn't really involve parrot's method code at all. (Or so I thought, though I'm coming to think differently, as even that will need to be delegated to the objects at some point) I've been concerned with cases like: foo->bar foo->bar foo->bar where the compiler would be getting foo's bar method once, sticking it into a PMC reg, and invoking it three times. Which would be very wrong, as that handle would be potentially really wrong after the first use. (Heck, finding it could potentially invalidate it, making the first use wrong) The common case for method handles, if they work, is as a shortcut/optimziation for the compiler, not for user code use, so that's what I'm most concerned with. -- Dan --"it's like this"--- Dan Sugalski even samurai [EMAIL PROTECTED] have teddy bears and even teddy bears get drunk
RE: Objects, finally (try 1)
At 11:44 AM -0500 1/15/03, attriel wrote: >> > >I think what Jonathan asked for was an operator for > >returning a method (as an object) which can be invoked > >later with some arguments (or even applied with a > >partial list of arguments for currying). > > > >This would be a lot more useful than a yes-or-no > >answer about the existence of a method. Exactly. 'Yes' might be valid one moment, and invalid the next. Not a very useful operation... Returning a coderef on the other hand is useful. Er. How could "Is it possible to call this method" become invalid, but the fptr remains valid? I'm not sure that I follow that ... I get the function pointer. Points to a method. Someone comes and redefines that method in the object's class, or deletes it outright. I still have a handle, so the code doesn't go away, but it's no longer the right code for that method name. -- Dan --"it's like this"--- Dan Sugalski even samurai [EMAIL PROTECTED] have teddy bears and even teddy bears get drunk
RE: Objects, finally (try 1)
At 10:28 AM -0600 1/15/03, Garrett Goebel wrote: Peter Haworth wrote: Dan Sugalski wrote: > Adriano wrote: > > > >I think what Jonathan asked for was an operator for > >returning a method (as an object) which can be invoked > >later with some arguments (or even applied with a > >partial list of arguments for currying). > > > >This would be a lot more useful than a yes-or-no > >answer about the existence of a method. Exactly. 'Yes' might be valid one moment, and invalid the next. Not a very useful operation... Returning a coderef on the other hand is useful. Returning a valid coderef isn't often useful, very limiting, and potentially inappropriate for our main targets. The only way they're of any general use is if they just wrap the method invocation again, in which case they're also slower than a plain method call. I have this nasty feeling I'm going to be going over this explanation several times, so I'm going to do it once here and hope for the best. We are building an OO system for dynamic languages. This means the list of methods that exist for an object may vary over time, it means the list of methods that can be satisfied for an object vary over time, and it means the two sets don't completely overlap. Plus we also have multimethods to contend with, for the unwary When you invoke a method, like: foo->bar One of several things could happen: 1) The bar method somewhere in foo's hierarchy is invoked 2) The bar method for no args is invoked in foo's hierarchy 3) AUTOLOAD, or its moral equivalent, is invoked somewhere in the hierarchy because there is no bar method, so the fallback is used 4) Like #3, only it then creates a bar method 5) We invoke the bar method, which then changes before we can invoke it again Getting a handle on the real method, then, is potentially wrong in cases 2 and 5, and not possible or really wrong in 3 and 4 (depending on how we do autoloadish things). It's only really correct for case 1. For user-level code, that's perfectly fine--if you want to write code that is potentially really wrong, there's no problem. (You won't be the first nor, alas, the last) For that reason we should provide a way to get the real handle for a particular invocation, so if you only want it for user code, that's cool, read no further. For the interpreter's purposes, though, we can't really use it. User code can incorrectly function in the face of mutating back-ends, but the interpreter must behave correctly in all cases. That's where things get more interesting for us. Yes, I fully want a caching method-invocation layer, so we can do our best to go as fast as possible in the common case. There's a lot of literature on this, and I'm well aware that we need it if we want to have any hope of blazing speed. Doing that right, though, means caching method lookups and trapping symbol table mutations, doing... interesting potential dispatch courtesy of multimethods, and generally getting funky. Static method handles, though, are just of no use for the *interpreter*. User program, sure, interpreter, no way. The languages are just too dynamic for it to be correct. For that we need dynamic handles, and those are much more work. That's one of the reasons I didn't really address method invocation with objects, as I wasn't quite ready to get into methods yet. (And I'm still not sure how to handle closed classes, or if we even should--perl/ruby/python classes aren't ever closed, though .NET/JVM classes, IIRC, are all entirely closed) -- Dan --"it's like this"--- Dan Sugalski even samurai [EMAIL PROTECTED] have teddy bears and even teddy bears get drunk
Re: Objects, finally (try 1)
If memory serves me right, Jonathan Sillito wrote: > x = a.f # get the method, a limited form of currying > # since the first arg (a==self) is stored > x() # output: A.f() > > setattr(A, "f", g) # replace A's f with g > > a.f()# output: g() > x() # output (still): A.f() !!! > > Which shows that the dispatch (i.e. selecting which method to call) can > happen before the invocation. This makes sense let me put it in this way x_mthdptr=a.__dict__["f"] a.__dict__["f"]=g_mthdptr x_mthdptr() The dispatch vs invocation looks childishly simple when written this way.. (and I hope I'm right about that ... :) Underneath the high level language most things are really simple ... The Python compiler should work around all these language quirks and generate appropriate Parrot code ... In bytecode it should look direct, simple and fast !. Gopal -- The difference between insanity and genius is measured by success
Re: Objects, finally (try 1)
> "JS" == Jonathan Sillito <[EMAIL PROTECTED]> writes: JS> Sounds like we want objects *and* classes to support: JS> static_attribs - which are defined at compile time and JS> accessed by offset probably stored in an array. JS> dynamic_attribs - which come and go at run time and are JS> generally accessed by name and likely stored in a hash. that isn't a bad idea. describe them in parrot by their lower level use (or implementation) and map them to the high level lang and its own OO/property terms. i would use shorter names like dyn_attr and stat_attr. but where they are stored is also an issue. are they instance specific or class only? there are several combinations of those features too. uri -- Uri Guttman -- [EMAIL PROTECTED] http://www.stemsystems.com - Stem and Perl Development, Systems Architecture, Design and Coding Search or Offer Perl Jobs http://jobs.perl.org Damian Conway Perl Classes - January 2003 -- http://www.stemsystems.com/class
RE: Objects, finally (try 1)
Sounds like we want objects *and* classes to support: static_attribs - which are defined at compile time and accessed by offset probably stored in an array. dynamic_attribs - which come and go at run time and are generally accessed by name and likely stored in a hash. -- Jonathan Sillito > -Original Message- > From: Nicholas Clark [mailto:[EMAIL PROTECTED]] > Sent: January 15, 2003 12:41 PM > To: Dan Sugalski > Cc: Gopal V; [EMAIL PROTECTED] > Subject: Re: Objects, finally (try 1) > > > On Wed, Jan 15, 2003 at 11:17:17AM -0500, Dan Sugalski wrote: > > In that case they'd correspond to our properties, and I can already > > feel a massive terminology disconnect looming. Maybe we should rename > > properties and attributes to frobs and thingies, just so there's no > > overlap. :( > > We could call them houses and hotels - you'd only be allowed attributes > after you had 4 properties, and if you want to mortgage, er serialise the > object you'd have to hand them all back to the bank, er GC system. > > Mmm. Maybe that's taking the analogy well beyond breaking point. > > I've had a look in a thesaurus for words similar to property and > attribute, > and I can't see much that's good. "idiosyncrasy" is a nice word, > but it's 6 > syllables, and hard to spell. "satellite" seems quite good for objects and > "stuff" that are hangers-on, as does "chattels". I quite liked the idea of > "virtue" for a quality, although I'm not sure if Larry would sanction PMCs > having vices as well :-) > > The downside of finding completely new names for these two > concepts is that > everyone would have to learn what they meant. The upside is that > there would > be no confusion with every other language's contradictory definitions. > > Nicholas Clark >
Re: Objects, finally (try 1)
On Wed, Jan 15, 2003 at 01:00:59AM -0500, Dan Sugalski wrote: > At 8:53 PM -0800 1/14/03, Adriano wrote: > >I think what Jonathan asked for was an operator for returning a > >method (as an object) which can be invoked later with some arguments > >(or even applied with a partial list of arguments for currying). > >This would be a lot more useful than a yes-or-no answer about the existence > >of a method. > > I thought about this--it's what the find_method vtable method was for > in the first place. Unfortunately, as was pointed out to me, there's > no good way to cache the result, since it could potentially be wrong > by the time the method is actually called. > > We could potentially get around this if we put in place a > notification framework to invalidate these method handles, but that > means we have to have a fair amount of infrastructure in place to do > that. (Though, honestly, I do really like the idea, as it means we > can be faster by default and just pay the price when things change, > but there's that pesky code that needs writing and systems that need > designing to support it...) How much infrastructure do you need? I thought perl5 cached method lookup, but had a global (per interpreter) generation count, which went up by one every time you (re)defined a method. So for parrot you return a "thingy" that is initially implemented as the direct pointer, a generation count, plus enough other stuff to redo the search. If at the time of calling the generation count is the same, wehay, go for it. Otherwise redo the search there and then, and update. Later on you can add in the notify system, if that's faster. (It may well be, as at that point the pointer will always be valid, even if it's now pointing to some placeholder bytecode that just throws an exception if called.) Hmm. That's a cheat idea. You could keep track of all these "thingies", and make sure the jump pointer was always valid. You just arrange that it is replaced with a pointer into a relookup routine every time something "relevant" gets redefined. (Initially a global counter, but it can get more specialised later). That trades faster call speed each time (because the pointer is now always valid, so you never need to check the generation count at each call) for more maintenance time for each method redefine. Although in turn you could then maintain you backpointers to all the "thingies" in two sets - ones that are currently pointing to the "lookup" code, and ones that point to real methods. Every time the "world" is updated with code (re)definition you convert all the real methods to point to the "lookup" code. Every time a "lookup" code routine is called it finds the real method, and moves itself back to the the real set. This would actually let you defer the method lookup - when you create one of these pointers it's actually lazy, pointing to the "lookup" code, and the lookup is really only done the first time you call it. Am I rambling too much? Nicholas Clark
Re: Objects, finally (try 1)
On Wed, Jan 15, 2003 at 11:17:17AM -0500, Dan Sugalski wrote: > In that case they'd correspond to our properties, and I can already > feel a massive terminology disconnect looming. Maybe we should rename > properties and attributes to frobs and thingies, just so there's no > overlap. :( We could call them houses and hotels - you'd only be allowed attributes after you had 4 properties, and if you want to mortgage, er serialise the object you'd have to hand them all back to the bank, er GC system. Mmm. Maybe that's taking the analogy well beyond breaking point. I've had a look in a thesaurus for words similar to property and attribute, and I can't see much that's good. "idiosyncrasy" is a nice word, but it's 6 syllables, and hard to spell. "satellite" seems quite good for objects and "stuff" that are hangers-on, as does "chattels". I quite liked the idea of "virtue" for a quality, although I'm not sure if Larry would sanction PMCs having vices as well :-) The downside of finding completely new names for these two concepts is that everyone would have to learn what they meant. The upside is that there would be no confusion with every other language's contradictory definitions. Nicholas Clark
Re: Objects, finally (try 1)
At 3:10 PM + 1/15/03, Peter Haworth wrote: On Wed, 15 Jan 2003 01:00:59 -0500, Dan Sugalski wrote: At 8:53 PM -0800 1/14/03, Adriano wrote: >I think what Jonathan asked for was an operator for returning a method >(as an object) which can be invoked later with some arguments (or even >applied with a partial list of arguments for currying). This would be a >lot more useful than a yes-or-no answer about the existence of a method. I thought about this--it's what the find_method vtable method was for in the first place. Unfortunately, as was pointed out to me, there's no good way to cache the result, since it could potentially be wrong by the time the method is actually called. Is that such a big deal? The same problem exists in perl 5 with the following code: Right, but the example is showing a programmer's error. The folks using parrot have to make their own subtle mistakes--we can't make the mistakes on their behalf. -- Dan --"it's like this"--- Dan Sugalski even samurai [EMAIL PROTECTED] have teddy bears and even teddy bears get drunk
Re: Objects, finally (try 1)
At 7:11 PM +0530 1/15/03, Gopal V wrote: If memory serves me right, Dan Sugalski wrote: rather than attributes, but I may be incorrect here. Are the current python instance attributes both: *) defined per object rather than per class *) Essentially global, that is not hidden from parent classes or anything. (Basically one big pool 'o things attached to the object) Speaking out of turn Python instance stuff is per Object ... And from the looks of it's just a dictionary lookup in the obj.__dict__ dictionary ... So the stuff looks essentially global. In that case they'd correspond to our properties, and I can already feel a massive terminology disconnect looming. Maybe we should rename properties and attributes to frobs and thingies, just so there's no overlap. :( At least getting to obj.__dict__ is simple enough, as we can map that to the property hash fetch opcode. -- Dan --"it's like this"--- Dan Sugalski even samurai [EMAIL PROTECTED] have teddy bears and even teddy bears get drunk
Re: Objects, finally (try 1)
On Wed, Jan 15, 2003 at 01:57:28AM -0500, Dan Sugalski wrote: > At 9:37 PM -0500 1/14/03, Christopher Armstrong wrote: > >But who knows, maybe it could be made modular enough (i.e., more > >interface-oriented?) to allow the best of both worlds -- I'm far too > >novice wrt Parrot to figure out what it'd look like, unfortunately. > > It'll actually look like what we have now. If you can come up with > something more abstract than: > > callmethod P1, "foo" > > that delegates the calling of the foo method to the method dispatch > vtable entry for the object in P1, well... gimme, I want it. :) > I'll add "define method dispatch more" to the list o' stuff for the > next edit of the proposal. I'll help you along by offering this explanation of how instance methods work in Python. (sorry if you're already familiar with this stuff, but it's in my best interest to make sure you are ;-)) When you say something like `o.foo()', it translates into these steps: 1) LOAD_NAME 'o' 2) LOAD_ATTR 'bar' 3) CALL_FUNCTION #2 has extra magic. What I mean is, when you LOAD_ATTR a function from a *class*, you just get back a plain old `unbound method'. When you LOAD_ATTR from an *instance*, and (after failing to find an instance attribute) the attribute is found on its class, you get a `bound method', which basically means that Python has "curried" that method so the first argument is automatically passed -- that first argument is the instance which you LOAD_ATTRd from. This is why you see all those python methods with the first argument being `self', and rarely see code which explicitly passes that first argument. Now, like I said, this magic is done in LOAD_ATTR, not CALL_FUNCTION, so you can take that bound method object and do whatever you want with it before calling it. Here's an interesting code snippet which also demonstrates the fact that methods are just attributes. >>> def toot(): print "hello" ... >>> class Foo: pass ... >>> # binding a method *to the instance* -- this prevents magic >>> o = Foo(); o.toot = toot >>> o.toot() hello >>> # binding method *to the class* -- just the same as if we defined >>> # `toot' in the class definition >>> Foo.toot = toot >>> o2 = Foo() >>> o2.toot() Traceback (most recent call last): File "", line 1, in ? TypeError: toot() takes no arguments (1 given) That traceback happened because, as I explained above, when the `toot' attribute was LOAD_ATTR'd from the instance and found on the class, it was turned into a bound method that would have the instance automatically passed to it. HTH, -- Twisted | Christopher Armstrong: International Man of Twistery Radix | Release Manager, Twisted Project -+ http://twistedmatrix.com/users/radix.twistd/
RE: Objects, finally (try 1)
> Perhaps I'm misunderstanding Dan's meaning when he talks of invalidating > method handles. In Perl5: > > package Foo; > sub bar { print "hello world\n" } > package main; > my $cref = Foo->can('bar'); > undef *Foo::bar; > Foo->$cref(); > Foo->bar(); > 1; > > would result in: > > hello world > Can't locate object method "bar" via package "Foo" (perhaps you forgot > to load " > Foo"?) at [...] line 7. > > As you can see, this is something you can do this in Perl5. And as Perl6 > is supposed to be able to run Perl5... I'd think this'd be something > parrot'd be required to support. Hrrm. I didn't know that case worked :o I guess then that we'd be returning a code-object and calling the (nifty new) compile opcode on it when we wanted to actually run it ... from what I understood of Dan's last reply, though, we're getting "yes/no" and this entire subtree got pruned :o I guess we'd be, effectively, looking at ref counters (like with memptrs and GC), so we can say "oh, we deleted that, but I have this reference, so I'll invalidate the real call, but leave it there so the ref works", effectively like hard links on unix, i guess ... Would that work as an option to resolve it? I don't know the memory or data-store values (especially not of objects that are still just words :o) but would it be possible to keep a refcount for the items, set at 1 (b/c it's defined :) and then if someone does a can() we increment it until the $val that can() went into either gets undef'd, descoped, or otherwise loses it's reference? (those two are static events, I think, and $var could just tell it's ref that it's going away, quit counting me ... ) random mumblings that I don't really understand how they'd work in parrot: If we have a FPtr PMC, and we provide it as a return to can(), after incrementing the internal refcount ... Then on an "undef *Foo::bar;" it invalidates the name in the PMC (and Foo's meth tables?) and decreases it's refcount ... Then set whatever kinds of traps (I guess they'd be compiler level) so that whenever the value of the $var that took the result of can() is changed, it decrements the refcount ... I think that's compiler level, so it just takes longer to compile, while it tosses in the extra opcodes for decrements ... and then if the refcount == 0 we just mark it for GC and forget about it entirely ... Like i said, no idea how all that ACTUALLY works out in parrot, though :o --attriel
RE: Objects, finally (try 1) [x-adr][x-bayes]
From: attriel [mailto:[EMAIL PROTECTED]] > > >> > >I think what Jonathan asked for was an operator for > >> > >returning a method (as an object) which can be invoked > >> > >later with some arguments (or even applied with a > >> > >partial list of arguments for currying). > >> > > > >> > >This would be a lot more useful than a yes-or-no > >> > >answer about the existence of a method. > > > > Exactly. 'Yes' might be valid one moment, and invalid the > > next. Not a very useful operation... Returning a coderef > > on the other hand is useful. > > Er. How could "Is it possible to call this method" become > invalid, but the fptr remains valid? I'm not sure that I > follow that ... Perhaps I'm misunderstanding Dan's meaning when he talks of invalidating method handles. In Perl5: package Foo; sub bar { print "hello world\n" } package main; my $cref = Foo->can('bar'); undef *Foo::bar; Foo->$cref(); Foo->bar(); 1; would result in: hello world Can't locate object method "bar" via package "Foo" (perhaps you forgot to load " Foo"?) at [...] line 7. As you can see, this is something you can do this in Perl5. And as Perl6 is supposed to be able to run Perl5... I'd think this'd be something parrot'd be required to support. -- Garrett Goebel IS Development Specialist ScriptPro Direct: 913.403.5261 5828 Reeds Road Main: 913.384.1008 Mission, KS 66202 Fax: 913.384.2180 www.scriptpro.com [EMAIL PROTECTED]
RE: Objects, finally (try 1)
I realize this will vary from language to language, but generally we will need a PMC that encapsulates a method (and responds to the invoke vtable method like Sub, or maybe the Sub PMC could do?). This python code is interesting: class A: def f (self): print "A.f()" def g (self): print "g()" a = A() a.f()# output: A.f() x = a.f # get the method, a limited form of currying # since the first arg (a==self) is stored x() # output: A.f() setattr(A, "f", g) # replace A's f with g a.f()# output: g() x() # output (still): A.f() !!! Which shows that the dispatch (i.e. selecting which method to call) can happen before the invocation. -- Jonathan Sillito > -Original Message- > From: Dan Sugalski [mailto:[EMAIL PROTECTED]] > > At 8:53 PM -0800 1/14/03, Adriano wrote: > >On Tue, 14 Jan 2003 17:18:22 -0500, Dan Sugalski <[EMAIL PROTECTED]> wrote: > > > >Dan: > >>You're off. It'll be something like: > >> > >>callmethod Px, "method_name" > >> > >>or > >> > >>jmpmethod Px, "method_name" > > > >Jonathan: > >>Is there going to be any way to (in PASM) find a method with > out invoking > >>it? I am not sure, but it may be useful for currying and some efficiency > >>stuff (like moving dispatch outside of a loop that repeatedly invokes a > >>method). > > > >Dan: > >>Yep. There should be a can operator, though I'm not sure how often > >>one wants to check for the existence of a method in an object > >>without calling it. But no reason not to. More for rev 2. > > > >I think what Jonathan asked for was an operator for returning a > >method (as an object) which can be invoked later with some arguments > >(or even applied with a partial list of arguments for currying). > >This would be a lot more useful than a yes-or-no answer about > the existence > >of a method. > > I thought about this--it's what the find_method vtable method was for > in the first place. Unfortunately, as was pointed out to me, there's > no good way to cache the result, since it could potentially be wrong > by the time the method is actually called. > > We could potentially get around this if we put in place a > notification framework to invalidate these method handles, but that > means we have to have a fair amount of infrastructure in place to do > that. (Though, honestly, I do really like the idea, as it means we > can be faster by default and just pay the price when things change, > but there's that pesky code that needs writing and systems that need > designing to support it...) > -- > Dan > > --"it's like this"--- > Dan Sugalski even samurai > [EMAIL PROTECTED] have teddy bears and even >teddy bears get drunk >
RE: Objects, finally (try 1)
>> > >I think what Jonathan asked for was an operator for >> > >returning a method (as an object) which can be invoked >> > >later with some arguments (or even applied with a >> > >partial list of arguments for currying). >> > > >> > >This would be a lot more useful than a yes-or-no >> > >answer about the existence of a method. > > Exactly. 'Yes' might be valid one moment, and invalid the next. Not a > very useful operation... Returning a coderef on the other hand is > useful. Er. How could "Is it possible to call this method" become invalid, but the fptr remains valid? I'm not sure that I follow that ... > I don't see it as a problem. In Perl5, you get back a coderef. And > despite whether the method is modified or removed from the class in the > meantime, that code reference is still valid. I think the issue is that Perl is interpreting things, whereas the parrot would be quoting back actual memory locations saying "ok, this is RIGHT HERE. when you want to do it, go RIGHT HERE" and then we up and moved "here" to "there" and all hell breaks loose when I try to "callmethod" on a pure number :o Although, I guess Parrot could still be doing memory management at the VM level and the PASM would still be getting lookup refs instead of actual physical pointers, at which case I'm not sure I see the problem ... I guess if "who's 'foo()' am I calling" is determined by some property of the object, then it's possible to get a fptr P to function F from object O at time T, do stuff with O (some of which might cause P' to be the proper F fptr instead of P), and then calling P is no longer "legitimate" ... But I'm not entirely convinced that's not the coder's problem, since that would, imo, be a side-effect of whatever calls were made between "can" and "call", which means either (a) they're documented properly and the coder missed that step and forgot to get a new P for F (making P <- P') or (b) it's NOT documented, at which point it's still the coder's error, just a different coder :) since the side-effect is important and (possibly) break-a-licious ... --attriel (so, at the level we're talking about right now, are we getting fptr P as a memory location that has the function and we want to jump there (or has the function ref, etc); or is P a ref that parrot will then look up in the object and dig up the right answer (but has already done some level of lookup to make this lookup easy; we've already found where it is in the object the first time; now I have to find out where that is in memory/load that into memory and call it)
RE: Objects, finally (try 1)
Peter Haworth wrote: > Dan Sugalski wrote: > > Adriano wrote: > > > > > >I think what Jonathan asked for was an operator for > > >returning a method (as an object) which can be invoked > > >later with some arguments (or even applied with a > > >partial list of arguments for currying). > > > > > >This would be a lot more useful than a yes-or-no > > >answer about the existence of a method. Exactly. 'Yes' might be valid one moment, and invalid the next. Not a very useful operation... Returning a coderef on the other hand is useful. > > I thought about this--it's what the find_method vtable > > method was for in the first place. Unfortunately, as > > was pointed out to me, there's no good way to cache > > the result, since it could potentially be wrong by the > > time the method is actually called. > > Is that such a big deal? The same problem exists in perl 5 with the > following code: > > if(my $meth=$obj->can($action)){ > # Stuff could happen here which redefines the method in > # $obj's class However, I know it won't get redefined > # because I wrote the whole system > $obj->$meth(); > }else{ > die "Some custom error message or appropriate action"; > } I don't see it as a problem. In Perl5, you get back a coderef. And despite whether the method is modified or removed from the class in the meantime, that code reference is still valid. Sure, if you want to garrauntee you'll get the "appropriate" method implementation at a given instance in time, you'll have to code a bit more carefully, but at least you know the method implementation you've got isn't going to be changed out from under you. I'm not sure I follow the talk of invalidating method handles. I'm sure there's some use for method handles. But I hope a reference to method's implementation isn't going to run the chance of being invalidated before its called. I realize with Perl6 we'll have the possiblity of multi-method dispatch. But my assumption based on Damian's posts to perl6-language is that Perl6's ->can will support passing some form of parameter list specification so that it'd be possible for ->can to resolve the dispatch and return a coderef to the implementation before you actually invoke it. -- Garrett Goebel IS Development Specialist ScriptPro Direct: 913.403.5261 5828 Reeds Road Main: 913.384.1008 Mission, KS 66202 Fax: 913.384.2180 www.scriptpro.com [EMAIL PROTECTED]
Re: Objects, finally (try 1)
On Wed, 15 Jan 2003 01:00:59 -0500, Dan Sugalski wrote: > At 8:53 PM -0800 1/14/03, Adriano wrote: > >I think what Jonathan asked for was an operator for returning a method > >(as an object) which can be invoked later with some arguments (or even > >applied with a partial list of arguments for currying). This would be a > >lot more useful than a yes-or-no answer about the existence of a method. > > I thought about this--it's what the find_method vtable method was for in > the first place. Unfortunately, as was pointed out to me, there's no good > way to cache the result, since it could potentially be wrong by the time > the method is actually called. Is that such a big deal? The same problem exists in perl 5 with the following code: if(my $meth=$obj->can($action)){ # Stuff could happen here which redefines the method in $obj's class # However, I know it won't get redefined because I wrote the whole system $obj->$meth(); }else{ die "Some custom error message or appropriate action"; } Surely it's up to the person/compiler writing the code to decide whether it matters that the method has been redefined in the meantime. We shouldn't prevent something useful just because it's not universally applicable. -- Peter Haworth [EMAIL PROTECTED] "I can talk on this stuff for hours when given insufficient discouragement." -- Dan Sugalski
Re: Objects, finally (try 1)
If memory serves me right, Dan Sugalski wrote: > rather than attributes, but I may be incorrect here. Are the current > python instance attributes both: > > *) defined per object rather than per class > *) Essentially global, that is not hidden from parent classes or > anything. (Basically one big pool 'o things attached to the object) Speaking out of turn Python instance stuff is per Object ... And from the looks of it's just a dictionary lookup in the obj.__dict__ dictionary ... So the stuff looks essentially global. eg. class Foo: def __init__(self): pass def toString(self): return self.Name class FooBar(Foo): def __init__(self,name): self.Name=name a=FooBar("hello") print a.toString() -- hello Gopal PS: considering the fact that non-virtual functions are the only portion holding out the TreeCC Python plugin , I have had quite some heart burn with this. (or I need a switch statement :) -- The difference between insanity and genius is measured by success
Re: Objects, finally (try 1)
At 9:37 PM -0500 1/14/03, Christopher Armstrong wrote: On Tue, Jan 14, 2003 at 03:00:17PM -0500, Dan Sugalski wrote: At 11:44 AM -0800 1/14/03, Mr. Nobody wrote: >Seems pretty reasonable, but don't you mean PerlRef, PerlAttr, PerlClass, >PerlObject? Nope. There's nothing particularly perlish about them, and if we're going to have a common base set of object functionality, they'll probably be named ParrotRef/Attr/Class/Object. They should suffice for perl, python, and ruby (at the very least) unless I've missed something. Hmm, well. Are you really trying to make it so Python won't have to make a specialized subclass (err, subPMC?) of this system? If so, then it'll probably need drastic changes.. I'm a Python hacker who's pretty familiar with its object system. If you want, I can offer up some explanations/advice for making this system usable directly by Python. Thanks--I *really* appreciate that. As it stands, an implementation of the Python object system could definitely be implemented _in terms of_ what you have now, but, for example, the method system that you have worked out now would be totally unusable (afaics), as instance methods have some pretty whacky, dynamic semantics. It'd probably have to be implemented in terms of properties. Methods I'm not actually worried about, though we've not much discussed them. (I think you'll find that Python's got nothing on Ruby or Perl for method wackiness... :) Though you've definitely pointed out an area that I need to get more detailed. Method dispatch is the one place I know that we may have custom behaviour, but I don't think it'll actually be necessary. Python method dispatch, from the references I have, isn't unusual, which is a good thing. (Plus I'll be layering multimethod dispatch on top, but that'll be transparent) The problem, of course, is that either you go more static and make the very dynamic, reflective languages like Python harder to implement (or prevent them from making use of your existing abstractions like methods, as explained above), or you go more dynamic and make the more static languages (like Haskell?) slower because they'd have to implement their features in terms of dynamic ones, when a lot of the information could be available at compile-time. At the moment the only really proposed static stuff is the attribute list, and only because I'm trying hard to stick with the more efficient array structure. (We could just bite the bullet and drop to using a tree, but I think we can avoid that in the common case if we have a fallback--I just need to define the fallback now) But who knows, maybe it could be made modular enough (i.e., more interface-oriented?) to allow the best of both worlds -- I'm far too novice wrt Parrot to figure out what it'd look like, unfortunately. It'll actually look like what we have now. If you can come up with something more abstract than: callmethod P1, "foo" that delegates the calling of the foo method to the method dispatch vtable entry for the object in P1, well... gimme, I want it. :) I'll add "define method dispatch more" to the list o' stuff for the next edit of the proposal. -- Dan --"it's like this"--- Dan Sugalski even samurai [EMAIL PROTECTED] have teddy bears and even teddy bears get drunk
Re: Objects, finally (try 1)
At 9:18 PM -0500 1/14/03, Christopher Armstrong wrote: On Tue, Jan 14, 2003 at 12:38:35PM -0800, Jonathan Sillito wrote: > -Original Message- > From: Dan Sugalski [mailto:[EMAIL PROTECTED]] > A property is a runtime assignable name/value pair that you stick on > a variable or value. An attribute is a named variable that all > objects of a particular class have. > > Properties can come and go at runtime, but attributes are fixed. (I > think you could also consider attributes "instance variables", but > I'm a bit OO fuzzy so I'm not sure that's entirely right) Ok, in the case of python or ruby, instance variables are not fixed and they are not declared as part of the class. I suppose this can be handled by giving such classes one hash attribute for storing these instance variables. Yeah, that would be similar to how Python works now anyway; all instance attributes are stored in a dict which is itself accessible as an attribute on an instance: '__dict__'. Oh, except for the new __slots__ feature, which might actually find a use with the fixed-attribute-system that Dan has proposed. I'm pretty sure (though not 100% sure) that the non-slot attribute stuff in python would actually correspond to variable properties, rather than attributes, but I may be incorrect here. Are the current python instance attributes both: *) defined per object rather than per class *) Essentially global, that is not hidden from parent classes or anything. (Basically one big pool 'o things attached to the object) -- Dan --"it's like this"--- Dan Sugalski even samurai [EMAIL PROTECTED] have teddy bears and even teddy bears get drunk
Re: Objects, finally (try 1)
At 8:53 PM -0800 1/14/03, Adriano wrote: On Tue, 14 Jan 2003 17:18:22 -0500, Dan Sugalski <[EMAIL PROTECTED]> wrote: Dan: You're off. It'll be something like: callmethod Px, "method_name" or jmpmethod Px, "method_name" Jonathan: Is there going to be any way to (in PASM) find a method with out invoking it? I am not sure, but it may be useful for currying and some efficiency stuff (like moving dispatch outside of a loop that repeatedly invokes a method). Dan: Yep. There should be a can operator, though I'm not sure how often one wants to check for the existence of a method in an object without calling it. But no reason not to. More for rev 2. I think what Jonathan asked for was an operator for returning a method (as an object) which can be invoked later with some arguments (or even applied with a partial list of arguments for currying). This would be a lot more useful than a yes-or-no answer about the existence of a method. I thought about this--it's what the find_method vtable method was for in the first place. Unfortunately, as was pointed out to me, there's no good way to cache the result, since it could potentially be wrong by the time the method is actually called. We could potentially get around this if we put in place a notification framework to invalidate these method handles, but that means we have to have a fair amount of infrastructure in place to do that. (Though, honestly, I do really like the idea, as it means we can be faster by default and just pay the price when things change, but there's that pesky code that needs writing and systems that need designing to support it...) -- Dan --"it's like this"--- Dan Sugalski even samurai [EMAIL PROTECTED] have teddy bears and even teddy bears get drunk
Re: Objects, finally (try 1)
At 6:16 PM -0500 1/14/03, attriel wrote: Short version: I think both are good. Yes/No is inferrable from a pointer, but if the pointer has to include other information (and thus be a full PMC or however, precisely) seperate might be good. I think we're going to have to go with can and method calls leave it at that. Much as I'd like to have automatically fetchable method PMCs, I don't think it's feasable at this point. I may well change my mind later--certainly wouldn't be the first time. :) -- Dan --"it's like this"--- Dan Sugalski even samurai [EMAIL PROTECTED] have teddy bears and even teddy bears get drunk
Re: Objects, finally (try 1)
On Tue, Jan 14, 2003 at 03:00:17PM -0500, Dan Sugalski wrote: > At 11:44 AM -0800 1/14/03, Mr. Nobody wrote: > >Seems pretty reasonable, but don't you mean PerlRef, PerlAttr, PerlClass, > >PerlObject? > > Nope. There's nothing particularly perlish about them, and if we're > going to have a common base set of object functionality, they'll > probably be named ParrotRef/Attr/Class/Object. They should suffice > for perl, python, and ruby (at the very least) unless I've missed > something. Hmm, well. Are you really trying to make it so Python won't have to make a specialized subclass (err, subPMC?) of this system? If so, then it'll probably need drastic changes.. I'm a Python hacker who's pretty familiar with its object system. If you want, I can offer up some explanations/advice for making this system usable directly by Python. As it stands, an implementation of the Python object system could definitely be implemented _in terms of_ what you have now, but, for example, the method system that you have worked out now would be totally unusable (afaics), as instance methods have some pretty whacky, dynamic semantics. It'd probably have to be implemented in terms of properties. The problem, of course, is that either you go more static and make the very dynamic, reflective languages like Python harder to implement (or prevent them from making use of your existing abstractions like methods, as explained above), or you go more dynamic and make the more static languages (like Haskell?) slower because they'd have to implement their features in terms of dynamic ones, when a lot of the information could be available at compile-time. But who knows, maybe it could be made modular enough (i.e., more interface-oriented?) to allow the best of both worlds -- I'm far too novice wrt Parrot to figure out what it'd look like, unfortunately. I've been lurking this thread for a while, very interested, and unsure if I should offer my suggestions for making the object system more compatible with Python, and this looks like a great chance for me to jump in. :-) -- Twisted | Christopher Armstrong: International Man of Twistery Radix | Release Manager, Twisted Project -+ http://twistedmatrix.com/users/radix.twistd/
Re: Objects, finally (try 1)
On Tue, Jan 14, 2003 at 12:38:35PM -0800, Jonathan Sillito wrote: > > -Original Message- > > From: Dan Sugalski [mailto:[EMAIL PROTECTED]] > > > A property is a runtime assignable name/value pair that you stick on > > a variable or value. An attribute is a named variable that all > > objects of a particular class have. > > > > Properties can come and go at runtime, but attributes are fixed. (I > > think you could also consider attributes "instance variables", but > > I'm a bit OO fuzzy so I'm not sure that's entirely right) > > Ok, in the case of python or ruby, instance variables are not fixed and they > are not declared as part of the class. I suppose this can be handled by > giving such classes one hash attribute for storing these instance variables. Yeah, that would be similar to how Python works now anyway; all instance attributes are stored in a dict which is itself accessible as an attribute on an instance: '__dict__'. Oh, except for the new __slots__ feature, which might actually find a use with the fixed-attribute-system that Dan has proposed. -- Twisted | Christopher Armstrong: International Man of Twistery Radix | Release Manager, Twisted Project -+ http://twistedmatrix.com/users/radix.twistd/
Re: Objects, finally (try 1)
> Dan: >> Yep. There should be a can operator, though I'm not sure how often one >> wants to check for the existence of a method in an object without >> calling it. But no reason not to. More for rev 2. Adriano: > I think what Jonathan asked for was an operator for returning a method > (as an object) > which can be invoked later with some arguments (or even applied with a > partial list > of arguments for currying). > This would be a lot more useful than a yes-or-no answer about the > existence of a method. I think just knowing it exists would be useful (ala java's "reflection") since you might want to know if it exists in order to do some set of calculations before calling it, since if it doesn't exist there's a better/different set of calcs you need to do that have no use for the first set. I also like currying functions, which I can see kindof wanting the funcall pointer (although ... would it also need some way of garnering what the parameterlist (quantity or types) is?) ... Luckily the former (yes/no) can be easily inferred from the latter (funcall ptr) simply by "if the pointer is null, that'd be a no" :) although, with the parameter info that may be encapsulated and returned in some way with the fptr (if any is returned, that is), it might also be beneficial to have a seperate opcode for "just tell me if it exists", depending on how much overhead the fptr & param-info incurs ... Short version: I think both are good. Yes/No is inferrable from a pointer, but if the pointer has to include other information (and thus be a full PMC or however, precisely) seperate might be good. --attriel
Re: Objects, finally (try 1)
On Tue, 14 Jan 2003 17:18:22 -0500, Dan Sugalski <[EMAIL PROTECTED]> wrote: Dan: You're off. It'll be something like: callmethod Px, "method_name" or jmpmethod Px, "method_name" Jonathan: Is there going to be any way to (in PASM) find a method with out invoking it? I am not sure, but it may be useful for currying and some efficiency stuff (like moving dispatch outside of a loop that repeatedly invokes a method). Dan: Yep. There should be a can operator, though I'm not sure how often one wants to check for the existence of a method in an object without calling it. But no reason not to. More for rev 2. I think what Jonathan asked for was an operator for returning a method (as an object) which can be invoked later with some arguments (or even applied with a partial list of arguments for currying). This would be a lot more useful than a yes-or-no answer about the existence of a method. -- Adriano
RE: Objects, finally (try 1)
At 3:05 PM -0600 1/14/03, Garrett Goebel wrote: From: Dan Sugalski [mailto:[EMAIL PROTECTED]] Properties can come and go at runtime, but attributes are fixed. (I think you could also consider attributes "instance variables", but I'm a bit OO fuzzy so I'm not sure that's entirely right) Both classes and objects can have attributes. No runtime modification of class and/or object attributes... :( Larry's decision, and a common one with OO languages. Not universal, though, so time to go fix... :) -- Dan --"it's like this"--- Dan Sugalski even samurai [EMAIL PROTECTED] have teddy bears and even teddy bears get drunk
RE: Objects, finally (try 1)
At 1:24 PM -0800 1/14/03, Mr. Nobody wrote: So a property is just an element in a hash attribute? No. Properties are separate from anything OO. -- Dan --"it's like this"--- Dan Sugalski even samurai [EMAIL PROTECTED] have teddy bears and even teddy bears get drunk
RE: Objects, finally (try 1)
At 12:38 PM -0800 1/14/03, Jonathan Sillito wrote: > -Original Message- From: Dan Sugalski [mailto:[EMAIL PROTECTED]] A property is a runtime assignable name/value pair that you stick on a variable or value. An attribute is a named variable that all objects of a particular class have. Properties can come and go at runtime, but attributes are fixed. (I think you could also consider attributes "instance variables", but I'm a bit OO fuzzy so I'm not sure that's entirely right) Ok, in the case of python or ruby, instance variables are not fixed and they are not declared as part of the class. I suppose this can be handled by giving such classes one hash attribute for storing these instance variables. Less work than that even. While the attributes aren't declared formally, the compiler definitely knows what they are, and can allocate space as needed. The only place you'll run into issues is either runtime introduction of attributes (after the class has been compiled) or writing to attributes by name. Though the need to add attributes after the fact is an important one--we don't want to have to go rejigging every object that derives from some wacky parent class every time that class adds or removes an attribute. > You're off. It'll be something like: callmethod Px, "method_name" or jmpmethod Px, "method_name" Is there going to be any way to (in PASM) find a method with out invoking it? I am not sure, but it may be useful for currying and some efficiency stuff (like moving dispatch outside of a loop that repeatedly invokes a method). Yep. There should be a can operator, though I'm not sure how often one wants to check for the existence of a method in an object without calling it. But no reason not to. More for rev 2. > >Do we store ptrs to parent classes in one of these slots? Also Can I access >slots like: > > set Px, Py[1]# store the name to offset hash in Px No the parent's gotten to via the vtable, and yes you can. Sorry if this is obvious, but which vtable method is used to get the parents? It should be hanging off the vtable as one of the fixed slots. I think it isn't, though, so that needs fixing too. -- Dan --"it's like this"--- Dan Sugalski even samurai [EMAIL PROTECTED] have teddy bears and even teddy bears get drunk
RE: Objects, finally (try 1)
--- Garrett Goebel <[EMAIL PROTECTED]> wrote: > From: Dan Sugalski [mailto:[EMAIL PROTECTED]] > > At 9:51 AM -0800 1/14/03, Jonathan Sillito wrote: > > > > > >Below are some questions about this ... > > > > And now some answers. :) > > > > >> From: Dan Sugalski [mailto:[EMAIL PROTECTED]] > > > > > >[snip] > > > > > >> Objects, as far as I see it, have the following properties: > > >> > > >> 1) They have runtime-assignable properties > > > > > >Terminology question: what is the difference between a > > >property and an attribute? Perhaps the answer could go in > > >the glossary. > > > > A property is a runtime assignable name/value pair that you stick on > > a variable or value. An attribute is a named variable that all > > objects of a particular class have. > > For a while perl6-language was using both terms for the runtime > variable/value name/value tag. This stems from Perl 5.6's attributes and > Attribute::Handlers modules. But in Perl6 s/attributes/properties/ because > properties have nothing to do with OO, whereas 'attribute' has the > "object/class data-member" meaning in OO. > > > Properties can come and go at runtime, but attributes are fixed. (I > > think you could also consider attributes "instance variables", but > > I'm a bit OO fuzzy so I'm not sure that's entirely right) > > Both classes and objects can have attributes. > > No runtime modification of class and/or object attributes... :( So a property is just an element in a hash attribute? __ Do you Yahoo!? Yahoo! Mail Plus - Powerful. Affordable. Sign up now. http://mailplus.yahoo.com
RE: Objects, finally (try 1)
From: Dan Sugalski [mailto:[EMAIL PROTECTED]] > At 9:51 AM -0800 1/14/03, Jonathan Sillito wrote: > > > >Below are some questions about this ... > > And now some answers. :) > > >> From: Dan Sugalski [mailto:[EMAIL PROTECTED]] > > > >[snip] > > > >> Objects, as far as I see it, have the following properties: > >> > >> 1) They have runtime-assignable properties > > > >Terminology question: what is the difference between a > >property and an attribute? Perhaps the answer could go in > >the glossary. > > A property is a runtime assignable name/value pair that you stick on > a variable or value. An attribute is a named variable that all > objects of a particular class have. For a while perl6-language was using both terms for the runtime variable/value name/value tag. This stems from Perl 5.6's attributes and Attribute::Handlers modules. But in Perl6 s/attributes/properties/ because properties have nothing to do with OO, whereas 'attribute' has the "object/class data-member" meaning in OO. > Properties can come and go at runtime, but attributes are fixed. (I > think you could also consider attributes "instance variables", but > I'm a bit OO fuzzy so I'm not sure that's entirely right) Both classes and objects can have attributes. No runtime modification of class and/or object attributes... :( -- Garrett Goebel IS Development Specialist ScriptPro Direct: 913.403.5261 5828 Reeds Road Main: 913.384.1008 Mission, KS 66202 Fax: 913.384.2180 www.scriptpro.com [EMAIL PROTECTED]
RE: Objects, finally (try 1)
> -Original Message- > From: Dan Sugalski [mailto:[EMAIL PROTECTED]] > A property is a runtime assignable name/value pair that you stick on > a variable or value. An attribute is a named variable that all > objects of a particular class have. > > Properties can come and go at runtime, but attributes are fixed. (I > think you could also consider attributes "instance variables", but > I'm a bit OO fuzzy so I'm not sure that's entirely right) Ok, in the case of python or ruby, instance variables are not fixed and they are not declared as part of the class. I suppose this can be handled by giving such classes one hash attribute for storing these instance variables. > You're off. It'll be something like: > > callmethod Px, "method_name" > > or > > jmpmethod Px, "method_name" > Is there going to be any way to (in PASM) find a method with out invoking it? I am not sure, but it may be useful for currying and some efficiency stuff (like moving dispatch outside of a loop that repeatedly invokes a method). > >Do we store ptrs to parent classes in one of these slots? Also > Can I access > >slots like: > > > > set Px, Py[1]# store the name to offset hash in Px > > No the parent's gotten to via the vtable, and yes you can. Sorry if this is obvious, but which vtable method is used to get the parents? Thanks! -- Jonathan Sillito
RE: Objects, finally (try 1)
At 11:44 AM -0800 1/14/03, Mr. Nobody wrote: Seems pretty reasonable, but don't you mean PerlRef, PerlAttr, PerlClass, PerlObject? Nope. There's nothing particularly perlish about them, and if we're going to have a common base set of object functionality, they'll probably be named ParrotRef/Attr/Class/Object. They should suffice for perl, python, and ruby (at the very least) unless I've missed something. -- Dan --"it's like this"--- Dan Sugalski even samurai [EMAIL PROTECTED] have teddy bears and even teddy bears get drunk
RE: Objects, finally (try 1)
--- Dan Sugalski <[EMAIL PROTECTED]> wrote: > At 9:51 AM -0800 1/14/03, Jonathan Sillito wrote: > >Dan, > > > >Below are some questions about this ... > > And now some answers. :) > > > > -Original Message- > >> From: Dan Sugalski [mailto:[EMAIL PROTECTED]] > > > >[snip] > > > >> Objects, as far as I see it, have the following properties: > >> > >> 1) They have runtime-assignable properties > > > >Terminology question: what is the difference between a property and an > >attribute? Perhaps the answer could go in the glossary. > > A property is a runtime assignable name/value pair that you stick on > a variable or value. An attribute is a named variable that all > objects of a particular class have. > > Properties can come and go at runtime, but attributes are fixed. (I > think you could also consider attributes "instance variables", but > I'm a bit OO fuzzy so I'm not sure that's entirely right) > > > > #3 Since each class has a PMC type, we just need to associate the PMC > >>type with the data a class needs. Also pretty much no big deal, and > >>something we already have facilities for. > > > >So, while there may be exceptions, generally all classes will be instances > >of the Class PMC, true? > > Generally, yes. > > > > The call/jmpmeth opcodes either make a returnable or non-returnable > >> method call. They fetch the function pointer from the object PMC and > >> either dispatch to it or save the current state and jsr to it. Note > >> that you can't jmpmeth into a C-implemented method, so no tail > >> calling into those without some wrapper opcodes. The registers still > >> need to be set up appropriately, just like with a regular sub call. > > > >So the call opcode takes a method name or offset and calls a vtable method > >to find the method and then invokes it? > > Yep. > > > > The find_method vtable entry should die, and be replaced with a plain > >> method entry. This should return either the address of the start of > >> the method's bytecode, or NULL. The NULL return is for those cases > >> where the method actually executed via native code, and thus doesn't > >> have to go anywhere. If an address is returned it's expected that the > >> engine will immediately dispatch to that spot, obeying parrot's > >> calling conventions. > > > >Not sure what this means, does it mean that there is a method named > >"find_method" accessed something like > > > > call Px, Py, "find_method" > > > >which I can then call to find the method or am I off? > > You're off. It'll be something like: > > callmethod Px, "method_name" > > or > > jmpmethod Px, "method_name" > > > > The structures: > >> > >> *) Attr PMCs have an array off their data pointer. > >> > >> *) Classes are variants of Attr PMCs. They have the following > >>guaranteed attributes in slots: > >> > >> 0) Hash with class name to attribute offset > > > >I am not sure what this means, Don't we already have the class and it's > >attributes if we are accessing these slots? > > Well... > > The problem is finding which slot to access, a problem that's > compounded by multiple inheritance. > > Let's say, for example, that you have a class A, which inherits from > B and C. Let's also say that each class has 10 attributes, and you > have a fixed-width mail reading font. The inheritance diagram then > looks like: > > > C B >\ / > | > A > > Since the attributes are an array, it looks like: > > CCBBAA > 012345678901234567890123456789 > > We make a method call and it gets resolved to be one we inherited > from B. Now, how does B know which slots in the object holds its > attributes? In a single-inheritance case, it could assume that since > it has no parents it can start at slot 0, but that doesn't work > here--C is first. So what B needs to do is query the object to find > out where the attributes for class B start in the attribute array, > and to do that it looks in the hash stored in the object's class > attributes that maps class names to starting offsets. From there B > can figure out what slot to look in, since class attributes are > contiguous, and thus there only needs to be a single lookup. > > Single inheritance makes all this resolvable at compile time, which > would be so much nicer. Alas, no joy for us there. > > > > 1) Hash with attribute name to attribute offset (relative to the > >> offset found from the hash in slot 0, generally known at > >> compile time, but introspection is nice) > >> 2) Integer number of attributes this class has > >> 3) Notification array > > > >Do we store ptrs to parent classes in one of these slots? Also Can I > access > >slots like: > > > > set Px, Py[1]# store the name to offset hash in Px > > No the parent's gotten to via the vtable, and yes you can. > > >So to sum up we need the following pmc's: > > > > pmclass Ref { > > data is a
RE: Objects, finally (try 1)
At 9:51 AM -0800 1/14/03, Jonathan Sillito wrote: Dan, Below are some questions about this ... And now some answers. :) > -Original Message- From: Dan Sugalski [mailto:[EMAIL PROTECTED]] [snip] Objects, as far as I see it, have the following properties: 1) They have runtime-assignable properties Terminology question: what is the difference between a property and an attribute? Perhaps the answer could go in the glossary. A property is a runtime assignable name/value pair that you stick on a variable or value. An attribute is a named variable that all objects of a particular class have. Properties can come and go at runtime, but attributes are fixed. (I think you could also consider attributes "instance variables", but I'm a bit OO fuzzy so I'm not sure that's entirely right) > #3 Since each class has a PMC type, we just need to associate the PMC type with the data a class needs. Also pretty much no big deal, and something we already have facilities for. So, while there may be exceptions, generally all classes will be instances of the Class PMC, true? Generally, yes. > The call/jmpmeth opcodes either make a returnable or non-returnable method call. They fetch the function pointer from the object PMC and either dispatch to it or save the current state and jsr to it. Note that you can't jmpmeth into a C-implemented method, so no tail calling into those without some wrapper opcodes. The registers still need to be set up appropriately, just like with a regular sub call. So the call opcode takes a method name or offset and calls a vtable method to find the method and then invokes it? Yep. > The find_method vtable entry should die, and be replaced with a plain method entry. This should return either the address of the start of the method's bytecode, or NULL. The NULL return is for those cases where the method actually executed via native code, and thus doesn't have to go anywhere. If an address is returned it's expected that the engine will immediately dispatch to that spot, obeying parrot's calling conventions. Not sure what this means, does it mean that there is a method named "find_method" accessed something like call Px, Py, "find_method" which I can then call to find the method or am I off? You're off. It'll be something like: callmethod Px, "method_name" or jmpmethod Px, "method_name" > The structures: *) Attr PMCs have an array off their data pointer. *) Classes are variants of Attr PMCs. They have the following guaranteed attributes in slots: 0) Hash with class name to attribute offset I am not sure what this means, Don't we already have the class and it's attributes if we are accessing these slots? Well... The problem is finding which slot to access, a problem that's compounded by multiple inheritance. Let's say, for example, that you have a class A, which inherits from B and C. Let's also say that each class has 10 attributes, and you have a fixed-width mail reading font. The inheritance diagram then looks like: C B \ / | A Since the attributes are an array, it looks like: CCBBAA 012345678901234567890123456789 We make a method call and it gets resolved to be one we inherited from B. Now, how does B know which slots in the object holds its attributes? In a single-inheritance case, it could assume that since it has no parents it can start at slot 0, but that doesn't work here--C is first. So what B needs to do is query the object to find out where the attributes for class B start in the attribute array, and to do that it looks in the hash stored in the object's class attributes that maps class names to starting offsets. From there B can figure out what slot to look in, since class attributes are contiguous, and thus there only needs to be a single lookup. Single inheritance makes all this resolvable at compile time, which would be so much nicer. Alas, no joy for us there. > 1) Hash with attribute name to attribute offset (relative to the offset found from the hash in slot 0, generally known at compile time, but introspection is nice) 2) Integer number of attributes this class has 3) Notification array Do we store ptrs to parent classes in one of these slots? Also Can I access slots like: set Px, Py[1]# store the name to offset hash in Px No the parent's gotten to via the vtable, and yes you can. So to sum up we need the following pmc's: pmclass Ref { data is a pointer to an object } pmclass Attr { data is an array of attributes } pmclass Class extends Attr { } pmclass Object { this was not explained, but I guess it at least has a reference to a Class and field data ??? } Does that cover it? I'd say so, yep. -- Dan --"it's like this"--- Dan Sugalski
RE: Objects, finally (try 1)
Dan, Below are some questions about this ... > -Original Message- > From: Dan Sugalski [mailto:[EMAIL PROTECTED]] [snip] > Objects, as far as I see it, have the following properties: > > 1) They have runtime-assignable properties Terminology question: what is the difference between a property and an attribute? Perhaps the answer could go in the glossary. [snip] > #3 Since each class has a PMC type, we just need to associate the PMC > type with the data a class needs. Also pretty much no big deal, and > something we already have facilities for. So, while there may be exceptions, generally all classes will be instances of the Class PMC, true? [snip] > The call/jmpmeth opcodes either make a returnable or non-returnable > method call. They fetch the function pointer from the object PMC and > either dispatch to it or save the current state and jsr to it. Note > that you can't jmpmeth into a C-implemented method, so no tail > calling into those without some wrapper opcodes. The registers still > need to be set up appropriately, just like with a regular sub call. So the call opcode takes a method name or offset and calls a vtable method to find the method and then invokes it? > The find_method vtable entry should die, and be replaced with a plain > method entry. This should return either the address of the start of > the method's bytecode, or NULL. The NULL return is for those cases > where the method actually executed via native code, and thus doesn't > have to go anywhere. If an address is returned it's expected that the > engine will immediately dispatch to that spot, obeying parrot's > calling conventions. Not sure what this means, does it mean that there is a method named "find_method" accessed something like call Px, Py, "find_method" which I can then call to find the method or am I off? [snip] > The structures: > > *) Attr PMCs have an array off their data pointer. > > *) Classes are variants of Attr PMCs. They have the following > guaranteed attributes in slots: > > 0) Hash with class name to attribute offset I am not sure what this means, Don't we already have the class and it's attributes if we are accessing these slots? > 1) Hash with attribute name to attribute offset (relative to the >offset found from the hash in slot 0, generally known at >compile time, but introspection is nice) > 2) Integer number of attributes this class has > 3) Notification array Do we store ptrs to parent classes in one of these slots? Also Can I access slots like: set Px, Py[1]# store the name to offset hash in Px [snip] So to sum up we need the following pmc's: pmclass Ref { data is a pointer to an object } pmclass Attr { data is an array of attributes } pmclass Class extends Attr { } pmclass Object { this was not explained, but I guess it at least has a reference to a Class and field data ??? } Does that cover it? -- Jonathan Sillito
Re: Objects, finally (try 1)
On Fri, 10 Jan 2003 11:49:14 -0500, Dan Sugalski wrote: > At 1:37 PM + 1/10/03, Peter Haworth wrote: > >On Thu, 9 Jan 2003 16:40:20 -0500, Dan Sugalski wrote: > >> #10 We do MI, but we don't instantiate a class' attributes multiple > >>times if its in the hierarchy for a class more than once. If it is, > >>the leftmost instance is real, the rest are virtual > > > >This will mean we can't support Eiffel > > Nope. :) I realised this soon after leaving for the weekend, thus leaving myself looking stupid for an extended period of time :-) > Eiffel's classes, IIRC, are compile-time fixed so it can do the necessary > code cloning and renaming magic to make it all work. Exactly. At the implementation level you end up directly inheriting once from the offending class, and reimplementing some/all of the features for the repeated inheritance, either directly in the derived class, or in a specially constructed modified copy of the base class which is only used for inheritance by the derived class. I'm not an Eiffel programmer either, but I have read OOSC, so I know enough to make me dangerous. -- Peter Haworth [EMAIL PROTECTED] "An IRC channel, in ERROR?! On Undernet no less?! THE DEUCE YOU SAY!! Next thing you're going to tell me the commentary on Slashdot isn't totally impartial!" -- Michael G Schwern
RE: Objects, finally (try 1)
At 10:07 AM -0800 1/12/03, Brent Dax wrote: Gopal V: # But coming back to parrot ... I don't think parrot uses UTF8 # (from what I could gather it seems to be all ASCII ?) ... Or # is UTF8 hiding in # somewhere ?... Parrot will have a "default string type" that's build-specific, so that e.g. Asian nations can have whatever the most popular encoding is in their country. The "default default string type" will be utf8, but it's currently ASCII because Unicode Is Hard. Well... default may well be latin-1 or plain ASCII, because Unicode Is Unneccesary. :) Well, most of the time at least. Unicode, of course, will be available, but if the data coming in is ASCII or Latin-1, re-encoding's a bit of a waste of time. -- Dan --"it's like this"--- Dan Sugalski even samurai [EMAIL PROTECTED] have teddy bears and even teddy bears get drunk
Re: Objects, finally (try 1)
At 7:27 PM +0530 1/12/03, Gopal V wrote: But coming back to parrot ... I don't think parrot uses UTF8 (from what I could gather it seems to be all ASCII ?) ... Or is UTF8 hiding in somewhere ?... Unicode is hiding in the ICU directory, which we need to get integrated. We'll probably be mostly UTF16, only because that's what ICU uses and there's no good reason to reinvent the wheel again. All three encodings and their endian variants will be supported, as will a variety of other encodings and character sets. -- Dan --"it's like this"--- Dan Sugalski even samurai [EMAIL PROTECTED] have teddy bears and even teddy bears get drunk
RE: Objects, finally (try 1)
Gopal V: # But coming back to parrot ... I don't think parrot uses UTF8 # (from what I could gather it seems to be all ASCII ?) ... Or # is UTF8 hiding in # somewhere ?... Parrot will have a "default string type" that's build-specific, so that e.g. Asian nations can have whatever the most popular encoding is in their country. The "default default string type" will be utf8, but it's currently ASCII because Unicode Is Hard. --Brent Dax <[EMAIL PROTECTED]> @roles=map {"Parrot $_"} qw(embedding regexen Configure) "If you want to propagate an outrageously evil idea, your conclusion must be brazenly clear, but your proof unintelligible." --Ayn Rand, explaining how today's philosophies came to be
Re: Objects, finally (try 1)
On 01/12/03 Gopal V wrote: > If memory serves me right, Paolo Molaro wrote: > > The CLR runtimes use 16 bit chars and UTF16-encoded strings (at least as > > far as it's visible to the 'user' programs). > > 1023.2.3 #Strings heap > 11 The stream of bytes pointed to by a "#Strings" header is the physical >representation of the logical string heap. > 13 but parts that are reachable from a table shall contain a valid null >terminated UTF8 string. When the #String The #Strings heap doesn't contain strings for programs that run in the CLR (unlike the #US -user sring- heap that contains the strings in UTF-16) encoding. What matters, though, is the encoding of the String class at runtime and that is defined to be UTF-16, it has absolutely no importance what encoding it has on disk (even though that encoding is still UTF-16). lupus -- - [EMAIL PROTECTED] debian/rules [EMAIL PROTECTED] Monkeys do it better
Re: Objects, finally (try 1)
If memory serves me right, Paolo Molaro wrote: > The CLR runtimes use 16 bit chars and UTF16-encoded strings (at least as > far as it's visible to the 'user' programs). 1023.2.3 #Strings heap 11 The stream of bytes pointed to by a "#Strings" header is the physical representation of the logical string heap. 13 but parts that are reachable from a table shall contain a valid null terminated UTF8 string. When the #String So I think the runtime does a UTF16 conversion , I suppose ...So you're right ... all C# programs get UTF16 strings to work with... but that's not the way they're in meta-data... (JVM also has UTF8 strings and 16 bit chars, it's not really a big issue :) But coming back to parrot ... I don't think parrot uses UTF8 (from what I could gather it seems to be all ASCII ?) ... Or is UTF8 hiding in somewhere ?... Gopal -- The difference between insanity and genius is measured by success
Re: Objects, finally (try 1)
On 01/11/03 Nicholas Clark wrote: > > This allows us to declare 8bit characters and strings of those and all the > > stuff we're used to with C like unions ... (C# has 16bit chars, and strings > > are UTF8 encoded , IIRC) ... > > That doesn't sound right. But if it is right, then it sounds very wrong. > > (Translation: Are you sure about your terms, because what you describe sounds > wonky. Hence if they are using UTF8 but with 16 bit chars, that feels like a > silly design decision to me. Perl 5 performance is not enjoying a variable > length encoding, but using an 8 bit encoding in 8 bit chars at least makes > it small in memory.) The CLR runtimes use 16 bit chars and UTF16-encoded strings (at least as far as it's visible to the 'user' programs). lupus -- - [EMAIL PROTECTED] debian/rules [EMAIL PROTECTED] Monkeys do it better
Re: Objects, finally (try 1)
At 6:12 PM +0100 1/10/03, Jerome Quelin wrote: Dan Sugalski wrote: and who's got questions on how this works? (I can put together examples, but this is pretty long as it is, and I think it's reasonably self-explanatory. Besides, assembly language isn't generally the best way to demonstrate anything... :) Well, as far as I'm concerned, an assembly snippet would be nice. But I can as well wait for implementation and study what will be relevant to objects in the t/ directory. I'll put together some of what I'm thinking of next week with the first rev of the object spec. -- Dan --"it's like this"--- Dan Sugalski even samurai [EMAIL PROTECTED] have teddy bears and even teddy bears get drunk
Re: Objects, finally (try 1)
At 4:08 PM + 1/11/03, Nicholas Clark wrote: On Thu, Jan 09, 2003 at 04:40:20PM -0500, Dan Sugalski wrote: The find_method vtable entry should die, and be replaced with a plain method entry. This should return either the address of the start of the method's bytecode, or NULL. The NULL return is for those cases where the method actually executed via native code, and thus doesn't have to go anywhere. If an address is returned it's expected that the engine will immediately dispatch to that spot, obeying parrot's calling conventions. What about the case where the object doesn't have the method you're asking for? You seem to be using NULL to mean something other than "not found", so does that mean not found is an exception? Sorry. The assumption is one of three things happen: 1) A value is returned, which is the address of the parrot code to dispatch to 2) A NULL is returned, which indicates the method call has been made and the interpreter can proceed to the next instruction in the stream 3) An exception is thrown, indicating that the method couldn't be called. And if NULL is returned it is expected that the method has already been called? If so, there doesn't seem to be any way to find out if a PMC possesses (modulo AUTOLOAD) a method, without the danger of it being called. If we don't have a can in the vtable, then we need to fix that. :) Will there be anything built in at parrot level like Perl's AUTOLOAD system? Or will that have to be done explicitly by the perl6 code generator wrapping methods in a routine that catches the "not found" exception, and attempts to use AUTOLOAD? [and whatever multimatch despatch system perl6 will be using to find the "best" method] Parrot will have an AUTOLOAD-style fallback mechanism available to it. I'll add that to the design todo list for the edited version of objects. -- Dan --"it's like this"--- Dan Sugalski even samurai [EMAIL PROTECTED] have teddy bears and even teddy bears get drunk
Re: Objects, finally (try 1)
If memory serves me right, Nicholas Clark wrote: > That doesn't sound right. But if it is right, then it sounds very wrong. > > (Translation: Are you sure about your terms, because what you describe sounds > wonky. Hence if they are using UTF8 but with 16 bit chars, that feels like a > silly design decision to me. Perl 5 performance is not enjoying a variable > length encoding, but using an 8 bit encoding in 8 bit chars at least makes > it small in memory.) I mean they're using UTF8 encoded strings ... and chars are 16 bit ... which means that reading chars from strings is wonky (from all I remember, ILString* uses int16[] for storing stuff... but the files do use UTF8).. Actually I think the ILImage functions in Portable.net abstract out the UTF8 reading and return int16* arrays ... Hope that makes more sense :) > Ooh. So what happens if I try to run: > > char *a = 0; > *a++; Assuming you meant (*a)++; ... coz *a++; is optimsed away into just a++; by GCC .. > Does the VM just "segfault" the failing thread, rather than all threads in > a process? How does this do for an answer ? Uncaught exception: System.NullReferenceException: The value 'null' was found where an instance of an object was required at .main() in segfault.c:3 at ..start(String[]) Bye Bye segfaults, hello exceptions ... > Hmm. So if DotGNU has a C to Parrot compiler, then we just compile the perl5 > source code down to Parrot bytecode, et voilá, we have a perl implementation. This is assuming we can get all the perl5 dependencies compiled to Parrot without any issues ... (in fact this might be very,very hard... considering the fact that parrot codegen is still commented out for most of portable.net). > I do hope no-one wanted it to go fast. :-) > [then again, I wonder how the parrot JIT would cope] Which is why nobody is really interested in doing this :-) ... we're building the C compiler for fun ... > So Rhys is mad: > > > The difference between insanity and genius is measured by success > > I hope he falls on the right side of the divide. That's *my* sig ... and I'm attempting a cross-over :) Gopal -- The difference between insanity and genius is measured by success
Re: Objects, finally (try 1)
On Sat, Jan 11, 2003 at 06:34:56PM +0530, Gopal V wrote: > If memory serves me right, Nicholas Clark wrote: > > fussy. I presume Rhys is thinking about compiling C code to parrot, and then > > linking through to native C code (such as the native standard C library) via > > parrot. > > Nope ... At least for our .NET platorm stuff ,we are planning to compile > glibc into IL so that the "native ABI" is accessed only via the engine. Oh right. As you commented on IRC, I am very wrong. > Rhys has also been really cool about the data stored via C ... So legacy > code which used fixed size files (otherwise called "records") will be useful. > This allows us to declare 8bit characters and strings of those and all the > stuff we're used to with C like unions ... (C# has 16bit chars, and strings > are UTF8 encoded , IIRC) ... That doesn't sound right. But if it is right, then it sounds very wrong. (Translation: Are you sure about your terms, because what you describe sounds wonky. Hence if they are using UTF8 but with 16 bit chars, that feels like a silly design decision to me. Perl 5 performance is not enjoying a variable length encoding, but using an 8 bit encoding in 8 bit chars at least makes it small in memory.) > So even with all the type-safety of IL we can run the following code ... > > float a=3.14; > int b=*((int*)(&(a))); Ooh. So what happens if I try to run: char *a = 0; *a++; :-) Does the VM just "segfault" the failing thread, rather than all threads in a process? > What Rhys is using right now is a custom stdlib which is called pnetC and > was just released ... People *really* curious about what Rhys is doing > (and what those half-a-million lines are doing in DotGNU) should try the > Portable.net C compiler (http://dotgnu.org/downloads/pnet/) .. We have > mirrors on each gnu mirror as /projects/dotgnu ... (since we're likely to > be slashdotted to death soon) > I'm really working only to get C# compiled to Parrot other language > frontends in development like Java or C or JScript can wait a looong time. Hmm. So if DotGNU has a C to Parrot compiler, then we just compile the perl5 source code down to Parrot bytecode, et voilá, we have a perl implementation. I do hope no-one wanted it to go fast. :-) [then again, I wonder how the parrot JIT would cope] So Rhys is mad: > The difference between insanity and genius is measured by success I hope he falls on the right side of the divide. Nicholas Clark
Re: Objects, finally (try 1)
If memory serves me right, Nicholas Clark wrote: > fussy. I presume Rhys is thinking about compiling C code to parrot, and then > linking through to native C code (such as the native standard C library) via > parrot. Nope ... At least for our .NET platorm stuff ,we are planning to compile glibc into IL so that the "native ABI" is accessed only via the engine. Most peices of glibc, depend on a few platform functions to run (most notably some in unistd.h) ... Most of the other peices of glibc can be directly used like the printf formatting code or file functions , once these underlying posix calls are in place... this is consistent with design philosophy of glibc which has been source portability rather than binary. So get your own glibc-managed.dll according to long,int, and char sizes :) > without needing a C compiler, but you'd not be able to call out from your > C code. We are facing a similar situation, but only that we have PInvoke (like your NCI) which allows you to define PInvoke methods from Managed C (I'd prefer the term Micro-Managed :) But the following does work for some functions :) extern int puts(const char *s) __attribute__((__pinvoke__("libc.so.6"))); mm... ugly ! Rhys has also been really cool about the data stored via C ... So legacy code which used fixed size files (otherwise called "records") will be useful. This allows us to declare 8bit characters and strings of those and all the stuff we're used to with C like unions ... (C# has 16bit chars, and strings are UTF8 encoded , IIRC) ... In short, we will keep similar layouts in memory for structs and unions as far as possible ... (unions without offset based access to memory boggles my mind) So even with all the type-safety of IL we can run the following code ... float a=3.14; int b=*((int*)(&(a))); > What Rhys is thinking about is potentially far more interesting, as it would What Rhys is using right now is a custom stdlib which is called pnetC and was just released ... People *really* curious about what Rhys is doing (and what those half-a-million lines are doing in DotGNU) should try the Portable.net C compiler (http://dotgnu.org/downloads/pnet/) .. We have mirrors on each gnu mirror as /projects/dotgnu ... (since we're likely to be slashdotted to death soon) Very, Very curiously ... I can call C# methods from Managed C, but not the otherway around :) .. and I can call native methods from Managed C , but that's dreadfully unportable like you said ... I'm really working only to get C# compiled to Parrot other language frontends in development like Java or C or JScript can wait a looong time. Gopal -- The difference between insanity and genius is measured by success
Re: Objects, finally (try 1)
On Sat, Jan 11, 2003 at 10:12:42AM +0530, Gopal V wrote: > If memory serves me right, Chris Dutton wrote: > > Actually, if you really want Eiffel to compile to Parrot, it might be > > interesting to work on getting ANSI C to compile to Parrot first, since > > most Eiffel compilers use compilation to C as an intermediate step. > [11:32] Dan: I was more thinking of the memory layout issues. C code is >very particular about struct layout, array representation, etc. I didn't see any >opcodes that would allow one to do "pull an int32 out of offset N from this pointer". > [11:33] C's not at all particular about struct layout, unless they changed the >standard. > [11:33] Still, you can do them either with struct PMCs, whcih'd be slowish, or >with the pack/unpack opcodes, which I bet are insufficiently documetned Probably this has all been worked out by now, but Rhys and Dan are coming at it from different angles. C isn't fussy, but the ABI for a platform is very fussy. I presume Rhys is thinking about compiling C code to parrot, and then linking through to native C code (such as the native standard C library) via parrot. Dan's assuming that C code we compile never wants to call out to the platform. If I remember the terms correctly, Dan's thinking about free standing C implementations. Effectively that would give Inline::C without needing a C compiler, but you'd not be able to call out from your C code. What Rhys is thinking about is potentially far more interesting, as it would allow the perl6 version of Inline::C to wrap external libraries supplied only as objects and headers, without needing a C compiler on the machine. It's also harder, partly because such a system would need to know the ABI for each platform you wanted to do this on. But if anyone has tuits, could we have a z-code interpreter first please? Or better still, a unified, fast, assembler? (with a pony?) Nicholas Clark
Re: Objects, finally (try 1)
Jerome Quelin wrote: Dan Sugalski wrote: ... Besides, assembly language isn't generally the best way to demonstrate anything... :) Indeed, once you wrote some Parrot assembly code to support a^Htwo stupid^Wesoteric languages, Parrot assembly is quite a nice and easy way to see how theory behaves in real life... :o) Good point. The implmentation of $thing does show, how's the real usability. These totally unneeded^Wsuperfluous^Wfine languages brought parrot & imcc a lot further. Jerome leo
Re: Objects, finally (try 1)
If memory serves me right, Chris Dutton wrote: > Actually, if you really want Eiffel to compile to Parrot, it might be > interesting to work on getting ANSI C to compile to Parrot first, since > most Eiffel compilers use compilation to C as an intermediate step. This won't be too much of stretch We already have an ANSI C compiler working well with DotGNU pnet.. (with a IL output plugin)... [11:31] Dan: to go off on a different tangent now - C support [11:31] Dan: compiling C to Parrot, that is [11:31] Ah, that. Yeah, definitely doable. It'll be rather slow, though [11:31] Our function call overhead's rather large compared to what C needs [11:32] Still, I find the thought of C with native continuations rather interesting. Scary, but interesting [11:32] Dan: I was more thinking of the memory layout issues. C code is very particular about struct layout, array representation, etc. I didn't see any opcodes that would allow one to do "pull an int32 out of offset N from this pointer". [11:33] C's not at all particular about struct layout, unless they changed the standard. [11:33] Still, you can do them either with struct PMCs, whcih'd be slowish, or with the pack/unpack opcodes, which I bet are insufficiently documetned [11:34] Action: Dan apparently can't type this evening [11:35] Still, the packed structures need more thoght. Hrm. [11:35] Dan: I suppose a better question would be "is supporting C a goal, or would it just be a cool hack but otherwise uninteresting?" [11:36] because, as you say, it wouldn't be terribly efficient ... [11:36] Neither, really. It's interesting in the sense that it'd let people use code that they otherwise couldn't, if they don't have a C compiler for. [11:36] But it's definitely not a primary goal [11:36] Consider it both mildly interesting and mildly bemusing :) [11:37] Dan: It could make it very useful as a power tool [11:37] Could someone toss up the Parrot URL so I can find out what it is? :) [11:37] Dan: sort of a "swiss army knife" kind of thing [11:37] True, but I'm not willing to lose sight of the primary goal for it. Was our last conversation about Parrot & C compilers .. We'll be adding a Parrot codegen for the compiler backend , as soon as the Objects are set in stone So possibly there exists a possibility for doing up the C compiler (with codegen tweaking) to develop a C compiler targetting Parrot. Gopal -- The difference between insanity and genius is measured by success
Re: Objects, finally (try 1)
Here are some examples from Object Oriented Software Construction (Second Edtion), Chapter 15 (Multiple Inheritance): * Simple multiple inheritance: class PLANE ... class ASSET ... class COMPANY_PLANE inherit PLANE ASSET ... or class TREE [G] ... -- Parametric Polymorphism class RECTANGLE ... class WINDOW inherit TREE[WINDOW] RECTANGLE ... * Renaming: class WINDOW inherit TREE [WINDOW] rename child as subwindow, is_leaf as is_terminal, root as screen, arity as child_count, ... end RECTANGLE ... * Page 548, "Unobtrusive repeated inheritance": Cases of repeated inheritance [...], with duplicated features as well as shared ones, do occur in practice, but not frequently. THey are not for beginners; only after you have reached a good level of sophistication and practice in object technology should you encounter any need for them. If you are writing a straightforward application and end up using repeated inheritance, you are probably making things more complicated than you need to. * Redundant inheritance: class A ... class B inherit A ... class D inherit B A ... -- Forgetting that B inherits from A In Eiffel, the default sharing semantics for multiple inheritance means this misstep doesn't cause weird things to happen. * Other weirdness class DRIVER ... -- violation count, address, etc. class US_DRIVER inherit DRIVER ... class FR_DRIVER inherit DRIVER ... -- Ah, France! class US_FR_DRIVER inherit US_DRIVER rename violations as us_violations, ... FR_DRIVER rename violations as fr_violations. PLEASE NOTE: I'm not a fan of this example. But, it comes from the book. I'd be more likely to model this as DRIVER has-a SET of LICENSEs keyed-by AUTHORITY, where the LICENSE has stuff like licensed address and violation count, etc. But, then, my thinking and modeling habits tend toward the dynamic, and Eiffel tends toward the static. The implications of continuing the pattern of this example in the face of a larger set of authorities (countries) is, well, explosive (speaking combinatorically). In the face of a dynamic set of authorities, its unworkable. Anyway, I know that the Eiffel libraries make plenty of use of Eiffel's inheritance and assertion mechanisms. I don't know how often these more complicated situations arise in practice. The point is, Eiffel does have these mechanisms defined and they are expected to be available, and possibly required just to build mundane applications that use the standard library. Regards, -- Gregor "attriel" <[EMAIL PROTECTED]> 01/10/2003 10:37 AM Please respond to attriel To: <[EMAIL PROTECTED]> cc: Subject:Re: Objects, finally (try 1) > On Thu, 9 Jan 2003 16:40:20 -0500, Dan Sugalski wrote: >> #10 We do MI, but we don't instantiate a class' attributes multiple >> times if its in the hierarchy for a class more than once. If it is, >> the leftmost instance is real, the rest are virtual My only question here is: What is leftmost? Is that the same as "closest to the actual class we're looking at" or is it "first time it appears in the inheritance structure, and thus the furthest from the relevant class" ? (or something else entirely?) > This will mean we can't support Eiffel, which allows repeated real > inheritance of the same class. It does this by allowing renaming at the > feature level (thats attributes and methods in perl) when inheritance is > declared. Repeated inherited features are shared if they keep the same > name (and they really are the same feature), or split if they don't. I'll admit to never having gotten to looking at eiffel, just hearing about it from some other folks ... But what is the point of explicitly inheriting from the same class multiple times? I mean, sure, if it's in the inheritance tree multiple times, fine, but then you ignore most of them generally; what benefit/use comes from having it actually be in the tree multiple times as distinct entities? I'm just wondering there ... But if it's renaming the structure anyway, wouldn't it still be possible with the single-MI structure that dan proposed? as in, if B inherits from A and then C inherits from A and B directly (and assuming there's a need to separately retain the individual inheritance directions), wouldn't the compiler then say that B inherits from A and C inherits from A2 and B, to retain them both in the parrot? --attriel (I could, of course, be horribly wrong, had I stated a firm opinion rather than requests for more information :)
Re: Objects, finally (try 1)
On Friday, January 10, 2003, at 11:49 AM, Dan Sugalski wrote: At 1:37 PM + 1/10/03, Peter Haworth wrote: This will mean we can't support Eiffel Nope. :) What it means is that the proposed base object system won't work for eiffel. Actually, if you really want Eiffel to compile to Parrot, it might be interesting to work on getting ANSI C to compile to Parrot first, since most Eiffel compilers use compilation to C as an intermediate step. You might lose the ability to reuse an Eiffel-created object with other languages, but if you're using Eiffel, you're probably not going to be happy with object-orientation in any language that doesn't strictly enforce DBC anyway. ;-)
Re: Objects, finally (try 1)
Dan Sugalski wrote: > and who's got > questions on how this works? (I can put together examples, but this > is pretty long as it is, and I think it's reasonably > self-explanatory. Besides, assembly language isn't generally the best > way to demonstrate anything... :) Well, as far as I'm concerned, an assembly snippet would be nice. But I can as well wait for implementation and study what will be relevant to objects in the t/ directory. Indeed, once you wrote some Parrot assembly code to support a^Htwo stupid^Wesoteric languages, Parrot assembly is quite a nice and easy way to see how theory behaves in real life... :o) Jerome -- [EMAIL PROTECTED]
Re: Objects, finally (try 1)
At 10:37 AM -0500 1/10/03, attriel wrote: > On Thu, 9 Jan 2003 16:40:20 -0500, Dan Sugalski wrote: #10 We do MI, but we don't instantiate a class' attributes multiple times if its in the hierarchy for a class more than once. If it is, the leftmost instance is real, the rest are virtual My only question here is: What is leftmost? Is that the same as "closest to the actual class we're looking at" or is it "first time it appears in the inheritance structure, and thus the furthest from the relevant class" ? (or something else entirely?) For attributes it doesn't matter. For methods, well, I'm not sure whether a leftmost depth-first insertion is right or inserting it somewhere else is better. I expect Damian Has The Answer. (Or, if I remember from the last time I asked, several answers of which there wasn't a clear Best Answer) > This will mean we can't support Eiffel, which allows repeated real inheritance of the same class. It does this by allowing renaming at the feature level (thats attributes and methods in perl) when inheritance is declared. Repeated inherited features are shared if they keep the same name (and they really are the same feature), or split if they don't. I'll admit to never having gotten to looking at eiffel, just hearing about it from some other folks ... But what is the point of explicitly inheriting from the same class multiple times? I mean, sure, if it's in the inheritance tree multiple times, fine, but then you ignore most of them generally; what benefit/use comes from having it actually be in the tree multiple times as distinct entities? If you do redispatching of method calls it makes sense, since if there are enough redispatches you may end up redispatching to one class' method more than once because it's in the tree more than once, in which case you'd want to get the correct set of attributes, as each instance of the class in the tree should have a separate set of attributes in that case. (I could, of course, be horribly wrong, had I stated a firm opinion rather than requests for more information :) Ah, go for the bold statement. People are more likely to refute an error that way. :) Also, as I pointed out a little while ago, this is the proposal for the base perl6/ruby/python object scheme, but there's nothing that forbids transparent interoperability with a different object scheme. -- Dan --"it's like this"--- Dan Sugalski even samurai [EMAIL PROTECTED] have teddy bears and even teddy bears get drunk
Re: Objects, finally (try 1)
At 1:37 PM + 1/10/03, Peter Haworth wrote: On Thu, 9 Jan 2003 16:40:20 -0500, Dan Sugalski wrote: #10 We do MI, but we don't instantiate a class' attributes multiple times if its in the hierarchy for a class more than once. If it is, the leftmost instance is real, the rest are virtual This will mean we can't support Eiffel Nope. :) What it means is that the proposed base object system won't work for eiffel. There are very few proposed core changes to support this object system, and if you think about it the expressed program-level semantics are sufficient for eiffel (I think), it's just the behind-the-curtain bits that aren't. And there's nothing to say that a theoretical eiffel implementation couldn't just have a different Attr-style object. (Eiffel's classes, IIRC, are compile-time fixed so it can do the necessary code cloning and renaming magic to make it all work. I suppose we could too, but it's a lot more work to do it since things can change at runtime in perl/python/ruby classes) -- Dan --"it's like this"--- Dan Sugalski even samurai [EMAIL PROTECTED] have teddy bears and even teddy bears get drunk
Re: Objects, finally (try 1)
> On Thu, 9 Jan 2003 16:40:20 -0500, Dan Sugalski wrote: >> #10 We do MI, but we don't instantiate a class' attributes multiple >> times if its in the hierarchy for a class more than once. If it is, >> the leftmost instance is real, the rest are virtual My only question here is: What is leftmost? Is that the same as "closest to the actual class we're looking at" or is it "first time it appears in the inheritance structure, and thus the furthest from the relevant class" ? (or something else entirely?) > This will mean we can't support Eiffel, which allows repeated real > inheritance of the same class. It does this by allowing renaming at the > feature level (thats attributes and methods in perl) when inheritance is > declared. Repeated inherited features are shared if they keep the same > name (and they really are the same feature), or split if they don't. I'll admit to never having gotten to looking at eiffel, just hearing about it from some other folks ... But what is the point of explicitly inheriting from the same class multiple times? I mean, sure, if it's in the inheritance tree multiple times, fine, but then you ignore most of them generally; what benefit/use comes from having it actually be in the tree multiple times as distinct entities? I'm just wondering there ... But if it's renaming the structure anyway, wouldn't it still be possible with the single-MI structure that dan proposed? as in, if B inherits from A and then C inherits from A and B directly (and assuming there's a need to separately retain the individual inheritance directions), wouldn't the compiler then say that B inherits from A and C inherits from A2 and B, to retain them both in the parrot? --attriel (I could, of course, be horribly wrong, had I stated a firm opinion rather than requests for more information :)
Re: Objects, finally (try 1)
On Thu, 9 Jan 2003 16:40:20 -0500, Dan Sugalski wrote: > #10 We do MI, but we don't instantiate a class' attributes multiple > times if its in the hierarchy for a class more than once. If it is, the > leftmost instance is real, the rest are virtual This will mean we can't support Eiffel, which allows repeated real inheritance of the same class. It does this by allowing renaming at the feature level (thats attributes and methods in perl) when inheritance is declared. Repeated inherited features are shared if they keep the same name (and they really are the same feature), or split if they don't. -- Peter Haworth [EMAIL PROTECTED] Warning! Your Operating System is out of date! It can be replaced by a more memory abusive Operating System. Please contact your System Vendor for details.