user-defined operators

Richard A. O'Keefe ok@REDACTED
Mon Mar 29 05:30:11 CEST 2004


I wrote:
	> First, the thread is about user-defined operators, NOT about
	> operator overloading.  

"Martin J. Logan" <mlogan@REDACTED> wrote:
	They are part in parcel. ad-hoc polymorphism, overloading, user defined
	operators are all the same in this context.

user-defined operators are *completely orthogonal* to overloading.

	If the language supports polymorphic functions then it is
	reasonable to assume that the addition of operators based on
	those very functions would support the same polymorphic
	attributes.
	
This makes user-defined operators IN NO WAY DIFFERENT from other
user-defined function names.

	> Second, most functional languages have supported user defined
	> operators for years.  ML has them.  Haskell has them.  Clean
	> has them.  Prolog has them.  Mercury has them. 
	
	Many of these also include operator overloading(Haskell).

No.  Haskell does *not* include operator overloading.  At any point in
a Haskell program, there is AT MOST ONE definition in scope for any
function name or operator name.  Haskell operators are IN NO WAY DIFFERENT
from other Haskell function names.  Haskell does have a system of
"type classes" where you write e.g.,

    class Fee x where
        goo :: x -> Int
        goo _ = 42

and you can override the definition, BUT NOT THE SIGNATURE, in a subclass:

    class Fee x => Fie x where
        goo _ = 137

However, you are NOT allowed to also have

    class Foe x where
        goo :: x -> String
        goo _ = "zero"

So in Haskell every operator name and every function name has a unique
definition point where its signature is either explicit or inferred from
a definition, and that signature applies consistently with no ad hoc
overloading.

I know that the Haskell report uses the word "overloading", but it is
*not* the kind of ad-hoc overloading you find in Algol 68, C++, PL/I,
and Fortran, which is multiple unrelated definitions with different
signatures.

Note that my example (where goo x = 42 sometimes and goo x = 127 other
times, depending on the type of x) does NOT involve an operator, although
it could have.

Operator syntax and overloading are orthognoal concepts.

	> *DO* you in fact get a welter of confusing operators?
	> 
	> NO. 
	
	What about this?
	
	It does not seem to me that
	>     n `sm` primes
	>     seconds `d` 60
	>     fromInteger big `aTf` x
	>     expr `catch` handler
	> are particularly hard to read.
	
	Which I agree is no worse than 
	
	sm(n, primes)
	d(seconds, 60)
	
Exactly so:  adding backquotes doesn't make the names any worse.

	How about this? 
	
	    N `@#` Primes
	    Seconds `@#` 60
	    MoreSeconds `@#` (Seconds `@#` String `@#` String2)
	
As I have said before, `@#` is NOT A LEGAL OPERATOR IN HASKELL.
Backquoted operator names *must* be ordinary function names; backquotes
in Haskell are NOT like ordinary quotes in Erlang, and there is no reason
why backquotes, should they ever be adopted, should be like ordinary
quotes in Erlang either.

	I want my `operator` to be defined as such. 
	
	'@#'(A, B) when is_integer(A), is_list(B) -> ...
	'@#'(A, B) when is_integer(A), is_integer(B) -> ...
	'@#'(A, B) when is_list(A), is_list(B) -> ...
	    
Your examples are bad because (a) '@#' is not mnemonic (but I have
recommended that such operators *not* be allowed in backquote form)
and (b) the single (not overloaded! the name is resolved to a unique
definition) definition of '@#' does strange things.  The use of
operator notation as such is quite irrelevant:

	'@#'(N, Primes)
	'@#'(Seconds, 60)
	'@#'(MoreSeconds,'@#'('@#'(Seconds,String),String))
	
are perfectly possible right now in Erlang.

	I am sure one could come up with some mangled syntax for restricting
	this.

Haskell syntax is not mangled, and it says quite plainly that the thing
between backquotes must be an ordinary function name.  I have an unfinished
preprocessor that gives Erlang a Haskell-like appearance.  It includes
backquotes, and nothing bad happens to the syntax rules.

You might well come back and say that

	
	    N `hic` Primes
	    Seconds `hic` 60
	    MoreSeconds `hic` (Seconds `hic` String `hic` String2))
	
	We could also conjure up a way to define precedence by user
	defined precedence number or some such.

Again, we don't have to conjure anything up.  It has been done before.
It works brilliantly in practice.  In the absence of any declaration
to the contrary, `foo` has weakest precedence and left associativity
in Haskell.  If memory serves me, ".FOO." has weakest precedence and
no associativity in Fortran.

	I am not trying to be polemic here but it honestly scares me.
	
You are scared by a boggart that is entirely of your own imagination.

The proposal under discussion is

    (1) <backquote> <identifier> <backquote>
	where <identifier> is an unquoted identifier or variable name
	should be an Erlang operator of weakest precedence
	and either left associativity or no associativity
    (2) E1 `f` E2 should be equivalent to f(E1, E2).

This introduces *no* new kind of overloading to Erlang.
It introduces *no* new kinds of unreadable spelling to Erlang.
In particular !! would have to be written `rpc`, not `!!`,
and `@#` would still not be an operator, although '@#' would still
be a function name.

I'm tired of scaremongering about how bad things *could* get, when
Haskell and Fortran experience shows that they *don't* get bad, and
when they *can't* get bad in some of the alleged ways.




More information about the erlang-questions mailing list