[OCaml #01]: OCaml starters

You should read this post first.

Last week or so I thought I would start to learn Perl or Lua, but I discovered OCaml…and then my focus instantly shifted into it. I’m not really sure what I’ll do about the language, but for now I’m studying it a little bit, so I’ll post here a few notes about it.

Note: this post is likely to be updated as I progress through the language; alternatively, a new post might be created, or I can abandon this thing altogether (yeah, this happens).

So…

  • To get an interpreter: ocaml
    • Now enter valid OCaml expressions, and finish them with ;;
    • You can enter more than one expression at a time, e.g.
    let x = 1
    let y = 2
    ;;
    • Equivalently, you can write a script.ml file and enter these same commands, then enter into the interpreter and type:
      #use "script.ml";;
  • Alternatively, you can compile this script with ocamlc. This will create three files: an executable (a.out by default), a.cmi (interface) and a.cmo (object file).
  • To run an OCaml executable, use ocamlrun.
  • Up to here, this is very similar to haskell: ghc, ghci, and runhaskell.
  • Pattern matching is very easy overall (as with haskell)
  • let isvowel c = 
        match c with
            'a' | 'e' | 'i' | 'o' | 'u' -> true
            | _ -> false;;
  • However, I find P.M. more explicit with OCaml. Haskell uses function overloading to implement pattern matching (at least in the syntax level), while OCaml uses a switch-like statement to do that. Well, actually haskell desugars function overloading to a ‘case’ expression behind the scenes, which is very similar to OCaml’s match, but hey…it is just slightly easier to read the OCaml syntax.
  • You can use _ to match anything.
  • You can also use _ to ignore what is not relevant to you in a match, e.g. when matching tuples:
  • let fst (x, _) = x;;
    let snd (_, y) = y;;
  • You can match character ranges, e.g. ‘A’..’Z’.
  • Two bindings are available: let and let rec. The last one is used to define recursive functions, and they are fundamentally the same; the difference lies in scoping rules (e.g., when using let … in). Example of let rec:
  • let rec factorial n = 
        if (n < 0) then failwith "negative factorial!"
        else if (n = 0) then 1
        else n * factorial (n-1);;
  • OCaml from the very beginning is a super nice intro book to the language. I gave it a 5/5 on Goodreads.
  • Examples from the book: in this user repository.
  • Logical operators are not exactly what you expect regarding equality: = and <>. Yeah, not ==. Annoying, huh?
  • true and false are written in lowercase. Different from python, equal to ruby. Why are programming languages so different? At least, if you write it wrong, you are prompted with a nice message:
  • Error: Unbound constructor True
    Hint: Did you mean true?
  • Speaking of messages, error messages from OCaml are veeeeeery good. It looks like its creators know how to actually communicate with other humans (gcc, this is a subtle sarcasm directed to you!). Want to see an example? I’ll give you one about a warning:
  • let f l = 
        match l with
        [] -> True;;
    
    (* Response: (yeah, this is a comment!)
    
    Warning 8: this pattern-matching is not exhaustive.
    Here is an example of a value that is not matched:
    _::_
    val f : 'a list -> bool = <fun>
    
    *)
  • Naming convention when deconstructing lists: h::t. This means head and tail. In haskell, we usually use x:xs.
  • Oh yeah, haskell is : while OCaml is :: while in the lisp family of languages this is cons.
  • And the append/concatenate operator is @. In haskell it is ++, in python it is +.
  • Yeah, I keep comparing OCaml with other languages because I find it easier to understand it this way.
  • A list in OCaml is a single linked list behind the scenes. So the :: operator only acts on one side of the list…you’re screwed if you want the other one — alternatively, revert the list or use a better data structure.
  • Speaking about lists….[1;2;3;4] not [1,2,3,4]. The last style is from Python / Haskell / Ruby.
  • Package manager? Yeah! opam. This should be analogous to RubyGems and Haskell’s Cabal or node’s npm. opam install, opam remove, opam search…I keep writing it opan, for some reason.
  • love this feature: every function in OCaml has only one parameter. Native currying (aka partial application) FTW! Like haskell.
  • The compiler is pretty smart about inferring types, but annotations can be made too:
  • let sum10 (x:int):int = x + 10;;
  • Anonymous functions:
  • fun x -> 2 * x
    
    (* example of use with map: *)
    map (fun x -> 2 * x) [1; 2; 3] (* yields [2; 4; 6] *)
  • Just comparing with haskell, which is slightly smaller:
  • map (\x -> 2 * x) [1..3]
    
    -- or, better yet
    map (* 2) [1..3]
  • Actually, it is possible to use something such as (+) or (<=) in OCaml. But…not (*). This is confused with a comment. Maybe there is a way of escaping this. Edit: yeah, we just have to insert spaces: ( * ).

I guess I’m stopping here for now. This includes up to chapter 6 of the aforementioned book, plus a few random sources on the web.

Advertisements
[OCaml #01]: OCaml starters

Functional languages, brainstorming all over again

Context

Historically, I love functional languages. The first family I was introduced to were the lispy ones; more specifically, emacs lisp, then racket, then clojure.

Emacs Lisp is very powerful for its purpose, and I believe the only reason people still use emacs today is because of the power of elisp. Emacs is very extendable and this is not a coincidence: functional languages are very expressive.

Racket was taught to me in a coursera course which intended to teach functional languages and how to design programs with them. It is very cool and nice for beginners, but after learning the basics of FP I don’t see much space for it.

Clojure is lisp for web programming and development. I believe it is the most suitable and useful functional language to learn today (from the lisp family, I mean).

Then we go away from the lisp family; the first most notable language out there that remains now is Haskell. Haskell is very peculiar and is what is called a “pure” functional language, which means that the FP paradigm is forced; there are no imperative ways to do anything with it (well, except after you learn about monads).

While I loved to learn Haskell and discovered it has a huge ecosystem, I don’t think it is the most practical functional language to use today. So…what do we do?

And now,

I then paused my functional programming research/learning for a while, until… I discovered about OCaml. It seems to have a good compromise between the functional and imperative paradigms, but it is functional by nature (but not pure). I am now reading OCaml from the very beginning. It is a very good introdutory book and it is making me like OCaml.

I’ll now see if I will like OCaml more than Haskell. And, more important yet: if it is practical to use in the day to day.

An example — sum of a list:

let rec sum l = 
  match l with
    [] -> 0
  | h::t -> h + sum(t)
Functional languages, brainstorming all over again