[comp.lang.modula2] OPERATOR

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