user-defined operators

Martin J. Logan <>
Mon Mar 29 20:32:25 CEST 2004


The definition of operator overloading is: "Use of a single symbol to
represent operators with different argument types" i.e one operator is
overloaded to handle two strings or two integers irrespective of where
the operator is defined or how many times it is defined separately.

It follows that if you have polymorphic functions and you base your user
defined operators on those functions then you can do the same thing with
operators as you can with functions, namely overload then to handle
different "types" i.e perform a different operation with with two
strings vs two integers etc... It is understood that user defined
operators are orthogonal to operator overloading in strict sense. Again
though if you allow user defined operators to be based on polymorphic
functions then you ARE allowing overloaded operators. 

In my years of programming I have come to expect that one must read a
function before understanding what it does is many cases. I typically do
not research what the * operator does really thoroughly though. I simply
don't want to see `*` in code that concatenates strings or multiplies
two floats producing a rounded integer.  Erlang is readable and
effective, adding user defined operators does little to increase the
expressive power of the language and goes one step in decreasing its
simplicity. 

Many people like Joes !! operator because it is more in keeping with the
theme and syntax of erlang than a function call to do the same. They do
not advocate it just because it is an operator. If you want to restrict
!! to `rpc` then all you are really arguing for is to add a strangely
restrictive infix erlang function calling syntax. I can't figure out how
that benefits anyone. We are trained through the mathematics we took in
school to use non-alphanumeric symbols as operators and that is just
what we shall do when we get to make up our own. If I want to deal with
refactoring peoples code that looks like a bunch of cryptic symbols
between strings and numbers where the symbols do different things
depending, then ... well I don't want to deal with code like that so I
will put my vote in for only having to deal with cryptic functions from
time to time and for keeping things just the way they are.

Cheers,
Martin


On Sun, 2004-03-28 at 21:30, Richard A. O'Keefe wrote:
> I wrote:
> 	> First, the thread is about user-defined operators, NOT about
> 	> operator overloading.  
> 
> "Martin J. Logan" <> 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