Computer Science Canada [O'Caml-tut] G'day O'Caml |
Author: | wtd [ Mon Jul 19, 2004 8:34 pm ] | ||||||||||||||||||||||||||||||||||
Post subject: | [O'Caml-tut] G'day O'Caml | ||||||||||||||||||||||||||||||||||
Getting O'Caml First off, O'Caml 3.08 is available for download here. For Linux users there's source code available, and for Windows and Mac OS X users precompiled binaries are also available. The ocaml program both runs compiled O'Caml programs and offers an interactive interpreter for quick experimentation. The normal prompt when using this interpreter is simply "#". The ocamlc program compiles O'Caml source code to code which can be executed by ocaml. A Quick Introduction Objective-Caml is a strongly typed language. However, the vast majority of the time, it is able to infer what types are being used, so there's no need to specify them yourself. This alone greatly speeds development. O'Caml is a functional language. Functions exist in O'Caml as first class things which can be passed around as easily as ints or chars in certain other languages which shall remain nameless. O'Caml is also an object-oriented language, supporting multiple inheritance. Though the syntax is a bit different than what you might be accustomed to, O'Caml offers great things for fans of object-oriented development. First Program
Obviously the code I ran simply printed the string "G'day O'Caml", tacking on a newline. So what's this about?
Everything in O'Caml has a return value. The "-" indicates that the return value of the functiion wasn't bound to any name. Normally if we had bound it to a name, that name would appear here instead. "unit" indicates the type of the return value. This is somewhat analogous to "void" in C-derived languages. "()" is always the value of type "unit", but this is where the actual value returned would be indicated. Binding Names to Values Let's look at a slightly more complex example to demonstrate this. Here I'll alo be demonstrating the "let" syntax used to bind names to values. This shouldn't be confused with the concept of variables in other languages. I'll simply be giving a name to a particular value. That name can then stand in wherever I might otherwise have manually typed the value, but it can't be modified, except by rebinding that name to a different value.
First, let me note that ";;" in much the same as ";" in C, C++, Java, etc. In larger O'Caml programs it rarely proves necessary due to the nature of O'Caml syntax, but it's essential here to tell the interactive interpreter we're done typing and want to see the result of what we've input. The above code should otherwise be pretty self-explanatory. Local Binding There's a twist though. In the above example, "greeting" is now visible to the rest of the program. It will also rebind "greeting" from whatever it was bound to before.
Instead, howerver, we could use "let ... in ..." to bind a value to "greeting" only for the duration of a single expression.
The ; Operator Of course, this isn't terribly valuable. If we could locally bind a value for a sequence of expressions, that might be valuable.
Here the ";" creates a sequence of expressions. A similar syntax is used for creating sequences of data, such as lists which are approximately the equivalent of arrays. The "^" operator concatenates strings. Of course, it should also be noted that the above can be improved by using more than one binding.
Functions Of course, being a functional language, functions are integral to O'Caml. Let's create a function to allow for greeting anyone.
Callling this function is then as simple as:
Where the ability to pass functions to other functions as arguments is easily demonstrated by applying a function to a list of items. For instance, I may want to greet a list of names.
List.iter is a function in the List module. That module is present by default in the O'Caml interactive interpreter, but programs should include the following line to have access to that module. The same syntax is used for accessing other modules as well.
This function allows us to apply functions which return "unit". To apply functions which return another value, we should use the List.map functions. For instance, we might want to add 1 to each number in a long list of numbers.
Operators as Functions Operators such as "+" are simply functions which take two arguments.
Is equivalent to:
Partial Application of Functions In O'Caml a function lacking one or more arguments simply returns a function which takes those arguments. Thus we can partially apply the (+) function.
Recursion and Pattern Matching as an Alternative to List.iter One of the most common ways of acting on lists in functional languages is recursion. Do something on one element of a list, then call the same function with the remaining elements. When you get down to an empty list, return an empty list. This algorithm is easily implemented in O'Caml. The "rec" keyword is needed for any function which is recursive.
Since we're only taking a single argument, and immediately using match on it (we never actually refer to "people" again), we can simplify this to:
|