caml-list - the Caml user's mailing list
 help / color / mirror / Atom feed
From: Brian Hurt <bhurt@spnz.org>
To: Peng Zang <peng.zang@gmail.com>
Cc: caml-list@yquem.inria.fr, Jon Harrop <jon@ffconsultancy.com>
Subject: Re: [Caml-list] stl?
Date: Wed, 4 Mar 2009 11:14:50 -0500 (EST)	[thread overview]
Message-ID: <alpine.DEB.2.00.0903041030490.7859@beast> (raw)
In-Reply-To: <200903040920.01990.peng.zang@gmail.com>



On Wed, 4 Mar 2009, Peng Zang wrote:

> -----BEGIN PGP SIGNED MESSAGE-----
> Hash: SHA1
>
> On Wednesday 04 March 2009 01:11:18 am Brian Hurt wrote:
>> 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...
>
> Ha!  =]
>
> But I'll add one more reason.  With functors you have extra overhead like
> having to be explicit with what function you're using.  In your example when
> you want to use Newton's method you always must write "RatioNewton.newtons"
> or "FloatNewtons.newtons".  The alternative is to functorize the call site,
> but (1) that has its own cost: lots of boilerplate functorizing code crowding
> the real code and (2) you just defer the explicit naming cost as when that
> function is called you'll still have to call either Float version or Ratio
> version.

Yeah.  I think of this as one of the advantages of Functors.

Here are two real problems I've hit with type classes, in only a few weeks 
banging around in Haskell.

For example, you can't have more than one instance of a type class for any 
given type.  So let's say you want to have a type class for things that 
can be converted to and from s-expressions, like:
 	data Sexp =
 		Atom String
 		| List [ Sexp ]

 	class Sexpable a where
 		toSexp :: a -> Sexp
 		fromSexp :: Sexp -> Maybe a

So then you start throwing out the standard instances, among others, you 
do one for string:
 	instance Sexpable String where
 		toSexp s = Atom s
 		fromSexp (Atom s) = Just s
 		fromSexp _ = Nothing

and, a little while later, one for generic lists:
 	instance Sexpable a => Sexpable [ a ] where
 		toSexp xs = List $ map toSexp xs
 		fromSexp (List xs) = mapM fromSexp xs
 		fromSexp _ = Nothing

Opps!  Now you have conflicting instances for type String- one the 
explicit implementation, and one via the generic list.  There are kludges 
to get around this, but they cause their own problems (Brian's first law 
of programming: kludges multiply).  A common one is to add the function 
toSexpList and fromSexpList to the fundamental type class, and drop the 
generic list implementation.  Except now you can't simply toSexp a value 
of type Map Int ([Int], Foo) despite the fact that Maps, Ints, Foos, and 
tuples all have toSexp defined over them- that list in there says that you 
have to pick things apart by hand, so you can call toSexpList instead of 
toSexp at the right point.

Here's another example, slightly translated.  Newton's method is actually 
a very widely applicable algorithm.  There is a variant of it, called 
Newton-Kantorovich, which solves systems of non-linear equations. 
Basically, the function f has type vector -> vector, with it's inputs the 
current values of all the variables used by all the equations (as a 
vector), and it's output the computed values of all the equations (as a 
vector).  The derivative of this function, f', has the type vector -> 
matrix, the input being the current values of all the variables, and the 
output being the matrix of partial derivatives.  Basically, the element at 
row i, column j of the matrix is the old fasioned, single-variable 
derivitive of equation i, assuming that all variables except variable j 
are constants (with their current value).  Then, instead of just doing x' 
= x - (f x)/(f' x), we first solve for (f' x)*y = f x for y, which is just 
your standard linear algebra solve Ax = b for x problem.  You can then 
calculate x' = x - y using standard vector subtraction.

But when you try to implement this, you realize that you have not one, but 
three (arguably four), different types all co-variant.  You have the type 
of x, which is a vector (and arguable the different type of f x, which can 
be a different size of vector- is the vector length an aspect of it's type 
or not?), the type of the differential (matrix, in this case), and the 
type of the norm of x, which is generally a real of some sort.  In my 
original example, I assumed that all three of these were the same type- 
but I may not want to.  And actually, you start wanting to split some of 
the various types off earlier- for example, if your function uses 
complexes or quaterions, the type of the values and the types of the 
derivitives may be the same, but you may want a different type (a real 
number type) for the norm.

Now, I comment you *can* do this in Haskell- using GHC specific 
extensions.  But you don't need fancy extensions (which cause problems in 
the type checker, if I understand things correctly) to do this, quite 
easily, with functors.

>
> I think objects are much closer to type classes and a much nicer solution.
> You can write:

If only Ocaml implemented objects!

Oh, wait.  Never mind.

Brian


  reply	other threads:[~2009-03-04 16:15 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
2009-03-04 14:08         ` Christophe TROESTLER
2009-03-04 14:19         ` Peng Zang
2009-03-04 16:14           ` Brian Hurt [this message]
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.0903041030490.7859@beast \
    --to=bhurt@spnz.org \
    --cc=caml-list@yquem.inria.fr \
    --cc=jon@ffconsultancy.com \
    --cc=peng.zang@gmail.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;
as well as URLs for NNTP newsgroup(s).