Re: [PROPOSAL] VTABLE_call_method
Sam Ruby [EMAIL PROTECTED] wrote: Ramblings on creating a new VTABLE_call_method slot to help with implementing Python's bound vs unbound methods: http://www.intertwingly.net/blog/2005/01/03/Bound-Methods 1) Methods are functions, where the first parameter is the object. We are currently passing the object (or the invocant) in current_object In subs denoted with method we have the magic self, which makes it available for user code. This doesn't match HLLs expectations and sematics. Proposal: P5 := object := invocant for method calls ex-P2 := current_invocant (now current_object aka self) So given: def index(self, substr) We have the common case of a method call and matching arguments: parrot.index(r) P5 ... parrot P6 ... r current_invocant ... parrot With an unbound method call: str.index(parrot, r) with this register setup prior to the call: P5 ... str P6 ... parrot P7 ... r current_invocant ... str we have to do: if (PObj_is_class_TEST(object)) shift_arguments(...); and we have again arguments matching. 2) WRT the proposed VTABLE_call_method() This just moves the burden of doing a method call down to all classes and doesn't really fix anything. 1) is not python-specific. Moving the code into language-specific PMCs hinders interoperbility and causes unneeded code duplication. - Sam Ruby leo
Re: [PROPOSAL] VTABLE_call_method
Leopold Toetsch wrote: Sam Ruby [EMAIL PROTECTED] wrote: Ramblings on creating a new VTABLE_call_method slot to help with implementing Python's bound vs unbound methods: http://www.intertwingly.net/blog/2005/01/03/Bound-Methods 1) Methods are functions, where the first parameter is the object. We are currently passing the object (or the invocant) in current_object In subs denoted with method we have the magic self, which makes it available for user code. This doesn't match HLLs expectations and sematics. Proposal: P5 := object := invocant for method calls ex-P2 := current_invocant (now current_object aka self) So given: def index(self, substr) We have the common case of a method call and matching arguments: parrot.index(r) P5 ... parrot P6 ... r current_invocant ... parrot With an unbound method call: str.index(parrot, r) with this register setup prior to the call: P5 ... str P6 ... parrot P7 ... r current_invocant ... str we have to do: if (PObj_is_class_TEST(object)) shift_arguments(...); and we have again arguments matching. How should the following be handled: f = parrot.index ... print f(r) 2) WRT the proposed VTABLE_call_method() This just moves the burden of doing a method call down to all classes and doesn't really fix anything. 1) is not python-specific. Moving the code into language-specific PMCs hinders interoperbility and causes unneeded code duplication. I've learned to expect such a predictable response. The exact same number of lines of code, and the exact same external behavior somehow magically hinders interoperability and causes unneeded code duplication. Whatever. - Sam Ruby
Re: [PROPOSAL] VTABLE_call_method
Sam Ruby [EMAIL PROTECTED] wrote: Leopold Toetsch wrote: How should the following be handled: f = parrot.index The CPython code is: 1 0 LOAD_CONST 0 ('parrot') 3 LOAD_ATTR0 (index) 6 STORE_NAME 1 (f) The interesting thing is hidden in LOAD_ATTR. It seems that it creates a call stub for the given (object, method) pair. ... print f(r) That looks like and is a plain function call (BTW it's not covered by your call_method proposal). The f object (the method call stub) has to shift up call arguments and place the object as the first argument. 2) WRT the proposed VTABLE_call_method() This just moves the burden of doing a method call down to all classes and doesn't really fix anything. 1) is not python-specific. Moving the code into language-specific PMCs hinders interoperbility and causes unneeded code duplication. I've learned to expect such a predictable response. The exact same number of lines of code, and the exact same external behavior somehow magically hinders interoperability and causes unneeded code duplication. What is unclear about: This just moves the burden of doing a method call down to all classes and doesn't really fix anything.? Whatever. Again: the problem is *not* python-specific. - Sam Ruby leo
Re: [PROPOSAL] VTABLE_call_method
Leopold Toetsch [EMAIL PROTECTED] wrote: Sam Ruby [EMAIL PROTECTED] wrote: How should the following be handled: f = parrot.index The CPython code is: 1 0 LOAD_CONST 0 ('parrot') 3 LOAD_ATTR0 (index) 6 STORE_NAME 1 (f) The interesting thing is hidden in LOAD_ATTR. It seems that it creates a call stub for the given (object, method) pair. Thinking a bit further about that: we have one part of the method call, i.e. the method lookup thingy: str = new String str = parrot meth = find_method str, index # [1] Now we'd have to associate the invocable PMC with the object, e.g. assign meth, str # set an object slot inside the invocable or maybe more explicit with a distinct PMC class: func = new MethStub, meth# create a new PMC for invocable meth assign func, object # associate object with it Calling this PMC then has to shift up arguments by one and place the remembered object as current_invocant and P5. [1] The find_method is probaly just getattribute or whatever the HLL compiler emits. Comments? leo
Re: [PROPOSAL] VTABLE_call_method
Leopold Toetsch wrote: Sam Ruby [EMAIL PROTECTED] wrote: Leopold Toetsch wrote: How should the following be handled: f = parrot.index The CPython code is: 1 0 LOAD_CONST 0 ('parrot') 3 LOAD_ATTR0 (index) 6 STORE_NAME 1 (f) The interesting thing is hidden in LOAD_ATTR. It seems that it creates a call stub for the given (object, method) pair. ... print f(r) That looks like and is a plain function call (BTW it's not covered by your call_method proposal). The f object (the method call stub) has to shift up call arguments and place the object as the first argument. 2) WRT the proposed VTABLE_call_method() This just moves the burden of doing a method call down to all classes and doesn't really fix anything. 1) is not python-specific. Moving the code into language-specific PMCs hinders interoperbility and causes unneeded code duplication. I've learned to expect such a predictable response. The exact same number of lines of code, and the exact same external behavior somehow magically hinders interoperability and causes unneeded code duplication. What is unclear about: This just moves the burden of doing a method call down to all classes and doesn't really fix anything.? First you state The f object (the method call stub) has to shift up call arguments and place the object as the first argument. In other words, moving the burden of doing the marshalling of parameters down to the class really *does* fix something. Then you state that moving the burden in a similar case doesn't fix anything. Whatever. Again: the problem is *not* python-specific. Analogy: is classes/string.pmc Perl Specific? I anticipate each language will need a language specific string class. Hopefully each will inherit much of their functionallity from Parrot's string class once all the multiple inheritance and MMD issues are worked out. In a similar manner, I expect many languages will need a language specific class class. Again, hopefully each will inherit much of their functionallity from a Parrot class class. If you take a look at my recent commit, you will see that the way that bound methods are implemented in Python leverages the way that Python Properties are defined. This isn't merely an implementation choice - this is the way the language is defined, and t/pie/b0.t seems carefully crafted to ensure that the implementation faithfully implements this part of the Python language definition. I suspect that much of this is Python specific. That's why it is nice that VTABLE_get_attr_str is a VTABLE entry and not hardwired into Parrot_getattribute_p_p_sc. In a similar manner, I expect most languages to implement call_method to either simply inherit the default or to implement the same basic flow of find_method followed by invoke. What is in between those two calls, however, may vary based on language - for example, what exception is to be thrown if the method is not found may vary from language to language. However, I can't override this behavior if it remains hardcoded in the op. Moving the burden down to the classes *does* allow me to fix something - it enables me to throw the exception that Python developers will expect, and will allow me to avoid the creation of bound method objects in many cases. - Sam Ruby
Re: [PROPOSAL] VTABLE_call_method
Sam Ruby [EMAIL PROTECTED] wrote: Leopold Toetsch wrote: What is unclear about: This just moves the burden of doing a method call down to all classes and doesn't really fix anything.? First you state The f object (the method call stub) has to shift up call arguments and place the object as the first argument. Yes. See another message I've posted WRT that. In other words, moving the burden of doing the marshalling of parameters down to the class really *does* fix something. Er, no. Because whatever you do, your (anybodies) HLL compiler will just emit a plain function call in that case. Your proposed call_method vtable doesn't cover it all. So just pushing down the problem to *all* classes that implement function or method calls doesn't help. Parrot itself has to deal with it. Then you state that moving the burden in a similar case doesn't fix anything. Yes, because it is *not* python-specific. We've to approach a common solution for all supported languages. Whatever. Again: the problem is *not* python-specific. Analogy: is classes/string.pmc Perl Specific? People including me have submitted lot of patches to get Perl* out of core PMCs. So string.pmc should end up in a usable base for many string functions. I anticipate each language will need a language specific string class. Hopefully each will inherit much of their functionallity from Parrot's string class once all the multiple inheritance and MMD issues are worked out. Exactly that's the goal. Inheritance, code reuse, interoperbility. In a similar manner, I expect many languages will need a language specific class class. Again, hopefully each will inherit much of their functionallity from a Parrot class class. Well, the class PMC aka the metaclass of the class system is much more HLL specific. Not much can be inherited here. All that's not inheritable has to be done in vtable methods. ... That's why it is nice that VTABLE_get_attr_str is a VTABLE entry and not hardwired into Parrot_getattribute_p_p_sc. This nicety is coming from my desire for abstraction. I thought, it'll be needed. I've written committed these patches (against Dan's wishes...) In a similar manner, I expect most languages to implement call_method to either simply inherit the default or to implement the same basic flow of find_method followed by invoke. I'm fully in accordance with you up to here. But argument passing and method calls isn't currently in sync - Parrot is doing different things then HLLs are doing. Before this isn't fixed (and it needs fixing) I can't and won't go any further. *If* then something isn't working for Python or whatever language, we can look for a more generic way. And argument passing and method or function calls isn't really a python-only language feature. First Parrot needs to adhere to HLL semantics. ... What is in between those two calls, however, may vary based on language - for example, what exception is to be thrown if the method is not found may vary from language to language. These are minor problems. They have to be solved, as well as creating a HLL specific destination PMC in infix methods. First we've to fix the basics. However, I can't override this behavior if it remains hardcoded in the op. We can throw a language-sepcific exception. You can translate the exception type. There are many ways to address such problems. Later. - Sam Ruby leo
[PROPOSAL] VTABLE_call_method
Ramblings on creating a new VTABLE_call_method slot to help with implementing Python's bound vs unbound methods: http://www.intertwingly.net/blog/2005/01/03/Bound-Methods This is related to a previous discussion on Overloaded Operator Methods: http://xrl.us/ekh8 - Sam Ruby