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 SAA17472; Thu, 29 Jan 2004 18:17:36 +0100 (MET) X-Authentication-Warning: pauillac.inria.fr: majordomo set sender to owner-caml-list@pauillac.inria.fr using -f 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 SAA17242 for ; Thu, 29 Jan 2004 18:17:35 +0100 (MET) Received: from mail.physik.uni-muenchen.de (mail.physik.uni-muenchen.de [192.54.42.129]) by concorde.inria.fr (8.11.1/8.11.1) with ESMTP id i0THHZP20723 for ; Thu, 29 Jan 2004 18:17:35 +0100 (MET) Received: from localhost (unknown [127.0.0.1]) by mail.physik.uni-muenchen.de (Postfix) with ESMTP id A85B5201C4; Thu, 29 Jan 2004 17:17:34 +0000 (UTC) Received: from mail.physik.uni-muenchen.de ([127.0.0.1]) by localhost (mail.physik.uni-muenchen.de [127.0.0.1]) (amavisd-new, port 10024) with LMTP id 11978-01-42; Thu, 29 Jan 2004 18:17:32 +0100 (CET) Received: from mailhost.cip.physik.uni-muenchen.de (kaiser.cip.physik.uni-muenchen.de [141.84.136.1]) by mail.physik.uni-muenchen.de (Postfix) with ESMTP id 3A3652001A; Thu, 29 Jan 2004 18:17:32 +0100 (CET) Received: from seekar.cip.physik.uni-muenchen.de (seekar.cip.physik.uni-muenchen.de [141.84.136.52]) by mailhost.cip.physik.uni-muenchen.de (Postfix) with ESMTP id DC6CD85113; Thu, 29 Jan 2004 18:17:31 +0100 (CET) Received: by seekar.cip.physik.uni-muenchen.de (Postfix, from userid 3092) id C040079FD; Thu, 29 Jan 2004 18:17:31 +0100 (CET) Received: from localhost (localhost [127.0.0.1]) by seekar.cip.physik.uni-muenchen.de (Postfix) with ESMTP id BD4F979FC; Thu, 29 Jan 2004 18:17:31 +0100 (CET) Date: Thu, 29 Jan 2004 18:17:31 +0100 (CET) From: Thomas Fischbacher To: William Lovas Cc: caml-list@inria.fr Subject: Re: fancy types (was Re: [Caml-list] ocaml killer) In-Reply-To: <20040129162048.GA29094@force.stwing.upenn.edu> Message-ID: References: <20040127063230.GA12482@inv_machine> <200401282326.i0SNQntl004612@bismarck-chet.watson.ibm.com> <40184A2F.6040007@dcs.qmul.ac.uk> <200401290000.i0T00ntl006988@bismarck-chet.watson.ibm.com> <40184FB9.4000808@dcs.qmul.ac.uk> <200401290034.i0T0Yutl009000@bismarck-chet.watson.ibm.com> <20040129162048.GA29094@force.stwing.upenn.edu> X-BOFH: Daemons did it MIME-Version: 1.0 Content-Type: TEXT/PLAIN; charset=US-ASCII X-Virus-Scanned: by amavisd-new at physik.uni-muenchen.de X-Loop: caml-list@inria.fr X-Spam: no; 0.00; physik:01 caml-list:01 lovas:01 val:01 stupid:01 factorial:01 unification:01 haskell:01 conceptually:01 combinators:01 combinator:01 combinator:01 discourage:01 tagging:01 dynamically:01 Sender: owner-caml-list@pauillac.inria.fr Precedence: bulk On Thu, 29 Jan 2004, William Lovas wrote: > I've passed functions to themselves before without ever having to make use > of such a function Look here: # let fac n = let do_rec specialist n = if n = 0 then 1 else n * specialist specialist (n-1) in do_rec do_rec n;; Characters 74-84: let fac n = let do_rec specialist n = if n = 0 then 1 else n * specialist specialist (n-1) in do_rec do_rec n;; ^^^^^^^^^^ This expression has type 'a -> 'b -> 'c but is here used with type 'a # let fac n = let do_rec specialist n = if n = 0 then 1 else n * (Obj.magic specialist) specialist (n-1) in do_rec do_rec n;; val fac : int -> int = # fac 8;; - : int = 40320 This is just one stupid example where the type system gets in the way while it should not. Yes, here it does not make too much sense, as I would use let rec if I wanted to just create a factorial, but it shows the general principle: whenever I have a function that handles a "base case" and takes a specialist to pass the recursive case on to, which may in turn again require a specialist, I cannot give the specialist itself as further specialist, "because unification would give infinite type", as other functional languages with similar type system (Haskell or SML, say), like to put it. and there are quite some cases where one would like to employ such techniques. (In Common LISP, I use it regularly when working with the "screamer" nondeterministic evaluation module: screamer's biggest advantage is that it is readily available, but it is conceptually broken at many levels. As it in particular cannot code walk a LABELS, I have to resort to such techniques for manual resolution of fixed points to make recursive nondeterministic functions...) As one particular consequence, I also cannot easily map some combinators to ocaml: # let l_combinator x y = x (y y);; Characters 28-29: let l_combinator x y = x (y y);; ^ This expression has type 'a -> 'b but is here used with type 'a But there are more issues... Look here: # type ('a,'b) mypair = Nil | Cons of 'a * 'b;; type ('a, 'b) mypair = Nil | Cons of 'a * 'b Try defining something like this on it: # let rec my_len x = match x with | Nil -> 0 | (Cons (p,q)) -> 1+my_len q;; Characters 70-71: let rec my_len x = match x with | Nil -> 0 | (Cons (p,q)) -> 1+my_len q;; ^ This expression has type 'a but is here used with type ('b, 'a) mypair OF COURSE opinions may differ whether this is really a problem or not. Certainly, you can implement every algorithm you want in ocaml, but I personally feel that a Hindley-Milner like type system restricts my freedom too much and occasionally gets in the way when I want to implement solutions to problems that are most naturally viewed from a lambda calculus point of view. On the other hand, I experience the benefits of such a type system as limited; it is able to catch a lot of mistakes I would not have made anyway. Nah, I'm rather a LISP hacker. > (which already exists in the standard library, it being > mysteriously named Obj.magic and its use being highly discouraged). For good. I bet this feature exists precisely to keep the LISP wizards happy who know about and are not afraid of these dark corners, and have (maybe out of stubbornness :-) ) a strong desire writing LISP code in ocaml. If there were only honest and upright ocaml programmers, such a feature certainly wouuld not exist, and hence it is perhaps a good idea to strongly discourage its use. [I still do not have a good overview over the ocaml library and thus did not know this function. Thanks for that piece of information.] BTW: I also strongly assume that internally, ocaml uses type tagging anyway, at least for the garbage collector; hence it may be possible to use just the engine of ocaml and build a dynamically typed lisp on top of it...? Would be terrific... -- regards, tf@cip.physik.uni-muenchen.de (o_ Dr. Thomas Fischbacher - http://www.cip.physik.uni-muenchen.de/~tf //\ (lambda (n) ((lambda (p q r) (p p q r)) (lambda (g x y) V_/_ (if (= x 0) y (g g (- x 1) (* x y)))) n 1)) (Debian GNU) ------------------- 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