caml-list - the Caml user's mailing list
 help / color / mirror / Atom feed
From: John Max Skaller <skaller@ozemail.com.au>
To: wester@ilt.fhg.de
Cc: caml-list@inria.fr
Subject: Re: [Caml-list] Why People Aren't Using OCAML? (was Haskell)
Date: Sat, 31 Mar 2001 04:59:16 +1000	[thread overview]
Message-ID: <3AC4D784.93F5F2FB@ozemail.com.au> (raw)
In-Reply-To: <200103270857.KAA24323@ilt.fhg.de>

wester@ilt.fhg.de wrote:

>But probably I still didn't grasp what the real advantages of
> OCaml compared to C++, Java etc. are. So give me and other OCaml
> beginners some more help to better understand what makes OCaml
> superior compared to these main stream languages.

	Ocaml offers (at least :-) two advantages for elementary
use. The first is a proper concept of union. Here is an Ocaml union
and a use of it:

	type node = 
		| Const of int 
		| Unary of char * node
		| Binary of char * node * node

	(* print expression tree in reverse polish *)
	let rp nd = match nd with
		| Const i -> print_int i
		| Unary (op , arg) -> 
			rp arg  ^ " " print_char op
		| Binary (op, arg1, arg2) ->
			rp arg1 ^ " " ^ rp arg2 ^ " " ^ print_char op

How would you do this in C/C++?

	In C, you _ought_ to use:

	struct node {
		enum { Const_tag, Unary_tag, Binary_tag } tag;
		union {
			int Const;
			struct { char op; node *arg; } Unary;
			struct { char op; node *arg1; node *arg2; } Binary;
		}
	};

To use it, you need to write:

	void rp(node *nd) {
		switch (u.tag) {
		case Const_tag: printf("%d",u.Const); break;
		case Unary_tag: 
			rp(u.Unary.arg); printch(' '); printch(U.Unary.op);
			break;
		case Binary_tag: 
			rp(u.Binary.arg1); printch(' ');
			rp(u.Binary.arg2); printch(' '); printch(U.Binary.op);
			break;
	}

You might leave out the break, and you might accidentally refer to the
wrong component: you can't make either of these mistakes in Ocaml.
Although not shown, you'd have problems destroying the structure
if you forgot a 'free': Ocaml collects garbage automatically.

The above is the 'correctest' solution in C. It won't work in C++,
however, because unions of constructible types are not allowed.
So you're forced to use inheritance and a dynamic cast, which is
very confusing because there is NO abstraction here, and NO
polymorphism.

The second advantage for elementary programming is that functions
are first class values. What this means is that you can define
a function in a scope, and pass the function to some other function,
and when you invoke it the scope is remembered. The thing you are
passing is sometimes called a function _closure_. Here is a simple
example:

	let printit printer = printer () in
	let f x = 
		let a = 1 in
		let p () = print_int a in
		printit p

Here, the printit function just invokes the printing routine 'printer',
which is 'p' in the function 'f'. In passing 'p', the value 'a' is not
forgotten. You can do the equivalent in C++ with functiods: but it 
is VERY messy (and very hard to get the memory management right).
Closures are very powerful. 

You do the 'moral equivalent' of the above in C++ using 
classes .. using about 10 times the number of lines of code, 
and probably destroying locality. Here is an example:

	let p lst = 
		let a = 1 in 
		List.iter (fun x -> print_int (x+a)) lst

In C++:

	struct printer {
		int a;
		printer(int aa) : a(aa) {}
		void operator()(int x); { cout << x + a; }
	}
	void p (list<int> l) {
		int a = 1;
		for_each(lst.begin(), lst,end(), printer(a));
	}

but you have to define the 'struct printer' outside
the 'p' routine, destroying locality. Just try
replacing a triply indexed loop with three invocations
of 'for_each' to see what I mean: STL is a great library,
which is basically useless because functions aren't first
class citizens.

[This particular example has significance to me: I gave up
writing a book on generic programming in C++ when I saw
just how long winded it was to code a triply nested loop
using 'for_each']

-- 
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


  reply	other threads:[~2001-04-01 21:09 UTC|newest]

Thread overview: 28+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2001-03-24  3:17 Arturo Borquez
2001-03-24  8:03 ` Vijay Chakravarthy
2001-03-24 18:38   ` Brian Rogoff
2001-03-24 21:55     ` Vijay Chakravarthy
2001-03-26  0:29     ` Dennis Gang Chen
2001-03-26  3:03       ` Brian Rogoff
2001-03-26  9:34         ` BDD and Ocaml (was: Re: [Caml-list] Why People Aren't Using OCAML?) David Mentre
2001-03-26 15:44           ` Brian Rogoff
2001-03-30 14:37             ` [Caml-list] OCaml binding to cmuBDD David Mentre
2001-03-26 14:10         ` [Caml-list] Why not article in journal ? (was Why People Aren't Using OCAML?) Christophe Raffalli
2001-03-26 12:43           ` Xavier Leroy
2001-03-26 13:25     ` [Caml-list] Why People Aren't Using OCAML? (was Haskell) FabienFleutot
2001-03-28  8:23       ` [Caml-list] [ora book] Why a horse? David Mentre
2001-03-29 13:48       ` [Caml-list] Why People Aren't Using OCAML? (was Haskell) Xavier Leroy
2001-03-29 14:05         ` Daniel de Rauglaudre
2001-03-29 14:14           ` Xavier Urbain
2001-03-29 14:38         ` Jean-Francois Monin
2001-03-29 16:19           ` Brian Rogoff
2001-03-27 23:43     ` John Max Skaller
2001-03-28  4:37       ` Brian Rogoff
2001-03-28 14:24         ` Joshua D. Guttman
2001-03-28 19:32       ` William Chesters
2001-03-27  3:43   ` Chris Hecker
2001-03-27  8:57     ` wester
2001-03-30 18:59       ` John Max Skaller [this message]
2001-03-28 22:00     ` Joseph R. Kiniry
  -- strict thread matches above, loose matches on Subject: below --
2001-03-29 14:26 Toby Moth
2001-03-23 18:04 [Caml-list] recursive modules redux, & interface files Brian Rogoff
2001-03-23 20:35 ` [Caml-list] Why People Aren't Using OCAML? (was Haskell) Mattias Waldau

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=3AC4D784.93F5F2FB@ozemail.com.au \
    --to=skaller@ozemail.com.au \
    --cc=caml-list@inria.fr \
    --cc=wester@ilt.fhg.de \
    /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).