caml-list - the Caml user's mailing list
 help / color / mirror / Atom feed
From: John Max Skaller <skaller@ozemail.com.au>
To: Chris Hecker <checker@d6.com>
Cc: caml-list@inria.fr
Subject: Re: [Caml-list] Re: generic programming
Date: Fri, 05 Jul 2002 01:18:17 +1000	[thread overview]
Message-ID: <3D246739.4030204@ozemail.com.au> (raw)
In-Reply-To: <4.3.2.7.2.20020703102610.0248b280@mail.d6.com>

Chris Hecker wrote:

>
>
> Is it, in the sense that Stepanov and those guys mean it?  John Max 
> Skaller and I were talking about this a long time ago, and I thought 
> he posted this to the list but it turns out it was in email to me, but 
> here goes anyway:
>
> "Sure. I have a 'problem' example: try to implement STL iterators
> in Caml. I don't have the expertise in Caml: I think this requires
> 'higher order functors'. Several people have attempted this, no one
> has succeeded that I know of."
>
> Perhaps he's reading and can explain some of the problems.
>
> Caml polymorphism&functors and C++ templates seem to have different 
> properties, and I wonder what you can and can't write in each. 


>
> > Is generic programming possible with O'Caml?
> Sure it is possible !

C++ templates use TWO kinds of 'polymorphism' together:

    1) parametric polymorphism
    2) overloading (ad hoc polymorphism)

for example:

    template<class T> int g(T t) { return f(t); }

Notice that 'f' is chosen at instantiation time, based on
the type T of t. You cannot do this in Ocaml, where you
must write instead:

    let g t f = f t in ...

