From: Brian Hurt <bhurt@spnz.org>
To: wiedergaenger@fastmail.fm
Cc: caml-list@inria.fr
Subject: Re: [Caml-list] generic functions
Date: Sun, 9 Jan 2005 09:48:38 -0600 (CST) [thread overview]
Message-ID: <Pine.LNX.4.44.0501090907240.5563-100000@localhost.localdomain> (raw)
In-Reply-To: <20050109131928.GA1759@wafthrudnir>
On Sun, 9 Jan 2005 wiedergaenger@fastmail.fm wrote:
> I just got from LISP to OCaml, and wondered if there is an equivalent of
> generic functions from LISP (CLOS) in OCaml. In the Common Lisp Object
> System methods don't belong to certain objects/classes. They are just
> function specializing on the argument types. So basically I want to
> write something like:
>
> let foo (x : int) = x*x;;
> let foo (x : float) = x*.x;;
>
> This, obviously, will not work since foo is just redefined by the second
> statement. One would think, that having methods not being belonging to
> objects/classes, is rather pointless. Well 95% of the time, there is no
> necessity for that. But in the other 5%, it is really helpful.
>
The short answer is no. For two reasons- first, Ocaml doesn't keep type
information (in most cases) of data at run time, the type information is
used during compilation and then tossed. Which means that Ocaml doesn't
have a way at run time to tell which version of the function to call. And
second, and more importantly, overloading (like you're doing above) would
make type inference extremely difficult if not impossible.
There are several ways to "work around" this limitation in Ocaml,
depending upon what exactly you are doing.
1) Just use different functions. Do:
let ifoo x = x * x;;
let ffoo x = x *. x;;
and just call the correct one. This is generally not as bad a solution as
you might think.
2) Use variant types:
type number = Int of int | Float of float;;
let foo = function
| Int(x) -> Int(x*x)
| Float(x) -> Float(x*.x)
;;
The tags in this case are the type information Ocaml would normally "throw
away".
3) Use modules:
module type Mult = sig
type t
val mul : t -> t -> t
end
module type Foo = sig
type t
val foo : t -> t
end
module Make(M: Mult) : Foo with type t = M.t = struct
type t = M.t
let foo x = M.mul x x
end;;
module IMult = struct
type t = int
let mul x y = x * y
end;;
module IFoo = Make(IMult);;
module FMult = struct
type t = float
let mul x y = x *. y
end
module FFoo = Make(FMult);
For this simple example, modules and functors are clunky- but they allow
the user of your code to create new foo functions, which is usefull.
With the exception of certain artificial contests (Paul Graham) I've never
met a real world problem that needed overloading, or even benefitted
signifigantly from overloading that didn't benefit just as much or more
from one of the solutions above.
Brian
next prev parent reply other threads:[~2005-01-09 15:47 UTC|newest]
Thread overview: 12+ messages / expand[flat|nested] mbox.gz Atom feed top
2005-01-09 13:19 wiedergaenger
2005-01-09 14:56 ` [Caml-list] " Richard Jones
2005-01-09 15:48 ` Brian Hurt [this message]
2005-01-09 17:17 ` David McClain
2005-01-09 18:09 ` brogoff
2005-01-09 18:45 ` padiolea
2005-01-10 0:23 ` skaller
2005-01-11 12:14 ` Daniel Yokomizo
2005-01-10 9:55 ` [Caml-list] " Alex Baretta
2005-01-10 10:47 ` Olivier Andrieu
2005-01-10 12:16 ` Alex Baretta
2005-01-12 23:49 ` Aleksey Nogin
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=Pine.LNX.4.44.0501090907240.5563-100000@localhost.localdomain \
--to=bhurt@spnz.org \
--cc=caml-list@inria.fr \
--cc=wiedergaenger@fastmail.fm \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox