caml-list - the Caml user's mailing list
 help / color / mirror / Atom feed
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



  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;
as well as URLs for NNTP newsgroup(s).