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 FAA28930; Tue, 16 Jul 2002 05:34:03 +0200 (MET DST) X-Authentication-Warning: pauillac.inria.fr: majordomo set sender to owner-caml-list@pauillac.inria.fr using -f Received: from nez-perce.inria.fr (nez-perce.inria.fr [192.93.2.78]) by pauillac.inria.fr (8.7.6/8.7.3) with ESMTP id FAA28920 for ; Tue, 16 Jul 2002 05:34:02 +0200 (MET DST) Received: from dewberry.cc.columbia.edu (dewberry.cc.columbia.edu [128.59.59.68]) by nez-perce.inria.fr (8.11.1/8.11.1) with ESMTP id g6G3Y0T04878 for ; Tue, 16 Jul 2002 05:34:01 +0200 (MET DST) Received: from there (tw304h3.cpmc.columbia.edu [156.111.84.180]) by dewberry.cc.columbia.edu (8.9.3/8.9.3) with SMTP id XAA13573; Mon, 15 Jul 2002 23:33:56 -0400 (EDT) Message-Id: <200207160333.XAA13573@dewberry.cc.columbia.edu> Content-Type: text/plain; charset="iso-8859-1" From: Oleg To: John Max Skaller Subject: Re: [Caml-list] productivity improvement Date: Mon, 15 Jul 2002 23:34:17 -0400 X-Mailer: KMail [version 1.3.2] Cc: caml-list@inria.fr References: <200207081952.PAA28813@hickory.cc.columbia.edu> <3D2C5538.2090901@ozemail.com.au> In-Reply-To: <3D2C5538.2090901@ozemail.com.au> MIME-Version: 1.0 Content-Transfer-Encoding: 8bit Sender: owner-caml-list@pauillac.inria.fr Precedence: bulk On Wednesday 10 July 2002 11:39 am, John Max Skaller wrote: > Oleg wrote: > >What are the _simplest_ examples that demonstrate considerable (> 2:1) > > O'Caml vs C++ productivity improvement (in terms of program size) and > > where can I find them? > > Try doing this in C++: > > type 'a node = Leaf of 'a | Unop of ('a->'a) * node | Binop of ('a * > 'a -> 'a) > let rec eval n = match n with > > | Leaf i -> i > | Unop (f,n) -> f (eval n) > | Binop (f,n1,n2) -> f ((eval n1), (eval n2)) > > [Hint: it cannot be done without one of: > a) casts, or > b) serious difficulties wth memory management > ] Shame on you! I hear you are on the C++ standardization committee :) Code first [1], comments below. 1 #include 2 #include 3 4 template 5 struct node { 6 virtual T eval() = 0; 7 }; 8 9 template 10 struct leaf : public node { 11 T i; 12 T eval() { return i; } 13 leaf(const T& t) : i(t) {}; 14 }; 15 16 template 17 struct unop : public node { 18 T (*fun)(T); 19 node& n; 20 T eval() { return fun(n.eval()); } 21 unop(T (*f)(T), node& N) : fun(f), n(N) {} 22 }; 23 24 template 25 struct binop : public node { 26 T (*fun)(T, T); 27 node &n1; 28 node &n2; 29 T eval() { return fun(n1.eval(), n2.eval()); } 30 binop(T (*f)(T, T), node& N1, node& N2) : fun(f), n1(N1), n2(N2) {} 31 }; 32 33 int main() { 34 typedef node N; 35 typedef leaf L; 36 typedef unop U; 37 typedef binop B; 38 L a(4); 39 U b(std::sin, a); 39 U b(std::sin, a); 40 U c(std::cos, a); 41 B d(std::atan2, b, c); 42 std::cout << d.eval() << '\n'; 43 } As one can see, the code is reasonably idiomatic C++, there are no casts or explicit memory management. Templates are used only for genericity. If one looks past the superficial syntax differences, the C++ code is not even much more verbal than the O'Caml example, namely: 1) one needs to define the abstract (interface) class instead of O'Caml's succinct "type 'a node = ". 2) writing "template", "struct", ": public node", "};" adds to program size, while decreasing readability and compilation speed. But writing these really happens without much thinking. 3) constructors do have to be written manually, but that's only 3 LOC total (1 per each derived class / variant), and they are very simple and idiomatic. 4) as used in "main()", the C++ code will not take any "abstraction" [2] performance pentalty John's example was still very interesting [3], thanks: we've learned that O'Caml variant types translate into C++ single inheritance from abstract classes, not unions. Give me more! Best regards, Oleg P.S. What I do like about C++, is that even though the language claims to be multi-paradigm, good design is really class-based (structs are classes), while in O'Caml one has to decide on using classes vs records + HOFs, and lists vs arrays vs bigarrays. IMHO maybe O'Caml needs fewer types. [1] I'm no language lawyer, but I think this is 100% ANSI/ISO C++. BTW, it compiled with "g++-3.0 -pedantic" without warnings or errors. [2] In C terms, "calling function through a pointer" in node's virtual table. There will be no penalty, because the C++ compiler is required to infer types at compile time here. How about O'Caml? Will it do "match" at compile time, if possible? [3] Special Simpsons quote today: KITENGE: This is the earliest known fossil of a human being. It's over two million years old. HOMER: Pff, I've got more bones than that guy. If you're trying to impress me, you've failed. KITENGE: It's not the number of bones, sir, it's the... HOMER: You have failed! ------------------- 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