From 02bc5183512e1548bfb3a54bacc85443dc33f86d Mon Sep 17 00:00:00 2001 From: James Baker Date: Sun, 26 Apr 2015 09:59:15 +0100 Subject: Standard ML has references Standard ML is not a pure language and has imperative structures like references while and seq --- standard-ml.html.markdown | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'standard-ml.html.markdown') diff --git a/standard-ml.html.markdown b/standard-ml.html.markdown index b545f3e1..cc5132f1 100644 --- a/standard-ml.html.markdown +++ b/standard-ml.html.markdown @@ -8,8 +8,8 @@ contributors: Standard ML is a functional programming language with type inference and some side-effects. Some of the hard parts of learning Standard ML are: Recursion, pattern matching, type inference (guessing the right types but never allowing -implicit type conversion). If you have an imperative background, not being able -to update variables can feel severely inhibiting. +implicit type conversion). Standard ML is distinguished from Haskell by including +references, allowing variables to be updated. ```ocaml (* Comments in Standard ML begin with (* and end with *). Comments can be -- cgit v1.2.3 From f8260574d9a29d5302dccf8fb883d5e3d60592d0 Mon Sep 17 00:00:00 2001 From: James Baker Date: Sun, 26 Apr 2015 10:00:21 +0100 Subject: Add examples of imperative-style control Make reference and update, add use of a while and use of seq --- standard-ml.html.markdown | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) (limited to 'standard-ml.html.markdown') diff --git a/standard-ml.html.markdown b/standard-ml.html.markdown index cc5132f1..8fc849cb 100644 --- a/standard-ml.html.markdown +++ b/standard-ml.html.markdown @@ -383,6 +383,25 @@ val test_poem = readPoem "roses.txt" (* gives [ "Roses are red,", "Violets are blue.", "I have a gun.", "Get in the van." ] *) + +(* We can create references to data which can be updated *) +val counter = ref 0 (* Produce a reference with the ref function *) + +(* Assign to a reference with the assignment operator *) +fun set_five reference = reference := 5 + +(* Read a reference with the dereference operator *) +fun equals_five reference = !reference = 5 + +(* We can use while loops for when recursion is messy *) +fun decrement_to_zero r = if !r < 0 + then r := 0 + else while !r >= 0 do r := !r - 1 + +(* This returns the unit value (in practical terms, nothing, a 0-tuple) *) + +(* To allow returning a value, we can use the semicolon to sequence evaluations *) +fun decrement_ret x y = (x := !x - 1; y) ``` ## Further learning -- cgit v1.2.3 From 183ca56459828f567457337204c7ef10351a31f0 Mon Sep 17 00:00:00 2001 From: James Baker Date: Sun, 26 Apr 2015 10:01:36 +0100 Subject: Add myself as a contributor --- standard-ml.html.markdown | 1 + 1 file changed, 1 insertion(+) (limited to 'standard-ml.html.markdown') diff --git a/standard-ml.html.markdown b/standard-ml.html.markdown index 8fc849cb..07896beb 100644 --- a/standard-ml.html.markdown +++ b/standard-ml.html.markdown @@ -3,6 +3,7 @@ language: "Standard ML" contributors: - ["Simon Shine", "http://shine.eu.org/"] - ["David Pedersen", "http://lonelyproton.com/"] + - ["James Baker", "http://www.jbaker.io/"] --- Standard ML is a functional programming language with type inference and some -- cgit v1.2.3 From 152c03ddf9072ed80efef0528968ca132385a2aa Mon Sep 17 00:00:00 2001 From: inaimathi Date: Sat, 6 Jun 2015 12:51:45 -0400 Subject: Add notes about records to Standard ML page. --- standard-ml.html.markdown | 42 ++++++++++++++++++++++++++++++++++++------ 1 file changed, 36 insertions(+), 6 deletions(-) (limited to 'standard-ml.html.markdown') diff --git a/standard-ml.html.markdown b/standard-ml.html.markdown index 07896beb..125183c0 100644 --- a/standard-ml.html.markdown +++ b/standard-ml.html.markdown @@ -4,6 +4,7 @@ contributors: - ["Simon Shine", "http://shine.eu.org/"] - ["David Pedersen", "http://lonelyproton.com/"] - ["James Baker", "http://www.jbaker.io/"] + - ["Leo Zovic", "http://langnostic.inaimathi.ca/"] --- Standard ML is a functional programming language with type inference and some @@ -136,9 +137,29 @@ val mixup = [ ("Alice", 39), val good_bad_stuff = (["ice cream", "hot dogs", "chocolate"], - ["liver", "paying the rent" ]) (* string list * string list *) + ["liver", "paying the rent" ]) (* : string list * string list *) +(* Records are tuples with named slots *) + +val rgb = { r=0.23, g=0.56, b=0.91 } (* : {b:real, g:real, r:real} *) + +(* You don't need to declare their slots ahead of time. Records with + different slot names are considered different types, even if their + slot value types match up. For instance... *) + +val Hsl = { H=310.3, s=0.51, l=0.23 } (* : {H:real, l:real, s:real} *) +val Hsv = { H=310.3, s=0.51, v=0.23 } (* : {H:real, s:real, v:real} *) + +(* ...trying to evaluate `Hsv = Hsl` or `rgb = Hsl` would give a type + error. While they're all three-slot records composed only of `real`s, + they each have different names for at least some slots. *) + +(* You can use hash notation to get values out of tuples. *) + +val H = #H Hsv (* : real *) +val s = #s Hsl (* : real *) + (* Functions! *) fun add_them (a, b) = a + b (* A simple function that adds two numbers *) val test_it = add_them (3, 4) (* gives 7 *) @@ -225,17 +246,26 @@ fun fibonacci 0 = 0 (* Base case *) | fibonacci 1 = 1 (* Base case *) | fibonacci n = fibonacci (n - 1) + fibonacci (n - 2) (* Recursive case *) -(* Pattern matching is also possible on composite types like tuples and lists. - Writing "fun solve2 (a, b, c) = ..." is in fact a pattern match on the one - three-tuple solve2 takes as argument. Similarly, but less intuitively, you - can match on a list consisting of elements in it (from the beginning of the - list only). *) +(* Pattern matching is also possible on composite types like tuples, lists and + records. Writing "fun solve2 (a, b, c) = ..." is in fact a pattern match on + the one three-tuple solve2 takes as argument. Similarly, but less intuitively, + you can match on a list consisting of elements in it (from the beginning of + the list only). *) fun first_elem (x::xs) = x fun second_elem (x::y::xs) = y fun evenly_positioned_elems (odd::even::xs) = even::evenly_positioned_elems xs | evenly_positioned_elems [odd] = [] (* Base case: throw away *) | evenly_positioned_elems [] = [] (* Base case *) +(* When matching on records, you must use their slot names, and you must bind + every slot in a record. The order of the slots doesn't matter though. *) + +fun rgbToTup {r, g, b} = (r, g, b) (* fn : {b:'a, g:'b, r:'c} -> 'c * 'b * 'a *) +fun mixRgbToTup {g, b, r} = (r, g, b) (* fn : {b:'a, g:'b, r:'c} -> 'c * 'b * 'a *) + +(* If called with {r=0.1, g=0.2, b=0.3}, either of the above functions + would return (0.1, 0.2, 0.3). But it would be a type error to call them + with {r=0.1, g=0.2, b=0.3, a=0.4} *) (* Higher order functions: Functions can take other functions as arguments. Functions are just other kinds of values, and functions don't need names -- cgit v1.2.3 From 21c3187f11cbb9926959af23d76743718e96d77b Mon Sep 17 00:00:00 2001 From: inaimathi Date: Sat, 6 Jun 2015 12:53:33 -0400 Subject: Fix indentation --- standard-ml.html.markdown | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'standard-ml.html.markdown') diff --git a/standard-ml.html.markdown b/standard-ml.html.markdown index 125183c0..143980e7 100644 --- a/standard-ml.html.markdown +++ b/standard-ml.html.markdown @@ -4,7 +4,7 @@ contributors: - ["Simon Shine", "http://shine.eu.org/"] - ["David Pedersen", "http://lonelyproton.com/"] - ["James Baker", "http://www.jbaker.io/"] - - ["Leo Zovic", "http://langnostic.inaimathi.ca/"] + - ["Leo Zovic", "http://langnostic.inaimathi.ca/"] --- Standard ML is a functional programming language with type inference and some -- cgit v1.2.3