Mantis Bug Tracker

View Issue Details Jump to Notes ] Issue History ] Print ]
IDProjectCategoryView StatusDate SubmittedLast Update
0005303OCaml~DO NOT USE (was: OCaml general)public2011-06-28 12:482013-08-31 12:44
Assigned To 
StatusclosedResolutionwon't fix 
PlatformOSOS Version
Product Version 
Target VersionFixed in Version 
Summary0005303: function overloading
DescriptionIt would be VERY useful for developers to have function overloading.
I know this has some big pressure for compiler - type inference could be confused with overloading, but... what if we force the user to specify function parameter types to let compiler infer types correctly ?
for example there could be OVERLOAD keyword:

let (overload +) (x:int) (y:int) = x+y
let (overload +) (x:float) (y:float) = x+.y

In this case compiler could generate two separate functions
and inline that function which is appropriate by it's parameter types...

TagsNo tags attached.
Attached Files

- Relationships

-  Notes
doligez (administrator)
2011-12-29 23:44

Thanks for the suggestion, but overloading is a bit more complex than it seems.

To begin with, what happens when I write:

  let (overload +) (x:int) (y:int) = x+y
  let (overload +) (x:float) (y:float) = x+.y
  let f x y z = x + y + z
pilki (reporter)
2011-12-30 14:26

@0x69 : basically, what Damien Doligez is saying is that the problem of type inference and overloading is not at the definition of the overloaded function, but where you use it. The type annotation you want to add at the definition of the function are useless: the compiler can find them easily:

# let ((*overloaded*)+) x y = x + y;;
val ( + ) : int -> int -> int = <fun>
# let ((*overloaded*)+) x y = x +. y;;
val ( + ) : float -> float -> float = <fun>

The problem is to find which function to use when you call "+".

It is worth noting that some feature of the recent releases of OCaml remove some of the burden:

module Float = struct
  let (+) x y = x +. y
  let (-) x y = x -. y
  let ( * ) x y = x *. y
  let ( / ) x y = x /. y

module Int = struct
  let (+) x y = x + y
  let (-) x y = x - y
  let ( * ) x y = x * y
  let ( / ) x y = x / y

let foo x y = Float.(x + y * 3.)

let bar x y =
  let open Float in
  42.3 * y + x
val foo : float -> float -> float = <fun>
val bar : float -> float -> float = <fun>

What you may want to do is to add a feature request for a unified interface of numerical operations and the corresponding modules for float, int, int32, int64 and bignums. You could even probably provide the patch for it ;)

meyer (developer)
2011-12-30 16:47


For this I raised: [^]

0x69 (reporter)
2011-12-30 18:55

>>To begin with, what happens when I write:
>>let (overload +) (x:int) (y:int) = x+y
>>let (overload +) (x:float) (y:float) = x+.y
>>let f x y z = x + y + z

If compiler can't deduce what overloaded version of operator to use - it can through an error forcing user to write type annotations:

let f (x:float) (y:float) (z:float) = x + y + z

I think type annotation is good idea. Somethimes it also helps increase code readability. But of course as @pilki showed new module system for types-

"let foo x y = Float.(x + y * 3.)"

is also a good solution ...

(But still i would prefer type specialization over operator specialization, maybe because i came from F# world :-). But others preferences can be different of course...)
meyer (developer)
2011-12-30 19:20

The reason why F# needs to support overloading because of it tight integration with .NET where the overloading is ubiqious.

Overloading with type inference is best accomplished with type classes - like in Haskell world (it's worth to note that Coq has also typeclasses!) - where you define a common interface (type class) and then the instance of it for each abstract data type that implements it. Therefore, Haskell type system is able to infer (with some extra type annotations) that the type belongs to this type class and apply the right function from the instance.

However ad-hoc polymorphism comes with the cost of extra annotations, and is quite ortogonal to how the ML style (parametric polymorphism) module system works.

As you noted as Haskell needs some boilerplate and annotations where the typeclasses are defined, in contrast to ML, where you need these special "annotations" where you *use* the functions or operators.
protz (manager)
2011-12-31 00:05

Just for the record, I think this is precisely what gcaml [^] tries to achieve.
Christophe Troestler (reporter)
2012-01-02 20:03

For the record: [^]

- Issue History
Date Modified Username Field Change
2011-06-28 12:48 0x69 New Issue
2011-12-29 23:44 doligez Note Added: 0006559
2011-12-30 14:26 pilki Note Added: 0006561
2011-12-30 16:47 meyer Note Added: 0006565
2011-12-30 18:55 0x69 Note Added: 0006569
2011-12-30 19:20 meyer Note Added: 0006570
2011-12-31 00:05 protz Note Added: 0006575
2012-01-02 20:03 Christophe Troestler Note Added: 0006578
2012-01-17 16:44 xleroy Status new => resolved
2012-01-17 16:44 xleroy Resolution open => won't fix
2013-08-31 12:44 xleroy Status resolved => closed
2017-02-23 16:36 doligez Category OCaml general => -OCaml general
2017-03-03 17:55 doligez Category -OCaml general => -(deprecated) general
2017-03-03 18:01 doligez Category -(deprecated) general => ~deprecated (was: OCaml general)
2017-03-06 17:04 doligez Category ~deprecated (was: OCaml general) => ~DO NOT USE (was: OCaml general)

Copyright © 2000 - 2011 MantisBT Group
Powered by Mantis Bugtracker