From 55c269cc3c6a5678bbff3effc587edb7a1cd6e8a Mon Sep 17 00:00:00 2001 From: Daniil Baturin Date: Fri, 12 Sep 2014 18:39:15 +0700 Subject: [PATCH 1/8] F# is also related to the ML family. --- ocaml.html.markdown | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/ocaml.html.markdown b/ocaml.html.markdown index 7f4e0a9d..8638a291 100644 --- a/ocaml.html.markdown +++ b/ocaml.html.markdown @@ -8,8 +8,10 @@ OCaml is a strictly evaluated functional language with some imperative features. Along with StandardML and its dialects it belongs to ML language family. -Just like StandardML, there are both a compiler and an interpreter -for OCaml. The interpreter binary is normally called "ocaml" and +F# is also heavily influenced by OCaml. + +Just like StandardML, OCaml features both an interpreter that can be +used interactively and a compiler. The interpreter binary is normally called "ocaml" and the compiler is "ocamlopt". There is also a bytecode compiler, "ocamlc", but there are few reasons to use it. From d9110cf7bc8a3dcf84207ea509340dbae868a44a Mon Sep 17 00:00:00 2001 From: Daniil Baturin Date: Fri, 12 Sep 2014 19:34:50 +0700 Subject: [PATCH 2/8] An overly simplified explanation of currying in OCaml tutorial. --- ocaml.html.markdown | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/ocaml.html.markdown b/ocaml.html.markdown index 8638a291..fd5b9b2e 100644 --- a/ocaml.html.markdown +++ b/ocaml.html.markdown @@ -31,7 +31,7 @@ val a : int = 99 ``` For a source file you can use "ocamlc -i /path/to/file.ml" command -to print all names and signatures. +to print all names and type signatures. ``` $ cat sigtest.ml @@ -47,7 +47,13 @@ val a : int ``` Note that type signatures of functions of multiple arguments are -written in curried form. +written in curried form. A function that takes multiple arguments can be +represented as a composition of functions that take only one argument. +The "f(x,y) = x + y" function from the example above applied to +arguments 2 and 3 is equivalent to the "f0(y) = 2 + y" function applied to 3. +Hence the "int -> int -> int" signature, which can be read as +"(int -> int) -> int". + ```ocaml (*** Comments ***) From 962d58d013fa245c6b61863d2d14420c4c563743 Mon Sep 17 00:00:00 2001 From: Daniil Baturin Date: Fri, 12 Sep 2014 19:35:56 +0700 Subject: [PATCH 3/8] Remove stray argument from the alternative matching syntax in OCaml tutorial. It wouldn't cause a syntax error, but wouldn't give intended result either. --- ocaml.html.markdown | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ocaml.html.markdown b/ocaml.html.markdown index fd5b9b2e..1732f7be 100644 --- a/ocaml.html.markdown +++ b/ocaml.html.markdown @@ -297,7 +297,7 @@ let is_zero x = ;; (* Alternatively, you can use the "function" keyword. *) -let is_one x = function +let is_one = function | 1 -> true | _ -> false ;; From 3995be4f4bf518e2c3436632ec100c14bb47bda1 Mon Sep 17 00:00:00 2001 From: Daniil Baturin Date: Fri, 12 Sep 2014 19:42:50 +0700 Subject: [PATCH 4/8] Break some long lines in OCaml tutorial to avoid horizontal scrolling. --- ocaml.html.markdown | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/ocaml.html.markdown b/ocaml.html.markdown index 1732f7be..41bc4ff2 100644 --- a/ocaml.html.markdown +++ b/ocaml.html.markdown @@ -81,7 +81,8 @@ let foo = 1 ;; let foo' = foo * 2 ;; (* Since OCaml compiler infers types automatically, you normally don't need to - specify argument types explicitly. However, you can do it if you want or need to. *) + specify argument types explicitly. However, you can do it if + you want or need to. *) let inc_int (x: int) = x + 1 ;; (* You need to mark recursive function definitions as such with "rec" keyword. *) @@ -285,8 +286,8 @@ let l = Cons (1, EmptyList) ;; languages, but offers a lot more expressive power. Even though it may look complicated, it really boils down to matching - an argument against an exact value, a predicate, or a type constructor. The type system - is what makes it so powerful. *) + an argument against an exact value, a predicate, or a type constructor. + The type system is what makes it so powerful. *) (** Matching exact values. **) @@ -328,8 +329,8 @@ say (Cat "Fluffy") ;; (* "Fluffy says meow". *) (* Recursive types can be traversed with pattern matching easily. Let's see how we can traverse a datastructure of the built-in list type. - Even though the built-in cons ("::") looks like an infix operator, it's actually - a type constructor and can be matched like any other. *) + Even though the built-in cons ("::") looks like an infix operator, + it's actually a type constructor and can be matched like any other. *) let rec sum_list l = match l with | [] -> 0 From 2d01fb3c0597cfc692e3edfebcfc81bf2e3e3ee9 Mon Sep 17 00:00:00 2001 From: Daniil Baturin Date: Fri, 12 Sep 2014 19:46:41 +0700 Subject: [PATCH 5/8] Minor formatting and punctuation fix in the OCaml tutorial. --- ocaml.html.markdown | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/ocaml.html.markdown b/ocaml.html.markdown index 41bc4ff2..0107fd35 100644 --- a/ocaml.html.markdown +++ b/ocaml.html.markdown @@ -10,10 +10,10 @@ features. Along with StandardML and its dialects it belongs to ML language family. F# is also heavily influenced by OCaml. -Just like StandardML, OCaml features both an interpreter that can be -used interactively and a compiler. The interpreter binary is normally called "ocaml" and -the compiler is "ocamlopt". There is also a bytecode compiler, "ocamlc", -but there are few reasons to use it. +Just like StandardML, OCaml features both an interpreter, that can be +used interactively, and a compiler. +The interpreter binary is normally called "ocaml" and the compiler is "ocamlopt". +There is also a bytecode compiler, "ocamlc", but there are few reasons to use it. It is strongly and statically typed, but instead of using manually written type annotations, it infers types of expressions using Hindley-Milner algorithm. From 166fb997a0793067b7aa09091a1c9f76229ea6de Mon Sep 17 00:00:00 2001 From: Daniil Baturin Date: Sat, 13 Sep 2014 00:36:15 +0700 Subject: [PATCH 6/8] Remove the signature explanation by grouping to avoid confusion with signature syntax for function types. --- ocaml.html.markdown | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/ocaml.html.markdown b/ocaml.html.markdown index 0107fd35..5be9510b 100644 --- a/ocaml.html.markdown +++ b/ocaml.html.markdown @@ -51,8 +51,7 @@ written in curried form. A function that takes multiple arguments can be represented as a composition of functions that take only one argument. The "f(x,y) = x + y" function from the example above applied to arguments 2 and 3 is equivalent to the "f0(y) = 2 + y" function applied to 3. -Hence the "int -> int -> int" signature, which can be read as -"(int -> int) -> int". +Hence the "int -> int -> int" signature. ```ocaml From 807a958c78c44a83172724766d446eadb24f8cc5 Mon Sep 17 00:00:00 2001 From: Daniil Baturin Date: Sat, 13 Sep 2014 00:46:46 +0700 Subject: [PATCH 7/8] Some information about the need for type annotations in OCaml tutorial. --- ocaml.html.markdown | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/ocaml.html.markdown b/ocaml.html.markdown index 5be9510b..bb9a1a75 100644 --- a/ocaml.html.markdown +++ b/ocaml.html.markdown @@ -82,7 +82,13 @@ let foo' = foo * 2 ;; (* Since OCaml compiler infers types automatically, you normally don't need to specify argument types explicitly. However, you can do it if you want or need to. *) -let inc_int (x: int) = x + 1 ;; +let inc_int (x: int) : int = x + 1 ;; + +(* One of the cases when explicit type annotations may be needed is + resolving ambiguity between two record types that have fields with + the same name. The alternative is to encapsulate those types in + modules, but both topics are a bit out of scope of this + tutorial. *) (* You need to mark recursive function definitions as such with "rec" keyword. *) let rec factorial n = From 5cf408a7a9f0d72f40dadd95d81430f35dee3a1e Mon Sep 17 00:00:00 2001 From: Daniil Baturin Date: Sat, 13 Sep 2014 00:54:23 +0700 Subject: [PATCH 8/8] Add anonymous functions and list map/filter sections to the OCaml tutorial. --- ocaml.html.markdown | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/ocaml.html.markdown b/ocaml.html.markdown index bb9a1a75..b9505f13 100644 --- a/ocaml.html.markdown +++ b/ocaml.html.markdown @@ -150,6 +150,8 @@ x + y ;; works for non-recursive definitions too. *) let a = 3 and b = 4 in a * b ;; +(* Anonymous functions use the following syntax: *) +let my_lambda = fun x -> x * x ;; (*** Operators ***) @@ -207,6 +209,10 @@ let bad_list = [1, 2] ;; (* Becomes [(1, 2)] *) (* You can access individual list items with the List.nth function. *) List.nth my_list 1 ;; +(* There are higher-order functions for lists such as map and filter. *) +List.map (fun x -> x * 2) [1; 2; 3] ;; +List.filter (fun x -> if x mod 2 = 0 then true else false) [1; 2; 3; 4] ;; + (* You can add an item to the beginning of a list with the "::" constructor often referred to as "cons". *) 1 :: [2; 3] ;; (* Gives [1; 2; 3] *)