that is, you have to pass the 'dependent function' f explicitly.
This includes methods. The only functions in Ocaml that can act
on a value which has the type of a parameter (but which
do not need to be explicit arguments) are parametrically
polymorphic ones, for example:

    let pair x = (x,x) in ..
    let f x = pair x (* don't need to pass 'pair', its polymorphic *)

now, C++ iterators *depend* on ad hoc polymophism.
For example the algorithm:

    template <class iterator1, class iterator2>
    iterator2 copy(iterator1 src, iterator1 end, iterator2 dst) {
        while(src != end) *dst++ = *src++;
        return dst;
    }

has 'ad hoc' operations on the types iterator1 and iterator2:
namely comparison, dereference, and increment,
and, there are also two implicit types

    iterator1::value_type
    iterator2::value_type

which either must be the same, or there is
a conversion between them .. which is yet another
function not passed explicitly to the template.

As you can see, C++ relies on the *syntactic form*
of the template body, to express the genericity,
and overloading at instantiation time. In general,
this is not 'well principled' although it works well
in practice (but also leads to disasters when it fails
without a compilation error). technically, instantiation
must be functorial, in the sense of both category theory
an Ocaml functors (since these are the same idea ..),
that is, instantiation should 'preserve structure'.

But there is no assurance the C++ instantiation mechanism is functorial.

To make 'copy' work in Ocaml, you can either pass ALL the arguments
explicitly -- and there are a lot of them here .. or you can package them
up in a module with a specifiic interface and use a functor.

Ocaml functors (and polymorphic functions) guarratee functorial 
instantiation
on the algebraic (free) types. If a module has constraints represented as
comments, these are not necessarily preserved by instantiation .. so both
systems have limitations.

Only two data structures in Ocaml readily admit iterators: lists and arrays.
Other data structures like hastables, sets, maps, etc, have control
inverted iterators, which are much weaker (that is, you have to provide
a callback which is given each value in turn -- this is very much less 
useful
than the C++ construction dual to it in which the values are fetched in turn
by an user algorithm...you have to 'control invert' the algorithm to use
it with Ocaml XXX.iter functions, which is non-trivial and greatly
obscures the code. [But I think it can always be done using a mechnical
procedure, related to continuatiuon passing .. my Felix compiler does in
precisely this, but only for a simgle message source at present]

The real problem for STL style iterators is this: in C++,
the very point of iterators is that container independent
algorithms can be written. There is no easy way to do this in Ocaml,
at least not without using classes.

There is a technical way to express the limitation: in Ocaml,
functions are value polymorphic. But higher order functions cannot
be functorially polymorphic, that is, that cannot vary over
different data functors (data structures like lists and arrays
are known as data functors). Hence, we have

    List..map
    Array.map
    Hashtble.map

etc, instead of just 'map' .

Functorial polymorphism can be implemented for a wide class
of functors in an extension of ML: there is work being done
by Barry Jay at UTS on this. See

    http://www-staff.it.uts.edu.au/~cbj/Publications/functorial_ml.ps.gz

Perhaps some of the type theorists reading the above text can give
a better and more proper explanation. But basically: C++ allows
polymorphism over data functors, but that polymorphism is NOT
parametric like it should be. Ocaml insists of everything being
'correct', which excludes features which 'sort of work sometimes' :-)

-- 
John Max Skaller, mailto:skaller@ozemail.com.au
snail:10/1 Toxteth Rd, Glebe, NSW 2037, Australia.
voice:61-2-9660-0850



-------------------
To unsubscribe, mail caml-list-request@inria.fr Archives: http://caml.inria.fr
Bug reports: http://caml.inria.fr/bin/caml-bugs FAQ: http://caml.inria.fr/FAQ/
Beginner's list: http://groups.yahoo.com/group/ocaml_beginners


  parent reply	other threads:[~2002-07-04 15:18 UTC|newest]

Thread overview: 31+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2002-07-03  2:49 [Caml-list] " Oleg
2002-07-03  8:37 ` [Caml-list] " Ketanu
2002-07-03 17:29   ` Chris Hecker
2002-07-03 20:07     ` Oleg
2002-07-03 20:34       ` Alessandro Baretta
2002-07-04 15:33         ` John Max Skaller
     [not found]           ` <3D249B27.5080807@baretta.com>
     [not found]             ` <3D25D27B.2020005@ozemail.com.au>
2002-07-07 20:42               ` Alessandro Baretta
2002-07-08  0:59                 ` John Max Skaller
2002-07-08  7:29                   ` Alessandro Baretta
2002-10-15  0:10         ` Eray Ozkural
2002-07-03 21:55     ` Peter Wood
2002-07-04  2:02       ` james woodyatt
2002-07-04 15:18     ` John Max Skaller [this message]
2002-07-05  8:42       ` Francois Pottier
2002-07-05  9:25         ` Xavier Leroy
2002-07-05  9:57           ` Chris Hecker
2002-07-05 13:54             ` Xavier Leroy
2002-07-05 17:59               ` Chris Hecker
2002-07-05 20:31                 ` John Max Skaller
2002-07-05 19:33               ` John Max Skaller
2002-07-05 19:31             ` John Max Skaller
2002-07-05  8:33     ` Francois Pottier
2002-07-05 23:05       ` Dave Berry
2002-07-08  9:54         ` Francois Pottier
2002-07-08 15:49           ` John Max Skaller
2002-08-02 14:49         ` [Caml-list] Streams Diego Olivier Fernandez Pons
2002-08-02 15:29           ` Alain Frisch
2002-08-03 14:19             ` Diego Olivier Fernandez Pons
2002-07-03  8:42 ` [Caml-list] generic programming Johan Baltié
     [not found]   ` <002301c22270$fb4ca160$2be213c3@youngkouzdra>
     [not found]     ` <20020703092753.M39371@wanadoo.fr>
2002-07-05 10:38       ` Anton Moscal
2002-07-03  9:10 ` Jun P.FURUSE

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=3D246739.4030204@ozemail.com.au \
    --to=skaller@ozemail.com.au \
    --cc=caml-list@inria.fr \
    --cc=checker@d6.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).