From mboxrd@z Thu Jan 1 00:00:00 1970 Received: (from majordomo@localhost) by pauillac.inria.fr (8.7.6/8.7.3) id PAA15441; Wed, 11 Apr 2001 15:57:21 +0200 (MET DST) X-Authentication-Warning: pauillac.inria.fr: majordomo set sender to owner-caml-list@pauillac.inria.fr using -f Received: (from weis@localhost) by pauillac.inria.fr (8.7.6/8.7.3) id PAA15328 for caml-list@pauillac.inria.fr; Wed, 11 Apr 2001 15:57:20 +0200 (MET DST) Received: from concorde.inria.fr (concorde.inria.fr [192.93.2.39]) by pauillac.inria.fr (8.7.6/8.7.3) with ESMTP id SAA29968 for ; Tue, 10 Apr 2001 18:49:24 +0200 (MET DST) Received: from localhost.localdomain (kenny78.zip.com.au [61.8.18.206]) by concorde.inria.fr (8.11.1/8.10.0) with ESMTP id f3AGnDb02399 for ; Tue, 10 Apr 2001 18:49:14 +0200 (MET DST) Received: from ozemail.com.au (IDENT:root@localhost [127.0.0.1]) by localhost.localdomain (8.9.3/8.8.7) with ESMTP id CAA05523; Wed, 11 Apr 2001 02:48:54 +1000 Message-ID: <3AD33976.41F6DE64@ozemail.com.au> Date: Wed, 11 Apr 2001 02:48:54 +1000 From: John Max Skaller X-Mailer: Mozilla 4.7 [en] (X11; I; Linux 2.2.12-20 i686) X-Accept-Language: en MIME-Version: 1.0 To: Chris Hecker CC: Brian Rogoff , caml-list@inria.fr Subject: Re: [Caml-list] Generics? References: <4.3.2.7.2.20010402232928.00d3b180@shell16.ba.best.com> <4.3.2.7.2.20010403124151.03427af0@shell16.ba.best.com> Content-Type: text/plain; charset=us-ascii Content-Transfer-Encoding: 7bit Sender: owner-caml-list@pauillac.inria.fr Precedence: bulk Chris Hecker wrote: > I first started thinking about this when I was trying to wrap my head > around the difference between Caml style polymorphism and C++ templates. Ocaml generic functions require all arguments to be passed in explicitly. C++ templates don't: some of the arguments are passed implicitly. These arguments have to be looked up at instantiation time, in places depending on the types of the template type arguments. For example: template T add(T t1, T t2) { return t1 + t2; } Here, operator+ must be looked up when T is bound. It may be a method of T, or it could be a function defined in the namespace in which T is defined, or any base of T. Or it could be defined in the context in which the template is defined. Lookup is followed by overload resolution. Consider even the case: template T add(T t1, T t2) { return t1.add(t2); } and you see there is a constraint that T must be a class with a method 'add' defined. The constraint is _implicit_. Ocaml generic functions provide 'unconstrained genericity': they work for ALL types. More precisely, if a call 'types' correctly, then the function will work. This is NOT true in C++, where it is not enough to know that a call types correctly, since the instantiation can still fail due to a failure looking up the implicit arguments (or during subsequent overload resolution). In general the use of implicit arguments is a bad, it breaks the fundamental principle 'Explicit Interfaces' of Bertrand Meyer. Note however that even Ocaml is 'weaker' than desired, since interfaces cannot fully express constraints: type systems aren't expressive enough. For example, a module may be: module type integer = sig type int val incr : int -> int val succ : int -> int -> bool end and you can see the interface is inadequate, because the axiom succ x (incr x) is not represented. This is relevant to generics too, since a functor may require this constraint of its argument, but it cannot be stated. While one can live with constraints stated in comments (by manually checking the constraints), Ocaml also has the opposite problem. Some higher order generics cannot be defined, and some of these CAN be defined using C++ templates. Consider the generic 'map' which takes a container container and applies a function f:T -> V to each element, producing a container container In Ocaml, there is one 'map' written per data structure. But 'map' is actually quite generic for a large class of containers. In C++ you can write a template for map, but it relies on overloading things like the begin() and end() methods used to obtain the iterators. In 'Functorial ML' (including FISh 2), there is a single 'map' function that works for all data structures. So advances are being made, to define 'even more generic' functions than ocaml can support, and separately, work is being done to allow constraints to be expressed (all obeying the 'Explicit Interfaces' requirement). [Note that Ocaml does have some ability to handle constraints] -- John (Max) Skaller, mailto:skaller@maxtal.com.au 10/1 Toxteth Rd Glebe NSW 2037 Australia voice: 61-2-9660-0850 checkout Vyper http://Vyper.sourceforge.net download Interscript http://Interscript.sourceforge.net ------------------- To unsubscribe, mail caml-list-request@inria.fr. Archives: http://caml.inria.fr