Overloading in Ocaml - ocaml

I know that OCaml does not support overloading. Then, instead of overloading, what can we do to work this around?
1) use polymorphism instead?
2) give different functions different names?
3) put functions of the same name in different modules?
Which one will work?

It all depends on what you mean by overloading. There are several use cases, such as:
If you want to use the usual infix operators name in a mathematical expression manipulating something else than integers: rebind your operators locally; modules and "local open" can help with that.
module I32 = struct
open Int32
let (+), (-), ( * ), (/), (!!) = add, sub, mul, div, of_int
end
... I32.(x + y * !!2) ...
If you want an operation to be polymorphic in the type of numeric type being used, you need to abstract over such numeric operators. For example the generic fast exponentiation function (by an integer), that can be used on matrices etc.
let rec pow ( * ) one a = function
| 0 -> one
| n -> pow ( * ) (if n mod 2 = 0 then one else one * a) (a * a) (n / 2)
let () = assert (pow ( *.) 1. 2. 3 = 8.)
More generally, yes, the idea is to capture what you want to "overload" on as a set of operators (here infix operators but plain names are fine and often better for readability), and pass around and abstract over dictionaries of those operations -- much like what Haskell type classes are compiled to, in fact.

Related

When should extensible variant types be used in OCaml?

I took a course on OCaml before extensible variant types were introduced, and I don't know much about them. I have several questions:
(This question was deleted because it attracted a "not answerable objectively" close vote.)
What are the low-level consequences of using EVTs, such as performance, memory representation, and (un-)marshaling?
Note that my question is about extensible variant type specifically, unlike the question suggested as identical to this one (that question was asked prior to the introduction of EVTs!).
Extensible variants are quite different from standard variants in term of
runtime behavior.
In particular, extension constructors are runtime values that lives inside
the module where they were defined. For instance, in
type t = ..
module M = struct
type t +=A
end
open M
the second line define a new extension constructor value A and add it to the
existing extension constructors of M at runtime.
Contrarily, classical variants do not really exist at runtime.
It is possible to observe this difference by noticing that I can use
a mli-only compilation unit for classical variants:
(* classical.mli *)
type t = A
(* main.ml *)
let x = Classical.A
and then compile main.ml with
ocamlopt classical.mli main.ml
without troubles because there are no value involved in the Classical module.
Contrarily with extensible variants, this is not possible. If I have
(* ext.mli *)
type t = ..
type t+=A
(* main.ml *)
let x = Ext.A
then the command
ocamlopt ext.mli main.ml
fails with
Error: Required module `Ext' is unavailable
because the runtime value for the extension constructor Ext.A is missing.
You can also peek at both the name and the id of the extension constructor
using the Obj module to see those values
let a = [%extension_constructor A]
Obj.extension_name a;;
: string = "M.A"
Obj.extension_id a;;
: int = 144
(This id is quite brittle and its value it not particurlarly meaningful.)
An important point is that extension constructor are distinguished using their
memory location. Consequently, constructors with n arguments are implemented
as block with n+1 arguments where the first hidden argument is the extension
constructor:
type t += B of int
let x = B 0;;
Here, x contains two fields, and not one:
Obj.size (Obj.repr x);;
: int = 2
And the first field is the extension constructor B:
Obj.field (Obj.repr x) 0 == Obj.repr [%extension_constructor B];;
: bool = true
The previous statement also works for n=0: extensible variants are never
represented as a tagged integer, contrarily to classical variants.
Since marshalling does not preserve physical equality, it means that extensible
sum type cannot be marshalled without losing their identity. For instance, doing
a round trip with
let round_trip (x:'a):'a = Marshall.from_string (Marshall.to_string x []) 0
then testing the result with
type t += C
let is_c = function
| C -> true
| _ -> false
leads to a failure:
is_c (round_trip C)
: bool = false
because the round-trip allocated a new block when reading the marshalled value
This is the same problem which already existed with exceptions, since exceptions
are extensible variants.
This also means that pattern-matching on extensible type is quite different
at runtime. For instance, if I define a simple variant
type s = A of int | B of int
and define a function f as
let f = function
| A n | B n -> n
the compiler is smart enough to optimize this function to simply accessing the
the first field of the argument.
You can check with ocamlc -dlambda that the function above is represented in
the Lambda intermediary representation as:
(function param/1008 (field 0 param/1008)))
However, with extensible variants, not only we need a default pattern
type e = ..
type e += A of n | B of n
let g = function
| A n | B n -> n
| _ -> 0
but we also need to compare the argument with each extension constructor in the
match leading to a more complex lambda IR for the match
(function param/1009
(catch
(if (== (field 0 param/1009) A/1003) (exit 1 (field 1 param/1009))
(if (== (field 0 param/1009) B/1004) (exit 1 (field 1 param/1009))
0))
with (1 n/1007) n/1007)))
Finally, to conclude with an actual example of extensible variants,
in OCaml 4.08, the Format module replaced its string-based user-defined tags
with extensible variants.
This means that defining new tags looks like this:
First, we start with the actual definition of the new tags
type t = Format.stag = ..
type Format.stag += Warning | Error
Then the translation functions for those new tags are
let mark_open_stag tag =
match tag with
| Error -> "\x1b[31m" (* aka print the content of the tag in red *)
| Warning -> "\x1b[35m" (* ... in purple *)
| _ -> ""
let mark_close_stag _tag =
"\x1b[0m" (*reset *)
Installing the new tag is then done with
let enable ppf =
Format.pp_set_tags ppf true;
Format.pp_set_mark_tags ppf true;
Format.pp_set_formatter_stag_functions ppf
{ (Format.pp_get_formatter_stag_functions ppf ()) with
mark_open_stag; mark_close_stag }
With some helper function, printing with those new tags can be done with
Format.printf "This message is %a.#." error "important"
Format.printf "This one %a.#." warning "not so much"
Compared with string tags, there are few advantages:
less room for a spelling mistake
no need to serialize/deserialize potentially complex data
no mix up between different extension constructor with the same name.
chaining multiple user-defined mark_open_stag function is thus safe:
each function can only recognise their own extension constructors.

How to write general integration function in OCaml

I would like to write a function in OCaml that will calculate the definite integral for the given function. The problem is that I aim for the following syntax:
let sphere r phi theta = r *. sin phi *. cos theta in
let dphi = 10 in (* number of parts *)
let dtheta = 10 in (* number of parts *)
let zero = 0.0 in
let two_pi = 2.0 *. 3.14159
in
integral zero two_pi (integral zero two_pi (sphere 3.0) dphi) dtheta
The problem is that using rule like trapezoidal rule I need to write something like:
0.5 *. (f a +. f b) *. d
Which expects that the f a and f b are not partially applicated functions.
I don't expect that the result from the last integral function call will return me a float number, I'm totally fine with some functional.
I've realized that the question is very unspecific. Let me restate it in a more general way:
I have a function float->float->float which after the application of integral function should give me float->float. It should be general, so the integral of float->float should result in float.
The problem is that I need subtract two functions of the same order: f(a) -. f(b), where both of them could be float->float->float, float->float or even float->float->float.
To decrease the order of a function I need a signature like: (float->'a->float) -> ('a->float).
Is this even possible? Specifically in OCaml?
The more I think about this problem of having one function calculating the integral that can be chained, the more it seems like an impossible task/stupid way to do it.
In fact I've implemented this but using my own data type (called function_type which can be Scalar3rdOrderFunction, Scalar2ndOrderFunction, Scalar1stOrderFunction, Scalar0thOrderFunction). But for the prize of polymorphism the compiler cannot warn me when I try apply the integral three times for function float->float->float.

Check whether number is Fibonacci or not in Standard ML

I am trying to write a code which checks if number is Fibonacci or not in ML. I am a beginner. Help me find out what is the problem with my code.
fun isfib(n :int): bool=
let
val a1=1;
val a2=1;
val temp=0;
in
while a2<n do (
a1=temp
a2=a1
a2=temp+a2
)
if a2=n then true
else false
end;
a1=temp
a2=a1
a2=temp+a2
= is the equality operator in SML, not an assignment operator. So the above code is just equivalent to this:
false (* because a1 is 1, but temp is 0 *)
true (* because a1 and a2 are both 1 *)
true (* because 1 = 0 + 1 *)
So you have three side-effect-free expressions in your loop, so it just won't do anything.
It's clear that you actually want to change the values of those variables, but you can't do that. Variables in SML are immutable - you can't change them after they're set. So even having a while condition like a2 < n doesn't make sense because a2 and n can't change, so the condition is either always true or always false. If you want to use a while loop like this, you should look into the ref type, which allows you to create mutable values that you can use to simulate mutable variables.
That said using while loops and mutation is not idiomatic SML. There's a reason why variables in SML aren't mutable: the language designers want to encourage you to not rely on mutation (and thus also not on while loops). The idiomatic way to loop in SML is to either use higher order functions (like map, filter, foldl etc.) or recursion. For your problem a recursive function would make the most sense.

structural comparison of variants

I want to deal with limits on the integer number line.
I would like to have Pervasives.compare treat RightInfinity > Point x for all x, and the inverse for LeftInfinity.
In the ocaml REPL:
# type open_pt = LeftInfinity | Point of int | RightInfinity
;;
# List.sort Pervasives.compare [LeftInfinity; Point 0; Point 1; RightInfinity]
;;
- : open_pt list = [LeftInfinity; RightInfinity; Point 0; Point 1]
but
# type open_pt = LeftInfinity | Point of int | RightInfinity of unit
;;
# List.sort Pervasives.compare [LeftInfinity; Point 0; Point 1; RightInfinity ()]
;;
- : open_pt list = [LeftInfinity; Point 0; Point 1; RightInfinity ()]
"The perils of polymorphic compare" says
Variants are compared first by their tags, and then, if the tags are equal, descending recursively to the content.
Can one rely on any relationship between the order in which variants appear in a type declaration and the order of the tags?
No, you should not rely on that. You should define your own comparison function. Of course, that means you'll have to lift it through datastructures (to be able to compare, say, lists of open_pt), but that's the safe thing to do when you want a domain-specific comparison function.
Note that extended standard libraries such as Batteries or Core provide auxiliary functions to lift comparisons through all common datastructures, to help you extend your domain-specific comparison to any type containing an open_pt.
Edit: Note that you can rely on that, as the ordering of non-constant constructors is specified in the OCaml/C interface. I don't think that's a good idea, though -- what if you need to put closures inside your functor argument type next time?

Function overloading in OCaml

I have defined some types:
type box = Box of int
type table = Table of int
type compare_result = Lt | Eq | Gt
It seems that in OCaml, we can't define 2 functions with same name but different types of arguments:
let compare (a: box) (b: box): compare_result = (...)
let compare (a: table) (b: table): compare_result = (...)
let res_box = compare (Box 1) (Box 2) in (* which is supposed to call the first funciton *)
let res_table = compare (Table 1) (Table 2) in (* which is supposed to call the second function *)
So could anyone tell me what is the alternative in OCaml to do this? Do we have to name these 2 functions differently?
Yes, the easiest solution is simply to call the functions differently. Allowing programs that do this vastly complicates the type system (not to the point that it isn't possible for experts to design a solution: to the point that you would find it unusable when they do).
Existing solutions for writing a single function compare are the object system in OCaml, and type classes in Haskell (a different extension to the same base type system). But it's much simpler to stay in the simple fragment and to name your functions compare differently.