On 2007.12.07., at 15:39, John Wilson wrote:
> > On Dec 7, 2007 2:22 PM, Jochen Theodorou <[EMAIL PROTECTED]> wrote: >> >> Attila Szegedi schrieb: >>> then the target types for argument conversion for all 2-arg >>> overloads >>> of foo will be computed to be [java.lang.String, >>> java.util.Collection]. When the method is dynamically invoked, the >>> passed callProtocol will be asked to provide a representation of the >>> first method as if it were a String, and to provide a representation >>> of the second method as if it were a Collection. Hopefully in the >>> real >>> invocation, the second argument will already be either a list or a >>> set, so it will be returned unchanged. If it is however a collection >>> that is neither a list nor a set, then no method will be invoked and >>> an error will be thrown. >> >> that is different from what we do in Groovy, because in Groovy we >> "convert" just before the call and there will be no error, because >> invalid choices are already removed.No I guess what you mean is >> getting >> the argument types... ehm.. no again... why should the arguments >> depend >> on the unified method parameter types? Why not add a method that >> checks >> if a parameter is assignable to an argument and let the language >> decide >> how it should behave here. Then you might still need a coercion step >> before the call, but here again I would let the language plug in. > > I think that you riase an important point. > > In dynamic languages which allow classes to convert themselves to > other types you have to take this ability into account when selecting > the appropriate method to dispatch. Indeed. What I do with my Beans MOP code is I ask each object passed to the method to be converted into the type of the associated formal argument of the Java method -- bear in mind the code I wrote deals with invoking methods on Java objects only. My approach for handling overloaded methods though is to first select an overload based on number of arguments (say it is invoked with 3 args), and then I ask the object passed as the i-th parameter to be converted to the most specific common superclass of all parameter classes in the i-th position in the parameter lists of all overloads that take 3 arguments. Also, I'm talking solely about the problem of selecting among overloaded Java methods invoked from a dynamic language here. Dynamic languages are better off without a concept of an overloaded method altogether, as they can mostly have a single method accepting any types of arguments anyway :-) > I have already explained that the Ng runtime asks each method object > for the cost of making the call given a set of parameters. The method > object does this by asking the MetaClass for each of the parameters > "how much would it cost you to convert yourself to this type?" Your approach indeed allows for some interesting additional automatic conversions, as when you're faced with the choice of whether to rather convert an argument to string or a boolean, you can apparently ask the object "please rate on a scale of 1 to 10 whether you'd like to be a string" and then "please rate on a scale of 1 to 10 whether you'd like to be a boolean", repeat that for all potential method signatures on all objects, summarize per method signature, and whichever method wins the objects' popular vote gets invoked. Of course, this presumes that the object can have meaningfully defined context-independent conversion preferences. I mean, if preferences would not be context- independent, and could change on a call by call basis, then you could as well just insert a narrowing conversion at the call site (like, use !!x in JavaScript to force conversion of x to boolean). Also note that you could have a different selection strategy instead of "one with lowest cost sum". You could also go with "one with highest number of individual minimal costs", and it'd be just as justified. So, yes, assigning weights/costs/preferences to various conversions is indeed an interesting concept. I'm a bit concerned about it though -- couldn't an object assigning very high costs to conversions it doesn't like rig the evaluation too much in its favour? That could lead to some counterintuitive results violating the principle of least surprise :-). Wouldn't it be safer for objects to have relative preferences for types, but without any preference being expressed as an absolute number? I.e. faced with prospect of converting an object to either type x, type y, or type z, you wouldn't ask it "how much does it cost to convert you to type x?", "how much does it cost to convert you to type y?", then "how much does it cost to convert you to type y?". Rather, you'd just ask it "we can convert you to either x, y, or z. Could you pick from these the conversions you actually support and then return them to us in your order of preference, please?" You could then try to select a method that satisfies some maximal preference criteria. Unfortunately, you can articulate _several_ maximal preference criterions (as I already indicated above), i.e. minimal sum of preference indexes, most first preferences selected, etc. So, if you decide to go down the route of weighted conversions, there are multiple selection strategies you can choose, and neither is more natural than any other. So I believe that it's OK to conservatively do automatic type conversions as long as the situation is 100% unambiguous, but as soon as the choice is not black and white, it's not a shame to bail out with an error and let the programmer narrow the types as necessary at the problematic call site, i.e. see above trick of using !! to force an expression to be boolean. > and > accumulating the costs (in fact we don't pass the actual parameters to > the method object we pass the MetaClasses for each of the actual > parameters - this way we support typed as well as untyped actual > parameters). This means that the method selection rules are not wired > into the runtime at all. What happens if two sets of parameters end up the same cost? > > > In general you can't just look at the type of a value and decide if it > can be converted to another type. Also, in a dynamic language, the > ability to convert from one type to another can appear or disappear at > will. Right - my MOP implementation will ask on each call the objects to convert themselves to a target type, and the system fully allows for their capability to do so to change. It's just that if the overloaded methods have wildly differing parameter types, the target type can end up being java.lang.Object basically saying "we can't meaningfully ask you to narrow down your type at this time, we'll run with whatever you are by nature". > In Ng it's quite conceivable that I can convert C to D in one > thread and not be able to do it at exactly the same time in another. > I'm not quite sure how groovy does coercion these days but I suspect > it's the same. > > John Wilson Attila. -- home: http://www.szegedi.org weblog: http://constc.blogspot.com --~--~---------~--~----~------------~-------~--~----~ You received this message because you are subscribed to the Google Groups "JVM Languages" group. To post to this group, send email to [email protected] To unsubscribe from this group, send email to [EMAIL PROTECTED] For more options, visit this group at http://groups.google.com/group/jvm-languages?hl=en -~----------~----~----~----~------~----~------~--~---
