BUDDENBERGRA@USC-ISI.ARPA (Rex Buddenberg) (02/25/86)
Since overloading is deemed evil (which may indeed be true), why not remove the discussion from the realm of language definition entirely. Wirth did this in M2 for I/O by exiling the subject to auxiliary modules. Maybe we should do the same with all the operators, not just the ones we wish to overload... -------
nagler%orb@SUN.ARPA (Rob Nagler) (02/25/86)
Infix arithmetic is an attempt to simulate mathematics (which we all know computers don't do very well). One could argue that the infix operators should extend to arrays, but APL certainly has its readability problems. I like lisp, but M2 isn't Lisp. There isn't much rational for keeping infix operators except for history and pseudo-upward compatibility. Overloading. Here is my main argument against overloading: Text_IO.Put( s ); is legal (if "s" is an array of char) and so is Text_IO.Put( s[0] ); This is a particularly simple example, but you get the drift. To me this eliminates the main feature of structured languages: type checking (or assertion verification, if you like). If you don't care about losing type checking, then I suggest you program in something like Smalltalk or Lisp. Why do you think Wirth put BYTE (formerly, WORD) in the module SYSTEM? It is a major loophole (which is how you can get your overloading of prefix operators by the way). Rob
ark@ut-sally.UUCP (Arthur M. Keller) (02/27/86)
I beg to differ with my esteemed colleague, Mr. Rob Nagler, about the interaction between overloading (and generics, for that matter) and strong type checking. My comments here apply to the issues in general without reference to the particular language. Without overloading and generics, strong type checking is much easier as there is no possible ambiguity. With overloading, the correct procedure is used by a resolution process that uses strong type checking. (I don't believe overloading can be resolved at compile time without strong type checking.) With overloading, controlled generic capability can be achieved. Why would anyone want that? Well, would you want to have to distinguish between + for integer and + for reals? Would you want to have to invent unique names for each procedure that did an equivalent thing to its data type? I see nothing wrong with Mr. Nagler's example. In fact, I like it because I wouldn't want to have to remember to use (say) PUT-ARRAY instead of PUT. Note that even with overloading, all the parameters have to be compatible with exactly one procedure spec. In the + example above, that could mean precluding adding an integer to a real, if so desired. In my point of view, the main benefit of strong type checking is compile-time versus run-time checking. Since overloading is resolved completely at compile-time, I don't see how it is incompatible with strong type checking. Some generic capability (such as that in Ada) is equivalent to a compile-time expansion of the generic package as if it were a macro, and then using overloading to resolve it. This too is compatible with strong type checking, although the generic package usually cannot use any features not common to all potential types for the generic (i.e., a type for a generic must support all the operators and procedures needed by the generic package). A true generic would have the capability of deciding what to do based on the type. If done at run-time, this is clearly not compatible with strong type checking. If done at compile-time, you can use compile-time expansion as if the generic package were a macro with macro conditionals. In some sense, overloading without generics can be thought of as a limited collection of macro expansions of the generic that used macro conditionals. --- Sometime, when I'm in a flaming mood, maybe I'll talk about sinister functions (i.e., functions that go on the left) and their relationship to the generalization of array indexing as locating an item in a structure. (That is, why shouldn't retrieval and storage into any structure have the syntactic nicety of arrays; and how can I replace an array with a complex data structure (i.e., if the array is sparse) without having to modify the code using the array.) I doubt if this is the right audience. Constructive comments on where to send this, as well as expressions of interest in discussing this, are welcome. Arthur -- ------------------------------------------------------------------------------ Arpanet: ARK@SALLY.UTEXAS.EDU UUCP: {gatech,harvard,ihnp4,pyramid,siesmo}!ut-sally!ark
nagler@ORB.UUCP (Rob Nagler) (02/28/86)
Hi Arthur. How's the weather in TX? Back to the discussion... I guess what I should have said is that strong type checking is subverted by the introduction of overloading. I kind like the idea of using the name of my procedure as acheck unto itself. When you combine generics and overloading you lose the extra compile time type checking that you get with unique names for every procedure. I realize that you can strongly type check anything, but my main use for type checking is to catch errors at compile time before integration. Rob
wyant@APOLLO.UUCP (Geoffrey Wyant) (03/03/86)
I would like to reply to Mr. Keller's comments on overloading: I'm going to agree w/ Rob Nagler on this one, even though I think his example was poorly chosen. ........... > With overloading, controlled generic capability can be achieved. > Why would anyone want that? Well, would you want to have to distinguish > between + for integer and + for reals? Would you want to have to > invent unique names for each procedure that did an equivalent thing > to its data type? This is just the problem with overloading. It provides a superficial veneer of polymorphism over what are essentially different procedures. If 2 procedures do the same thing and only differ in the data types they take, why should I have 2 invent 2 different procedures ? True polymorphism would allow you to write only a single procedure. If the 2 operations differ subtley (or even not so subtley) in their semantics, I would claim that it is poor software engineering to allow them to be named the same thing. > I see nothing wrong with Mr. Nagler's example. In fact, I like it > because I wouldn't want to have to remember to use (say) PUT-ARRAY > instead of PUT. Again this instance, the PUT procedure shouldn't be overloaded, but should be able to accept parameters of any type, provided said parameter provides a "write" operation. > If done at compile-time, you can use compile-time expansion as if the > generic package were a macro with macro conditionals. In some sense, > overloading without generics can be thought of as a limited collection > of macro expansions of the generic that used macro conditionals. Macro expansion of types is the wrong way to think about type parameters. It fails to allow for recursive types among other things. Well, not that any of this has anything to do with Modula-2, and I'm not proposing that M2 should be made polymorphic. I just believe that overloading is a knee-jerk approach to polymorhism, and the semantic underpinnings fail to generalize in any sort of usefull fashion. ---------------------------- Geoff Wyant -------