X903@DMAFHT1.BITNET (Marc Wachowitz) (06/06/91)
On Wed, 5 Jun 91 08:21:25 CDT Mike Dorman said: > >Someone opined in a Dr. Dobbs Journal many years back, that one obvious >addition to Modula-2 (or any other language, for that matter) is a keyword >like OPERATOR, or something, which would let you define thingies which you >use to perform operations on variables, like **. > Add concepts (when necessary), not keywords :-) >The only problem I see is that it would either have to take into account >all possible variable types, or be variable-type-specific. It would be >quite nice to be able to write a + operator for concatenating strings, >and stuff like that. There are much more problems in this area: - If you allow arbitrary operators, the scanner must be changed at run time, e.g. to recognize "**" after it has been defined. This would slow down lexical analysis and make the grammar context sensitive even on the lexical level *shudder*. - A second problem in this case would be how to define precedence. Fixed (and probably equal) precedence of user-defined operators would be counter-intuitive (imagine "**" with lower precedence than "+"). User-defined precedence (perhaps like Prolog's precedence numbers) would make nearly every common parsing technique unworkable; and it would cause problems when selveral unrelated modules are used by one client module. Parsing precedence grammars (whether precedence is dynamic or not) is terrible. If you restrict it to additional meanings for existing operators, what you are proposing is just overloading, which does also have several problems: - It forces you to use unqualified imports, which I consider just unacceptable in large projects. I want to see on each and every occurence of a name where it comes from, instead of referring to many tenth of lines of imports. Reminds me to the tons of include files for X11 programs in C :-( - Overloading resolution adds considerable complexity to the compiler, including nasty scope resolution problems. Of course none of the problems is unsolvable, but all "solutions" I've seen so far (and there are many) are unusable, difficult to understand or difficult to implement, usually all three. Therefore I'd argue not to have general overloading is better. I consider the "effort" typing something like "RealMath.Power(...") or "ComplexMath.Power(...)" etc. not too high a price for clarity. Of course, a powerful editor (like Emacs) reduces much of the typing overhead :-) Marc Wachowitz X903@DMAFHT1.BITNET
randy@PSG.COM (Randy Bush) (06/06/91)
In comp.lang.modula2 (aka INFO-MODULA2) you write: > There are much more problems in this area: > ... Thank you! A bit of rationality in the discussion. And why are you not on your national Modula-2 standards committee? We need you before it becomes Ada-2. randy
schoebel@bs3.informatik.uni-stuttgart.de (Thomas Schoebel) (06/07/91)
In article <INFO-M2%91060605014399@UCF1VM.BITNET> Modula2 List <INFO-M2%UCF1VM.BITNET@ucf1vm.cc.ucf.edu> writes: >On Wed, 5 Jun 91 08:21:25 CDT Mike Dorman said: >> >>Someone opined in a Dr. Dobbs Journal many years back, that one obvious >>addition to Modula-2 (or any other language, for that matter) is a keyword >>like OPERATOR, or something, which would let you define thingies which you >>use to perform operations on variables, like **. >> >Add concepts (when necessary), not keywords :-) Yes, but adding concepts without keywords, is this possible in general? I think the problem is more complicated: All you can do with Operators could be done also with functions. But the point is *how* you can do it. It is really "only" a syntactic problem, because semantics of operators can be simulated by functions. Algebraically, there is no really new concept. >>The only problem I see is that it would either have to take into account >>all possible variable types, or be variable-type-specific. It would be >>quite nice to be able to write a + operator for concatenating strings, >>and stuff like that. >There are much more problems in this area: >- If you allow arbitrary operators, the scanner must be changed at > run time, e.g. to recognize "**" after it has been defined. This > would slow down lexical analysis and make the grammar context > sensitive even on the lexical level *shudder*. If you look at the possible tokens in MODULA-2, there are a lot of symbols and combinations of them which are not leagal. You simply could legalize them for use as operators. Just define: All that is neither a keyword, an identifier, a literal constant or a special symbol like ".", ",", ";", parentheses etc. is an operator. More precisely, Operators consist of strings on a restricted alphabet, namely all characters not allowed in the other token classes. Then the scanner need not be changed at run time, but the semantic analysis has to check the validity of an operator. But this problem is in principle the same as for identifiers. >- A second problem in this case would be how to define precedence. > Fixed (and probably equal) precedence of user-defined operators > would be counter-intuitive (imagine "**" with lower precedence than > "+"). User-defined precedence (perhaps like Prolog's precedence > numbers) would make nearly every common parsing technique unworkable; > and it would cause problems when selveral unrelated modules are used > by one client module. > Parsing precedence grammars (whether precedence is dynamic or not) > is terrible. I think there is also a solution for this problem. At first, we should ensure that precedence of one particular operator symbol is always the same, regardless of the types of the operands. Next, there is a simple way to resolve operator precedence in common parsing techniques: Just construct the grammar using a production like Expr -> Expr Op Expr. Of course, this is highly ambiguous, but the resulting conflicts can be easily decided deterministically by the precedence relation, if no two operators have the same precedence. In case of same precedence, the associativity must be used additionally. You are right that it will produce additional overhead, but I think the problem is solvable in practice, for example by adding a precedence decider to standard LR or LL parsers. >If you restrict it to additional meanings for existing operators, >what you are proposing is just overloading, which does also have >several problems: >- It forces you to use unqualified imports, which I consider just > unacceptable in large projects. I want to see on each and every > occurence of a name where it comes from, instead of referring to > many tenth of lines of imports. Reminds me to the tons of include > files for X11 programs in C :-( What about that: x := y Module.** z :-) >- Overloading resolution adds considerable complexity to the compiler, > including nasty scope resolution problems. I cannot see the last problem; why not regard operators as (special) identifiers? The only difference is that you have two identifier classes: conventional identifiers and operator identifiers. Why not apply the same scope rules to them? >Of course none of the problems is unsolvable, but all "solutions" I've >seen so far (and there are many) are unusable, difficult to understand >or difficult to implement, usually all three. Therefore I'd argue not >to have general overloading is better. I have to agree that I never have seen a really *good* solution. Why not change the state of the art? (for better, of course! :-) --Thomas