From: Brian Hurt <bhurt@spnz.org>
To: Jon Harrop <jon@ffconsultancy.com>
Cc: caml-list@yquem.inria.fr
Subject: Re: [Caml-list] stl?
Date: Wed, 4 Mar 2009 01:11:18 -0500 (EST) [thread overview]
Message-ID: <alpine.DEB.2.00.0903032359570.7859@beast> (raw)
In-Reply-To: <200903040159.48574.jon@ffconsultancy.com>
On Wed, 4 Mar 2009, Jon Harrop wrote:
> On Wednesday 04 March 2009 00:11:32 you wrote:
>> On Tue, 3 Mar 2009, Jon Harrop wrote:
>>> Functors give you the same capability in OCaml but they are rarely used
>>> precisely because the functionality is not very useful.
>
> Also largely because there is not enough good tutorial information available
> explaining how to leverage functors.
This is another large factor. The three reasons functors aren't used very
much are because:
1) They're a big, scary name,
2) They're slightly less efficient,
3) There are no good tutorials about how to use them, and
4) A fanatical devotion to the pope.
I'll come in again...
> Efficiency is only important in the context of functors when abstracting very
> fast and common functions like arithmetic without defunctorizing your code. I
> don't think that is why people avoid functors in OCaml.
Arithmetic operators that are themselves very cheap. The cost of
functorization is large compared to, say, floating point addition- but
small compared to the cost of, say, vector addition. And it's expensive
only because Ocaml lacks an obvious optimization (defunctorization). And
yet this whole discussion is simply proving my point- we're comparing
clock cycles here. Yes, if you're writing the inner loops of a numeric
computation that'll take days to run, maybe, *MAYBE*, the cost difference
of calling via a functor is worthwhile to worry about. But that's the
point where I start being really tempted to drop down to C, or even
assembly (for SSE Vectorization). But for the vast bulk of people
programming, performance (at least on the clock cycle level) simply isn't
that important- as demonstrated by all the "real work" being done in
hideously slow languages like Ruby, Python, etc...
> I think that is a reflection of what the communities desire rather than what
> they already have. OCaml is already fast (particularly on amd64) but OCamlers
> always want even better performance. Haskell's development experience is a
> real sore point and they want to address that. However, I would also say that
> both communities are moving very slowly toward these goals.
Both languages have their annoyances. Adjusting for the fact that I'm
significantly more familiar with and comfortable with Ocaml, I don't find
Haskell that much more difficult to work in.
>
>> The type classes comparison isn't even an analogy- it's a precise
>> relationship. Anywhere you might be thinking, in Ocaml, "this would be a
>> nice place to use a type class", use a functor. You want operator
>> overloading in Ocaml? You got it: use a functor.
>
> Functors do not facilitate operator overloading. You still end up with a
> combinatorial explosion in the number of operator names.
Bwuh?
Try this. Let's reimplement Haskell's Fractional class, in Ocaml, and
then do Newton's method using this new Fractional class. Then I'll
provide implementations that use both floats and ratios (arbitrary
precision fractions). First, we need to define Fractional. That's just:
module type Fractional = sig
type t
val ( +. ) : t -> t -> t
val ( -. ) : t -> t -> t
val ( *. ) : t -> t -> t
val ( /. ) : t -> t -> t
val fabs : t -> t
(* other functions elided from brevity *)
end;;
Now we write our functorized Newton's method:
module Make(F: Fractional) = struct
open F;;
let rec newtons epsilon f df x =
let x' = x -. ((f x) /. (df x)) in
if (fabs (x -. x')) < epsilon then
x'
else
newtons epsilon f df x'
;;
end;;
Now we provide an instance of Fractional for floats:
module FloatFractional = struct
type t = float
let ( +. ) = ( +. );;
let ( -. ) = ( -. );;
let ( *. ) = ( *. );;
let ( /. ) = ( /. );;
let fabs x = abs_float x;;
end;;
module FloatNewtons = Make(FloatFractional);;
Now we provide an instance for Ratios:
module RatioFractional = struct
type t = Ratio.ratio;;
let ( +. ) = Ratio.add_ratio;;
let ( -. ) = Ratio.sub_ratio;;
let ( *. ) = Ratio.mult_ratio;;
let ( /. ) = Ratio.div_ratio;;
let fabs = Ratio.abs_ratio;;
end;;
module RatioNewtons = Make(RatioFractional);;
Viola. Operator overloading. In Ocaml. And it's not that much worse
than Haskell equivalent, once you realize that the definitions of
Fractional, FloatFractional, and RatioFractional all should be in the
standard library (and the latter two should be just called Float and
Ratio).
And typeclasses have their problems as well- which are off topic for this
list.
>
>> If this causes you a
>> knee jerk reaction about performance, ask yourself this: do you know how
>> type classes are implemented in Haskell, and what their performance hit
>> there is? Now, imagine programming haskell where typeclasses are only
>> used in a very places- Ord, Eq, Monad. No Num. No Monoid. No Show.
>> That's Ocaml. Not that it has to be.
>
> I don't follow your breakdown. OCaml does not have Ord and Eq, it only has a
> hack for structural equality. Same for Show. Few people care about Monad, Num
> and Monoid.
The turn you missed was that I'm say "what if Haskell programmers used
type classes as rarely as Ocaml programmers use functors?" Typeclasses
are a huge win in Haskell, but primarily because they get *used*.
>
> However, that is trivial to fix with run-time type information that can convey
> per-type functions. Both F# and my HLVM already do that.
I suppose we could sit around and whine that Ocaml doesn't have type
classes, or reflection, or some other neat feature, that if it only had
it, we could all these neat things with them.
Or we could use the equivalently powerfull features Ocaml *already* has...
Brian
next prev parent reply other threads:[~2009-03-04 6:11 UTC|newest]
Thread overview: 72+ messages / expand[flat|nested] mbox.gz Atom feed top
2009-03-03 21:40 stl? Raoul Duke
2009-03-03 22:31 ` [Caml-list] stl? Yoann Padioleau
2009-03-03 22:42 ` Till Varoquaux
2009-03-03 23:36 ` Jon Harrop
2009-03-04 0:13 ` Peng Zang
2009-03-04 0:58 ` Yoann Padioleau
2009-03-04 1:10 ` Raoul Duke
2009-03-04 1:19 ` Pal-Kristian Engstad
2009-03-04 1:21 ` Yoann Padioleau
2009-03-04 1:29 ` Jon Harrop
2009-03-04 14:26 ` Kuba Ober
2009-03-04 14:24 ` Kuba Ober
2009-03-03 23:42 ` Jon Harrop
2009-03-04 0:11 ` Brian Hurt
2009-03-04 1:05 ` Yoann Padioleau
2009-03-04 4:56 ` Brian Hurt
2009-03-04 20:11 ` Yoann Padioleau
2009-03-04 21:59 ` Brian Hurt
2009-03-04 22:42 ` Yoann Padioleau
2009-03-04 23:19 ` Jon Harrop
2009-03-04 23:03 ` Jon Harrop
2009-03-11 3:16 ` Brian Hurt
2009-03-11 5:57 ` David Rajchenbach-Teller
2009-03-11 6:11 ` David Rajchenbach-Teller
2009-03-04 1:59 ` Jon Harrop
2009-03-04 6:11 ` Brian Hurt [this message]
2009-03-04 14:08 ` Christophe TROESTLER
2009-03-04 14:19 ` Peng Zang
2009-03-04 16:14 ` Brian Hurt
2009-03-04 16:35 ` Andreas Rossberg
2009-03-04 16:40 ` Peng Zang
2009-03-04 21:43 ` Nicolas Pouillard
2009-03-05 11:24 ` Wolfgang Lux
2009-03-04 19:45 ` Jon Harrop
2009-03-04 21:23 ` Brian Hurt
2009-03-04 23:17 ` Jon Harrop
2009-03-05 2:26 ` stl? Stefan Monnier
2009-03-04 3:10 ` [Caml-list] stl? Martin Jambon
2009-03-04 6:18 ` Brian Hurt
2009-03-04 16:35 ` Mikkel Fahnøe Jørgensen
2009-03-04 16:48 ` Yoann Padioleau
2009-03-04 20:07 ` Jon Harrop
2009-03-04 20:31 ` Richard Jones
2009-03-04 20:49 ` Yoann Padioleau
2009-03-04 21:20 ` Andreas Rossberg
2009-03-04 21:51 ` Pal-Kristian Engstad
2009-03-04 22:50 ` Jon Harrop
2009-03-04 23:18 ` Pal-Kristian Engstad
2009-03-05 1:31 ` Jon Harrop
2009-03-05 2:15 ` Pal-Kristian Engstad
2009-03-05 3:26 ` Jon Harrop
2009-03-05 6:22 ` yoann padioleau
2009-03-05 7:02 ` Raoul Duke
2009-03-05 8:07 ` Erick Tryzelaar
2009-03-05 9:06 ` Richard Jones
2009-03-05 9:34 ` malc
2009-03-05 9:56 ` Richard Jones
2009-03-05 10:49 ` malc
2009-03-05 11:16 ` Richard Jones
2009-03-05 12:39 ` malc
2009-03-05 19:39 ` Jon Harrop
2009-03-05 21:10 ` Pal-Kristian Engstad
2009-03-05 22:41 ` Richard Jones
2009-03-05 22:53 ` malc
2009-03-05 8:59 ` Richard Jones
2009-03-05 17:50 ` Raoul Duke
2009-03-05 8:17 ` Kuba Ober
2009-03-05 1:06 ` Jon Harrop
2009-03-05 9:09 ` Richard Jones
2009-03-05 20:44 ` Jon Harrop
2009-03-05 20:50 ` Jake Donham
2009-03-05 21:28 ` [Caml-list] OCaml's intermediate representations Jon Harrop
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=alpine.DEB.2.00.0903032359570.7859@beast \
--to=bhurt@spnz.org \
--cc=caml-list@yquem.inria.fr \
--cc=jon@ffconsultancy.com \
/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