re: Does edu-sig extend to Jython
Dethe writes -
Don't be too quick to take this off-list.
I'm game.
While your situation is pretty specific, the general case of "why doesn't Python support feature X of language Y" seems to be appropriate here. There are several possible answers, all valuable in an educational context:
1) It does support X, but the python idiom looks like X() .2) X isn't needed because of python feature Z 3) Python doesn't support X because X is a bad idea for such and such a reason 4) Python doesn't support X, but you can do Z to simulate it
I would think as to method overloading we are in the realm of 4).
In your case, if both Line and Point have methods getHalfIntersection(), could you then have:
def intersection(first, second): return first.getHalfIntersection() * second.getHalfIntersection()
I get the gist of your suggestion, but the issue is pervasive and might overly tax my ingenuity. My current thinking is this: I need some testing of the arguments and some decent error reporting for inappropriate arguments, in any case. Right now you send a Line where the class needs a Plane, and somewhere down the pike you'll probably get a message about object x not having an attribute "normal" let's say -which Planes's have and Line's don't. For me, as a user, I pretty now where to go. For someone else, as a user, it would be a mystery. (Again, I am assuming this is a necessary byproduct of dynamic typing. I believe that Java would give an error message on construction that would be specific enough to allow me to forego some of this. OTOH, I went through the process far enough to understand some of what the dynamic typing of Python is *giving* me and *saving* me versus Java's typing methodology to know not to resent - more than just a little - what it might be costing me. I could elaborate with specifics, but won't) And in doing some real error catching and reporting on arguments, I would expect isinstance will come into play, and in doing it, it should not be very much additional burden to do it in such a way so that at least I can make argument order irrelevant. After that I guess I need to see where I am, and then take the more complex issues of this kind on a case by case basis - there probably is no one-size answer for all cases. Art
[Arthur]
I get the gist of your suggestion, but the issue is pervasive and might overly tax my ingenuity.
My current thinking is this:
I need some testing of the arguments and some decent error reporting for inappropriate arguments, in any case. Right now you send a Line where the class needs a Plane, and somewhere down the pike you'll probably get a message about object x not having an attribute "normal" let's say -which Planes's have and Line's don't. For me, as a user, I pretty now where to go. For someone else, as a user, it would be a mystery.
[snip]
And in doing some real error catching and reporting on arguments, I would expect isinstance will come into play, and in doing it, it should not be very much additional burden to do it in such a way so that at least I can make argument order irrelevant.
Here is a less contrived example of a similar situation. I'm working on a module used to generate proper xhtml documents in Python. To do this, I'm applying a certain level of type checking for each level of a typical html document hierarchy. For example, here is part of the Html class, which corresponds to the html element, which can only contain one head and one body element: class Html(Element, AttrstringMixin): """HTML class.""" name = 'html' format = '<html%(attributes)s>\n%(head)s%(body)s</html>\n' def __init__(self, head=None, body=None, lang='en', xmllang='en', xmlns='http://www.w3.org/1999/xhtml', dir=None): if head is None: # Create a default head instance. self.head = Head() elif not isinstance(head, (str, Head)): raise TypeError, \ 'head must be a string, a Head instance, or None' else: self.head = head if body is None: # Create a default body instance. self.body = Body() elif not isinstance(body, (str, Body)): raise TypeError, \ 'body must be a string, a Body instance, or None' else: self.body = body self.attrs = { 'lang': lang, # Language. 'xml:lang': xmllang, # XML language. 'xmlns': xmlns, # XML namespace. 'dir': dir, # Direction. } Elsewhere I've got a Head class and a Body class defined. As you can see, I'm using isinstance() to guarantee that the proper type of objects are used by the Head instance. (Of course, I've intentionally left a big back door wide open by allowing a string as a valid parameter.) Anyway, I hope this helps illustrate one way of making Python stricter than usual. This module is a prototype and I'm playing around with various ideas so don't necessarily look at this as a suggestion for THE way to solve the problem, just one way that does work and isn't too hard to code. -- Patrick K. O'Brien Orbtech ----------------------------------------------- "Your source for Python programming expertise." ----------------------------------------------- Web: http://www.orbtech.com/web/pobrien/ Blog: http://www.orbtech.com/blog/pobrien/ Wiki: http://www.orbtech.com/wiki/PatrickOBrien -----------------------------------------------
4) Python doesn't support X, but you can do Z to simulate it I would think as to method overloading we are in the realm of 4).
Yes and no. Python doesn't have method overloading, but Java doesn't have keyword parameters. In my mind keyword parameters are more flexible, versatile, and powerful. There is also a general OO pattern of separating what changes from what stays the same and putting what changes into its own class. This is what I was trying to demonstrate with my Line and Point example. Often, a huge switch() statement Java is a symptom of needing to give each class a method which does the right thing, replacing the switch with polymorphic behaviour. Your example doesn't require switch, but the same pattern may apply. Another pattern is demultiplexing. In this you would determine the types of parameters and call a more specific routine: def intersection(first, second): if first instanceof Line: lineIntersection(first, second) else: pointIntersection(first, second) def lineIntersection(first, second): if second instanceof Line: lineLineIntersection(first, second) else: linePointIntersection(first, second) def lineLineIntersection(first, second): # now we know the types, do something with them. etc... This is slightly more verbose than Java overloading, and requires additiaonl function/method call overhead, but keeps the intent relatively clear. The biggest problem is one which you will also have with method overloading: Combinatorial Explosion. Say we have two java classes, which I'll simulate with the following pseudocode: class Point: def Intersection(Line, Line) def Intersection(Point, Line) def Intersection(Point, Point) def Intersection(Line, Point) class Line: pass OK, now you add class Plane and you want to calculate intersections. Then you add NonEuclideanPlane. And LineSegment. Relying on method overloading will soon result in hundreds of method definitions, when all you want is a fairly simple method comparing two *things*. If each *thing* can present itself in a thing-neutral way, you only need one method with no overloading, no demultiplexing, and no named variables. Of course, that's not always possible. Sometimes you know you won't ever need more than these two things, or all of the new classes will be subclasses of the first two, or whatever. But these are two strategies which can be used or mutated for quite a lot of situations.
I get the gist of your suggestion, but the issue is pervasive and might overly tax my ingenuity.
My current thinking is this:
I need some testing of the arguments and some decent error reporting for inappropriate arguments, in any case. Right now you send a Line where the class needs a Plane, and somewhere down the pike you'll probably get a message about object x not having an attribute "normal" let's say -which Planes's have and Line's don't. For me, as a user, I pretty now where to go. For someone else, as a user, it would be a mystery.
If you want early failure, in an appropriate way, assert() is the way to go.
(Again, I am assuming this is a necessary byproduct of dynamic typing. I believe that Java would give an error message on construction that would be specific enough to allow me to forego some of this. OTOH, I went through the process far enough to understand some of what the dynamic typing of Python is *giving* me and *saving* me versus Java's typing methodology to know not to resent - more than just a little - what it might be costing me. I could elaborate with specifics, but won't)
What Java is giving is that it takes positional arguments and demultiplexes for you based on type (and only on type). What python gives you is that you can demultiplex based on name. Since python can mix positional parameters and named parameters, and you can test type yourself easily enough, it seems more powerful to me.
And in doing some real error catching and reporting on arguments, I would expect isinstance will come into play, and in doing it, it should not be very much additional burden to do it in such a way so that at least I can make argument order irrelevant.
That seems like a reasonable expectation.
After that I guess I need to see where I am, and then take the more complex issues of this kind on a case by case basis - there probably is no one-size answer for all cases.
There is, but it doesn't fit. --Dethe
I think the usual thing with method overloading in Java is to accommodate different numbers of arguments of various types, e.g. (int int int) verus (int int) or (int int) versus (float int) -- all with the same method name (the compiler tells them apart by the type signature of the parameters, same as in C++). What I *don't* think any standard Java API is designed to accommodate is simple parameter switching, i.e. to catch (int a, int b) verus (int b, int a). Nor even (int a, float b) versus (float b, int a). It *is* possible to code for these multiple variations and permutations, but it's entirely customary to burden the class user with the job of at least getting the *order* of the parameters right. The multiplicity of methods has to do with differences that are *not* at the level of parameter ordering alone. Someone please correct me if I'm wrong about this. Kirby
[Kirby Urner]
I think the usual thing with method overloading in Java is to accommodate different numbers of arguments of various types, e.g. (int int int) verus (int int) or (int int) versus (float int) -- all with the same method name (the compiler tells them apart by the type signature of the parameters, same as in C++).
What I *don't* think any standard Java API is designed to accommodate is simple parameter switching, i.e. to catch (int a, int b) verus (int b, int a). Nor even (int a, float b) versus (float b, int a).
It *is* possible to code for these multiple variations and permutations, but it's entirely customary to burden the class user with the job of at least getting the *order* of the parameters right. The multiplicity of methods has to do with differences that are *not* at the level of parameter ordering alone.
Someone please correct me if I'm wrong about this.
I'm not a Java guy, but your interpretation matches my experience with other languages that support method overloading. Of course, I think this is in large part due to the fact that it is relatively rare that the order of parameters is insignificant, or can be made insignificant through type checking or method overloading. -- Patrick K. O'Brien Orbtech ----------------------------------------------- "Your source for Python programming expertise." ----------------------------------------------- Web: http://www.orbtech.com/web/pobrien/ Blog: http://www.orbtech.com/blog/pobrien/ Wiki: http://www.orbtech.com/wiki/PatrickOBrien -----------------------------------------------
I'm not a Java guy, but your interpretation matches my experience with other languages that support method overloading. Of course, I think this is in large part due to the fact that it is relatively rare that the order of parameters is insignificant, or can be made insignificant through type checking or method overloading.
It's a bit of a circle: the parameter order is rarely insignificant because the methods aren't overloaded to accommodate all permutations. If they were, order wouldn't matter. If you have just 3 parameters, that's six permutations right there. Four parameters means 4!=24 possible function signatures. No Java programmer want's to provide 24 ways of calling the exact same function with the exact same parameters -- just in different order. That would seem insane. Kirby
participants (4)
-
Arthur -
Dethe Elza -
Kirby Urner -
Patrick K. O'Brien