diff --git a/markup/ml b/markup/ml index 56e7863..006d3e0 100644 --- a/markup/ml +++ b/markup/ml @@ -2,14 +2,14 @@ [#grammar-invocation grammar and invocation] | [#var-expr variables and expressions] | [#arithmetic-logic arithmetic and logic] | [#strings strings] | [#dates-time dates and time] | [#arrays arrays] | [#lists lists] | [#tuples tuples] | [#dictionaries dictionaries] | [#functions functions] | [#execution-control execution control] | [#exceptions exceptions] | [#concurrency concurrency] | [#file-handles file handles] | [#files files] | [#directories directories] | [#processes-environment processes and environment] | [#libraries-namespaces libraries and namespaces] | [#user-defined-types user-defined types] | [#objects objects] | [#inheritance-polymorphism inheritance and polymorphism] | [#net-web net and web] | [#unit-tests unit tests] | [#debugging-profiling debugging and profiling] | [#repl repl] -||~ ||~ [#sml sml]||~ [#ocaml ocaml]||~ [#fsharp f#]||~ [#haskell haskell]|| +||~ ||~ [#sml sml]||~ [#ocaml ocaml]||~ [#fsharp f#]||~ [#haskell haskell]||~ [#loon loon]|| ||[[# version-used]][#version-used-note version used] _ @< >@||##gray|//SML NJ 110//##||##gray|//4.0//##||##gray|//F# 3.0//## _ -##gray|//Mono 3.2//##||##gray|//7.4//##|| +##gray|//Mono 3.2//##||##gray|//7.4//##||##gray|//Loon 0.6//##|| ||[[# version]][#version-note show version] _ -@< >@||##gray|//displayed at startup//##||$ ocaml -version||$ fsharpi @@--@@help||$ ghc @@--@@version|| -||||||||||~ [[# grammar-invocation]][#grammar-invocation-note grammar and invocation]|| -||~ ||~ sml||~ ocaml||~ f#||~ haskell|| +@< >@||##gray|//displayed at startup//##||$ ocaml -version||$ fsharpi @@--@@help||$ ghc @@--@@version||$ loon @@--@@version|| +||||||||||||~ [[# grammar-invocation]][#grammar-invocation-note grammar and invocation]|| +||~ ||~ sml||~ ocaml||~ f#||~ haskell||~ loon|| ||[[# interpreter]][#interpreter-note interpreter] _ @< >@|| ||$ echo 'print_endline "hello"' > hello.ml _ _ @@ -20,7 +20,8 @@ EOF _ _ $ fsharpi @@--@@quiet @@--@@exec hello.fs||$ echo 'main = putStrLn "hello"' > hello.hs _ _ -$ runghc hello.hs|| +$ runghc hello.hs||$ echo '[fn main [] [println "hello"]]' > hello.oo _ +$ loon run hello.oo|| ||[[# shebang]][#shebang-note shebang]|| ||$ cat @@<<@@EOF > hello.ml _ #!/usr/bin/env ocaml _ _ @@ -46,67 +47,70 @@ main = putStrLn "hello" _ EOF _ _ $ chmod +x hello.hs _ -$ ./hello.hs|| +$ ./hello.hs||##gray|//none//##|| ||[[# bytecode-compiler-interpreter]][#bytecode-compiler-interpreter-note bytecode compiler and interpreter]|| ||$ echo 'print_endline "hello";;' > hello.ml _ $ ocamlc -o hello hello.ml _ $ ocamlrun hello||$ echo 'printfn "hello"' > hello.fs _ $ fsharpc hello.fs _ -$ mono hello.exe||##gray|//none//##|| +$ mono hello.exe||##gray|//none//##||##gray|//none//##|| ||[[# native-compiler]][#native-compiler-note native compiler]|| ||$ echo 'print_endline "hello";;' > hello.ml _ $ ocamlopt hello.ml -o hello _ $ ./hello||##gray|//none//##||$ echo 'main = putStrLn "hello"' > hello.hs _ $ ghc -o hello hello.hs _ -$ ./hello|| -||[[# library-always-imported]][#library-always-imported-note library which is always imported]|| ||Pervasives||Core||Prelude|| -||[[# statement-terminator]][#statement-terminator-note statement terminator]||;||;;||;;||##gray|//next line has equal or less indentation, or//## ;|| +$ ./hello||##gray|//compiles to WASM://## _ +$ loon build hello.oo|| +||[[# library-always-imported]][#library-always-imported-note library which is always imported]|| ||Pervasives||Core||Prelude||##gray|//prelude (builtins, IO, Fail)//##|| +||[[# statement-terminator]][#statement-terminator-note statement terminator]||;||;;||;;||##gray|//next line has equal or less indentation, or//## ;||##gray|//none; expression-based//##|| ||[[# blocks]][#blocks-note blocks]||( ##gray|//expr//## ; ##gray|//…//## )||( ##gray|//expr//## ; ##gray|//...//## ) _ begin ##gray|//expr//## ; ##gray|//...//## end||( ##gray|//expr//## ; ##gray|//...//## ) _ -begin ##gray|//expr//## ; ##gray|//...//## end||##gray|//offside rule or//## { }|| -||[[# end-of-line-comment]][#end-of-line-comment-note end-of-line comment]||##gray|//none//##||##gray|//none//##||@@//@@ ##gray|//comment//##||@@--@@ ##gray|//comment//##|| +begin ##gray|//expr//## ; ##gray|//...//## end||##gray|//offside rule or//## { }||[do ##gray|//expr//## ##gray|//...//##]|| +||[[# end-of-line-comment]][#end-of-line-comment-note end-of-line comment]||##gray|//none//##||##gray|//none//##||@@//@@ ##gray|//comment//##||@@--@@ ##gray|//comment//##||; ##gray|//comment//##|| ||[[# multiple-line-comment]][#multiple-line-comment-note multiple line comment]||(* ##gray|//comment//## _ ##gray|//another comment//## *)||(* ##gray|//comment _ another comment//## *)||(* ##gray|//comment _ another comment//## *)||{- ##gray|//comment _ -another comment//## -}|| -||||||||||~ [[# var-expr]][#var-expr-note variables and expressions]|| -||~ ||~ sml||~ ocaml||~ f#||~ haskell|| +another comment//## -}||##gray|//none//##|| +||||||||||||~ [[# var-expr]][#var-expr-note variables and expressions]|| +||~ ||~ sml||~ ocaml||~ f#||~ haskell||~ loon|| ||[[# value]][#value-note write-once variable] _ -@< >@||val a = 3;||let n = 1 + 2;;||let n = 1 + 2||n = 3|| +@< >@||val a = 3;||let n = 1 + 2;;||let n = 1 + 2||n = 3||[let n [+ 1 2]]|| ||[[# variable]][#variable-note modifiable variable]||val a = ref 3; _ a := 4; _ !a + 7;||let n = ref 3;; _ n := 4;; _ !n + 7;;||let n = ref 3 _ n := 4 _ -!n + 7||n <- return 3|| +!n + 7||n <- return 3||[let mut n 3] _ +[set! n 4]|| ||[[# unit]][#unit-note unit type and value]||unit _ ()||unit _ ()||unit _ ()||() _ -()|| +()||##gray|//type//## () ##gray|//; value//## ()|| ||[[# conditional-expression]][#conditional-expression-note conditional expression]||val x = 3; _ if x < 0 then ~x else x;||let n = -3;; _ let absn = if n < 0 then -n else n;;||let n = -3 _ let absn = if n < 0 then -n else n||n = -3 _ -let absn = if n < 0 then -n else n|| +let absn = if n < 0 then -n else n||[if [> x 0] "pos" "neg"]|| ||[[# branch-type-mismatch]][#branch-type-mismatch-note branch type mismatch]||##gray|(* compilation error: *)## _ if true then "hello" else 3;||##gray|(* compilation error: *)## _ if true then "hello" else 3;;||##gray|(* compilation error: *)## _ if true then "hello" else 3||##gray|@@--@@ compilation error:## _ -if True then "hello" else 3|| +if True then "hello" else 3||##gray|//compile error (type)//##|| ||[[# null]][#null-note null] _ @< >@||NONE||None||None _ _ ##gray|//Also this value returned by .NET library functions. It has a type distinct from// None:## _ -null||Nothing|| +null||Nothing||##gray|//none//##|| ||[[# nullable-type]][#nullable-type-note nullable type]||type list_option_int = int option list; _ _ val list = [SOME 3,NONE, SOME ~4];||type list_option_int = int option list;; _ _ -let list = [Some 3; None; Some (-4)];;|| ||list = [Just(3), Nothing, Just(-4)]|| +let list = [Some 3; None; Some (-4)];;|| ||list = [Just(3), Nothing, Just(-4)]||[type Option [Some a] None] _ +##gray|//then://## [Some 3] ##gray|//or//## None|| ||[[# null-test]][#null-test-note null test]|| ||match foo with _ @<  >@| None -> true _ -@<  >@| _ -> false;;|| || || +@<  >@| _ -> false;;|| || ||[match o [Some v] true None false]|| ||[[# coalesce]][#coalesce-note coalesce]||val foo = SOME 3; _ _ ##gray|(* raises exception if NONE: *)## _ @@ -123,11 +127,11 @@ fromJust foo _ _ let intId x = x _ ##gray|//evaluates to 0 if Nothing://## _ -maybe 0 intId foo|| +maybe 0 intId foo||[get m :key dflt]|| ||[[# nullif]][#nullif-note nullif]|| ||match foo with _ @<  >@| -999 -> None _ -@<  >@| n -> Some n;;|| || || -||[[# expr-type-declaration]][#expr-type-decl-note expression type declaration]|| ||float 1||float 1||1 :: Double|| +@<  >@| n -> Some n;;|| || ||[if [= a b] None [Some a]]|| +||[[# expr-type-declaration]][#expr-type-decl-note expression type declaration]|| ||float 1||float 1||1 :: Double||[sig n : Int] ##gray|//; on bindings//##|| ||[[# let-in]][#let-in-note let ... in ...]||val z = _ let _ @<  >@val x = 3.0 _ @@ -142,29 +146,30 @@ end;||let z = _ @<  >@let y = 2.0 * x in _ @<  >@x * y||z = let x = 3.0 _ @<  >@@<  >@@<  >@@<  >@y = 2.0 * x _ -@<  >@@<  >@in x * y|| +@<  >@@<  >@in x * y||[do [let n 3] [* n n]]|| ||[[# where]][#where-note where]||##gray|//none//##||##gray|//none//##||##gray|//none//##||z = x * y _ @<  >@where x = 3.0 _ -@<  >@@<  >@@<  >@@<  >@y = 2.0 * x|| -||||||||||~ [[# arithmetic-logic]][#arithmetic-logic-note arithmetic and logic]|| -||~ ||~ sml||~ ocaml||~ f#||~ haskell|| +@<  >@@<  >@@<  >@@<  >@y = 2.0 * x||##gray|//none//##|| +||||||||||||~ [[# arithmetic-logic]][#arithmetic-logic-note arithmetic and logic]|| +||~ ||~ sml||~ ocaml||~ f#||~ haskell||~ loon|| ||[[# boolean-type]][#boolean-type-note boolean type] _ -@< >@||bool||bool||bool||Bool|| +@< >@||bool||bool||bool||Bool||Bool|| ||[[# true-false]][#true-false-note true and false] _ -@< >@||true false||true false||true false||True False|| -||[[# logical-op]][#logical-op-note logical operators]||andalso orelse not||&& @@||@@ not||&& @@||@@ not||&& @@||@@ not|| -||[[# relational-op]][#relational-op-note relational operators]||@@=@@ <> < > <= >=||@@=@@ <> < > <= >=||@@=@@ <> < > <= >=||== /= < > <= >=|| +@< >@||true false||true false||true false||True False||true false|| +||[[# logical-op]][#logical-op-note logical operators]||andalso orelse not||&& @@||@@ not||&& @@||@@ not||&& @@||@@ not||[and a b] [or a b] [not a] _ +##gray|//eager, not short-circuiting//##|| +||[[# relational-op]][#relational-op-note relational operators]||@@=@@ <> < > <= >=||@@=@@ <> < > <= >=||@@=@@ <> < > <= >=||== /= < > <= >=||= != < > <= >=|| ||[[# min-max]][#min-max-note min and max]|| ||min 1 2 _ max 1 2||min 1 2 _ max 1 2||min 1 2 _ -max 1 2|| +max 1 2||##gray|//of a collection://## [min xs] [max xs]|| ||[[# int-type]][#int-type-note integer type]||int||int _ _ ##gray|//other integer types://## _ int32 int64 nativeint||int _ _ ##gray|//other integer types://## _ -int32 int64 nativeint||Integer|| +int32 int64 nativeint||Integer||Int ##gray|//; 64-bit signed//##|| ||[[# int-literal]][#int-literal-note integer literal]||##gray|negative integer://## _ ~4||##gray|int, int64, and nativeint literals:## _ 12 12L 12n _ @@ -174,33 +179,34 @@ int32 int64 nativeint||Integer|| _ ##gray|//this parses as an expression://## _ -4||-4||##gray|//an expression, not a literal://## _ --4|| -||[[# float-type]][#float-type-note float type]||real||float||float||Double|| +-4||7|| +||[[# float-type]][#float-type-note float type]||real||float||float||Double||Float ##gray|//; 64-bit//##|| ||[[# int-op]][#int-op-note integer operators]||+ - * div mod||+ - * / mod _ ##gray|mod //is an infix operator//##||+ - * / %||+ - * div rem _ -##gray|div //and// rem //are functions, not infix operators//##|| +##gray|div //and// rem //are functions, not infix operators//##||+ - * / %|| ||[[# float-op]][#float-op-note float operators] _ -@< >@||+ - * /||+. -. *. /.||@@+@@ - * /||+ - * /|| -||[[# add-int-float]][#add-int-float-note add integer and float]||real 3 + 7.0;||float 3 +. 7.0||float 3 + 7.0||3 + 7.0|| +@< >@||+ - * /||+. -. *. /.||@@+@@ - * /||+ - * /||+ - * /|| +||[[# add-int-float]][#add-int-float-note add integer and float]||real 3 + 7.0;||float 3 +. 7.0||float 3 + 7.0||3 + 7.0||[+ [float 1] 2.0] _ +##gray|//no implicit coercion//##|| ||[[# int-div]][#int-div-note integer division] _ ##gray|//and remainder//##||7 div 3 _ 7 mod 3 _ real 7 / real 3||7 / 3 _ 7 mod 3||7 / 3 _ 7 % 3||div 7 3 _ -rem 7 3|| -||[[# int-div-zero]][#int-div-zero-note integer division by zero]|| ||##gray|//raises//## Division_by_zero||System.DivideByZeroException||##gray|//Exception: divide by zero//##|| +rem 7 3||[/ 7 2] ##gray|//; 3//##|| +||[[# int-div-zero]][#int-div-zero-note integer division by zero]|| ||##gray|//raises//## Division_by_zero||System.DivideByZeroException||##gray|//Exception: divide by zero//##||##gray|//runtime error//##|| ||[[# float-div]][#float-div-note float division] _ -@< >@|| ||float 7 /. float 3||float 7 / float 3||7 / 3|| -||[[# float-div-zero]][#float-div-zero-note float division by zero]|| ||infinity nan ##gray|//or//## neg_infinity||infinity nan ##gray|//or//## neg_infinity||##gray|//evaluates to// Infinity, NaN, //or// -Infinity, //values which do not have literals//##|| +@< >@|| ||float 7 /. float 3||float 7 / float 3||7 / 3||[/ 7.0 2.0] ##gray|//; 3.5//##|| +||[[# float-div-zero]][#float-div-zero-note float division by zero]|| ||infinity nan ##gray|//or//## neg_infinity||infinity nan ##gray|//or//## neg_infinity||##gray|//evaluates to// Infinity, NaN, //or// -Infinity, //values which do not have literals//##||[/ 1.0 0.0] ##gray|//; inf//##|| ||[[# power]][#power-note power]||Math.pow (2.0, 32.0);||2.0 ** 32.0||2.0 ** 32.0||2 ** 32 _ _ ##gray|@@--@@ syntax error if exponent not an integer:## _ -2 ^ 32|| +2 ^ 32||##gray|//none//##|| ||[[# sqrt]][#sqrt-note sqrt] _ -@< >@||Math.sqrt 2.0||sqrt 2.0||sqrt 2.0||sqrt 2|| +@< >@||Math.sqrt 2.0||sqrt 2.0||sqrt 2.0||sqrt 2||##gray|//none//##|| ||[[# sqrt-negative-one]][#sqrt-negative-one-note sqrt -1]||##gray|//Math.sqrt ~1.0 evaluates to// nan##||##gray|sqrt (-1.0):## _ -nan||nan||##gray|sqrt (-1) //evaluates to// NaN, //a value which has no literal//##|| +nan||nan||##gray|sqrt (-1) //evaluates to// NaN, //a value which has no literal//##||##gray|//none//##|| ||[[# transcendental-func]][#transcendental-func-note transcendental functions]||Math.exp Math.ln _ Math.sin Math.cos Math.tan _ Math.asin Math.acos Math.atan _ @@ -213,12 +219,12 @@ asin acos atan _ atan2||exp log _ sin cos tan _ asin acos atan _ -atan2|| +atan2||##gray|//none//##|| ||[[# transcendental-const]][#transcendental-const-note transcendental constants]||Math.pi _ Math.e||4.0 *. atan 1.0 _ exp 1.0||System.Math.PI _ System.Math.E||pi _ -exp 1|| +exp 1||##gray|//none//##|| ||[[# float-truncation]][#float-truncation-note float truncation]||round 3.14 _ trunc 3.14 _ floor 3.14 _ @@ -231,7 +237,7 @@ floor 3.14 ##gray|//returns float//## _ ceil 3.14 ##gray|//returns float//##||truncate 3.14 _ round 3.14 _ floor 3.14 _ -ceiling 3.14|| +ceiling 3.14||[int 3.7] ##gray|//; 3//##|| ||[[# abs-val]][#abs-val-note absolute value] _ ##gray|//and signum//##|| ||abs (-7) _ abs_float (-7.0) _ @@ -239,9 +245,9 @@ abs_float (-7.0) _ abs -7.0 _ sign -7 _ sign -7.0||abs (-7) _ -signum (-7)|| -||[[# int-overflow]][#int-overflow-note integer overflow]||##gray|//Overflow exception//##||##gray|//modular arithmetic//##||##gray|//modular arithmetic//##||##gray|//has arbitrary length integers//##|| -||[[# float-overflow]][#float-overflow-note float overflow]|| ||infinity||infinity||##gray|//evaluates to// Infinity, //a value which has no literal//##|| +signum (-7)||[abs -4]|| +||[[# int-overflow]][#int-overflow-note integer overflow]||##gray|//Overflow exception//##||##gray|//modular arithmetic//##||##gray|//modular arithmetic//##||##gray|//has arbitrary length integers//##||##gray|//returns//## () ##gray|//(no wrap)//##|| +||[[# float-overflow]][#float-overflow-note float overflow]|| ||infinity||infinity||##gray|//evaluates to// Infinity, //a value which has no literal//##||##gray|//inf//##|| ||[[# arbitrary-len-int]][#arbitrary-len-int-note arbitrary length integer]|| ||open Big_int;; _ _ let n = big_int_of_int 7;; _ @@ -249,7 +255,7 @@ let m = big_int_of_int 12;;||##gray|@@//@@ System.Numerics.BigInteger:## _ let n = 7I _ let m = 12I||##gray|@@--@@ Integer is arbitrary length type:## _ let n = 7 _ -let m = 12|| +let m = 12||##gray|//none//##|| ||[[# arbitrary-len-int-op]][#arbitrary-len-int-op-note arbitrary length integer operators]|| ||add_big_int n m _ sub_big_int n m _ mult_big_int n m _ @@ -280,26 +286,26 @@ n == m _ n < m _ n < m _ n <= m _ -n >= m|| -||[[# rational-type]][#rational-type-note rational type]|| || || ||Ratio Integer|| +n >= m||##gray|//none//##|| +||[[# rational-type]][#rational-type-note rational type]|| || || ||Ratio Integer||##gray|//none//##|| ||[[# rational-construction]][#rational-construction-note rational construction]|| || || ||import Data.Ratio _ _ -1 % 7|| +1 % 7||##gray|//none//##|| ||[[# rational-decomposition]][#rational-decomposition-note rational decomposition]|| || || ||import Data.Ratio _ _ numerator (1 % 7) _ -denominator (1 % 7)|| -||[[# complex-type]][#complex-type-note complex type]|| ||Complex.t|| ||Complex Double|| +denominator (1 % 7)||##gray|//none//##|| +||[[# complex-type]][#complex-type-note complex type]|| ||Complex.t|| ||Complex Double||##gray|//none//##|| ||[[# complex-const]][#complex-const-note complex constants]|| ||Complex.zero _ Complex.one _ -Complex.i|| || || +Complex.i|| || ||##gray|//none//##|| ||[[# complex-op]][#complex-op-note complex operators]|| ||Complex.add z w;; _ Complex.sub z w;; _ Complex.mul z w;; _ -Complex.div z w;;|| || || +Complex.div z w;;|| || ||##gray|//none//##|| ||[[# complex-construction]][#complex-construction-note complex construction]|| ||{Complex.re=1.0; Complex.im=2.0}||System.Numerics.Complex(1.0, 2.0)||import Data.Complex _ _ -1 :+ 2.0|| +1 :+ 2.0||##gray|//none//##|| ||[[# complex-decomposition]][#complex-decomposition-note complex decomposition]|| ||let z = {Complex.re=1.0; Complex.im=2.0};; _ _ z.Complex.re;; _ @@ -312,7 +318,7 @@ realPart (1 :+ 2) _ imagPart (1 :+ 2) _ phase (1 :+ 2) _ magnitude (1 :+ 2) _ -conjugate (1 :+ 2)|| +conjugate (1 :+ 2)||##gray|//none//##|| ||[[# random-num]][#random-num-note random number] _ ##gray|//uniform int, uniform float, normal float//##|| ||Random.int 100 _ Random.float 1.0 _ @@ -325,7 +331,7 @@ import System.Random _ _ getStdRandom (randomR (0, 99)) _ getStdRandom (randomR (0.0, 1.0)) _ -##gray|//none//##|| +##gray|//none//##||##gray|//none//##|| ||[[# random-seed]][#random-seed-note random seed] _ ##gray|//set, get, restore//##|| ||Random.init 17;; _ let seed = Random.get_state();; _ @@ -336,7 +342,7 @@ import System.Random _ _ setStdGen $ mkStdGen 17 _ seed <- getStdGen _ -setStdGen seed|| +setStdGen seed||##gray|//none//##|| ||[[# bit-op]][#bit-op-note bit operators]|| ||1 lsl 4 _ 1 lsr 4 _ 1 land 3 _ @@ -357,127 +363,128 @@ shiftR x 4 _ x .&. y _ x .|. y _ xor x y _ -complement x|| +complement x||##gray|//none//##|| ||[[# binary-octal-hex-literals]][#binary-octal-hex-literals-note binary, octal, and hex literals]|| ||0b101010 _ 0o52 _ 0x2a||0b101010 _ 0o52 _ 0x2a||##gray|//none//## _ 052 _ -0x2a|| -||[[# radix]][#radix-note radix]|| || || || || -||||||||||~ [[# strings]][#strings-note strings]|| -||~ ||~ sml||~ ocaml||~ f#||~ haskell|| +0x2a||##gray|//none//##|| +||[[# radix]][#radix-note radix]|| || || || ||##gray|//none//##|| +||||||||||||~ [[# strings]][#strings-note strings]|| +||~ ||~ sml||~ ocaml||~ f#||~ haskell||~ loon|| ||[[# str-type]][#str-type-note string type] _ -@< >@||string||string||string||String|| +@< >@||string||string||string||String||Str|| ||[[# str-literal]][#str-literal-note string literal] _ -@< >@||"Hello, World!"||"Hello, World!"||"Hello, World!"||"Hello, World!"|| -||[[# newline-in-str-literal]][#newline-in-str-literal-note newline in literal]|| ||##gray|//no//##||##gray|//yes//##||##gray|//no//##|| +@< >@||"Hello, World!"||"Hello, World!"||"Hello, World!"||"Hello, World!"||"hello"|| +||[[# newline-in-str-literal]][#newline-in-str-literal-note newline in literal]|| ||##gray|//no//##||##gray|//yes//##||##gray|//no//##||"line1\nline2"|| ||[[# str-esc]][#str-esc-note literal escapes]||\000 \a \b \f \n \r \t \v \040||\b \n \r \t \" \' \\ _ \##gray|//ooo//## \x##gray|//hh//##||\b \n \r\ t \" \' \\ _ \u##gray|//hhhh//## \U##gray|//hhhhhhhh//##||\a \b \f \n \r \t \v \" \& \' \\ _ \o##gray|//o@@...@@//## \##gray|//d@@...@@//## \x##gray|//h@@...@@//## _ _ -##gray|//Octal, decimal, and hex escapes denote Unicode characters and can contain anywhere from 1 to 7 digits. The max values are \o4177777, \1114111, and \x10ffff. The \& escape does not represent a character, but can separate a numeric backslash escape sequence from a following digit.//##|| +##gray|//Octal, decimal, and hex escapes denote Unicode characters and can contain anywhere from 1 to 7 digits. The max values are \o4177777, \1114111, and \x10ffff. The \& escape does not represent a character, but can separate a numeric backslash escape sequence from a following digit.//##||\n \t \" \\|| ||[[# format-str]][#format-str-note format string]|| || ||sprintf "foo %s %d %.2f" "bar" 7 3.1415||import Text.Printf _ _ -printf "foo %s %d %.2f" "bar" 7 3.1415|| +printf "foo %s %d %.2f" "bar" 7 3.1415||"hi {name}, {[+ 1 2]}"|| ||[[# str-concat]][#str-concat-note concatenate] _ -@< >@|| "Hello" ^ ", " ^ "World!"||"Hello" ^ ", " ^ "World!"||"Hello" + ", " + "World!"||"Hello" ++ ", " ++ "World!"|| +@< >@|| "Hello" ^ ", " ^ "World!"||"Hello" ^ ", " ^ "World!"||"Hello" + ", " + "World!"||"Hello" ++ ", " ++ "World!"||[str a b]|| ||[[# str-replicate]][#str-replicate-note replicate] _ -@< >@|| ||String.make 80 '-'||String.replicate 80 "-"||concat ( replicate 80 "-" )|| +@< >@|| ||String.make 80 '-'||String.replicate 80 "-"||concat ( replicate 80 "-" )||##gray|//none//##|| ||[[# translate-case]][#translate-case-note translate case] _ ##gray|//to upper, to lower//##|| ||String.uppercase "hello" _ String.lowercase "HELLO"||"hello".ToUpper() _ "HELLO".ToLower()||import Data.Char _ _ map toUpper "hello" _ -map toLower "HELLO"|| +map toLower "HELLO"||[uppercase s] _ +[lowercase s]|| ||[[# capitalize]][#capitalize-note capitalize] _ -@< >@|| ||String.capitalize "hello"|| || || +@< >@|| ||String.capitalize "hello"|| || ||##gray|//none//##|| ||[[# trim]][#trim-note trim] _ ##gray|//both sides, left, right//##|| ||String.trim " hello "||" hello ".Trim() _ " hello".TrimStart() _ -"hello ".TrimEnd()|| || +"hello ".TrimEnd()|| ||[trim s]|| ||[[# pad]][#pad-note pad] _ ##gray|//on left, on right//##|| || ||"hello".PadLeft(10, ' ') _ -"hello".PadRight(10, ' ')|| || +"hello".PadRight(10, ' ')|| ||##gray|//none//##|| ||[[# num-to-str]][#num-to-str-note number to string]|| ||"two: " ^ string_of_int 2 _ "pi: " ^ float_of_string 3.14||"two: " + string 2 _ "pi: " + string 3.14||"two: " ++ (show 2) _ -"pi: " ++ (show 3.14)|| +"pi: " ++ (show 3.14)||[str 42]|| ||[[# str-to-num]][#str-to-num-note string to number]||Int.toString 3 _ Real.toString 3.14||7 + int_of_string "12" _ 73.9 +. float_of_string ".037"||7 + int "12" _ 73.9 + float ".037||7 + (read "12")::Integer _ 73.9 + (read "0.037")::Double _ -##gray|//raises exception if string doesn't completely parse//##|| +##gray|//raises exception if string doesn't completely parse//##||##gray|//none//##|| ||[[# join]][#join-note join] _ -@< >@|| || ||System.String.Join(" ", ["do"; "re"; "mi"])|| || +@< >@|| || ||System.String.Join(" ", ["do"; "re"; "mi"])|| ||[join ", " xs]|| ||[[# split]][#split-note split] _ -@< >@|| || ||"do re mi".Split(' ')|| || +@< >@|| || ||"do re mi".Split(' ')|| ||[split s ","]|| ||[[# char-type]][#char-type-note character type] _ -@< >@||char||char||char||Char|| -||[[# char-literal]][#char-literal-note character literal]||#"h"||'h'||'h'||'h'|| +@< >@||char||char||char||Char||##gray|//none; single-char Str//##|| +||[[# char-literal]][#char-literal-note character literal]||#"h"||'h'||'h'||'h'||##gray|//none; use//## "a"|| ||[[# str-len]][#str-len-note length] _ -@< >@||size "hello"||String.length "hello"||"hello".Length||length "hello"|| -||[[# index-substr]][#index-substr-note index of substring]|| || ||"hello".IndexOf("hell")|| || -||[[# substr]][#substr-note extract substring]||substring ("hello",0,4)||String.sub "hello" 0 4||"hello".Substring(0, 4)||drop 0 (take 4 "hello")|| -||[[# extract-char]][#extract-char-note extract character]||String.sub ("hello", 0)||"hello".[0]||"hello".[0]||"hello" !! 0|| +@< >@||size "hello"||String.length "hello"||"hello".Length||length "hello"||[len s] ##gray|//; bytes//##|| +||[[# index-substr]][#index-substr-note index of substring]|| || ||"hello".IndexOf("hell")|| ||[index-of s "lo"] ##gray|//; -1 if absent//##|| +||[[# substr]][#substr-note extract substring]||substring ("hello",0,4)||String.sub "hello" 0 4||"hello".Substring(0, 4)||drop 0 (take 4 "hello")||[substring s 1 4]|| +||[[# extract-char]][#extract-char-note extract character]||String.sub ("hello", 0)||"hello".[0]||"hello".[0]||"hello" !! 0||[char-at s 0]|| ||[[# chr-ord]][#chr-ord-note chr and ord]||ord #"a" _ chr 97||Char.code 'a' _ Char.chr 97||int 'a' _ char 97||Char.ord 'a' _ -Char.chr 97|| -||||||||||~ [[# dates-time]][#dates-time-note dates and time]|| -||~ ||~ sml||~ ocaml||~ f#||~ haskell|| -||[[# dates-time-types]][#dates-time-types-note date and time types]|| || || ||ClockTime CalendarTime TimeDiff|| +Char.chr 97||##gray|//none//##|| +||||||||||||~ [[# dates-time]][#dates-time-note dates and time]|| +||~ ||~ sml||~ ocaml||~ f#||~ haskell||~ loon|| +||[[# dates-time-types]][#dates-time-types-note date and time types]|| || || ||ClockTime CalendarTime TimeDiff||##gray|//none//##|| ||[[# current-date-time]][#current-date-time-note current date and time]|| || || ||import Time _ _ -t <- getClockTime|| +t <- getClockTime||##gray|//none//##|| ||[[# current-unix-epoch]][#current-unix-epoch-note current unix epoch]|| ||open Unix;; _ _ ##gray|(* float: *)## _ time();;|| ||import System.Time _ _ -getClockTime @@>>@@= (\(TOD sec _) -> return sec)|| -||||||||||~ [[# arrays]][#arrays-note arrays]|| -||~ ||~ sml||~ ocaml||~ f#||~ haskell|| -||literal|| || || || || -||size|| || || || || -||lookup|| || || || || -||update|| || || || || -||out-of-bounds|| || || || || -||||||||||~ [[# lists]][#lists-note lists]|| -||~ ||~ sml||~ ocaml||~ f#||~ haskell|| -||[[# list-literal]][#list-literal-note literal]||[1, 2, 3]||[1; 2; 3]||[1; 2; 3]||[1, 2, 3]|| +getClockTime @@>>@@= (\(TOD sec _) -> return sec)||##gray|//none//##|| +||||||||||||~ [[# arrays]][#arrays-note arrays]|| +||~ ||~ sml||~ ocaml||~ f#||~ haskell||~ loon|| +||literal|| || || || ||#[1 2 3]|| +||size|| || || || ||[len a]|| +||lookup|| || || || ||[nth a 0]|| +||update|| || || || ||##gray|//none//##|| +||out-of-bounds|| || || || ||[nth a 99] ##gray|//; runtime error//##|| +||||||||||||~ [[# lists]][#lists-note lists]|| +||~ ||~ sml||~ ocaml||~ f#||~ haskell||~ loon|| +||[[# list-literal]][#list-literal-note literal]||[1, 2, 3]||[1; 2; 3]||[1; 2; 3]||[1, 2, 3]||#[1 2 3]|| ||[[# empty-list]][#empty-list-note empty list] _ -@< >@|| ||[]|| ||[]|| +@< >@|| ||[]|| ||[]||#[]|| ||[[# empty-list-test]][#empty-list-test-note empty list test]|| ||let list = [1; 2; 3];; _ _ list == []|| ||let list = [1, 2, 3] _ _ list == [] _ -null list|| +null list||[empty? xs]|| ||[[# cons]][#cons-note cons] _ -@< >@||1 :: [2, 3]||1 :: [2; 3]||1 :: [2; 3]||1 : [2, 3]|| +@< >@||1 :: [2, 3]||1 :: [2; 3]||1 :: [2; 3]||1 : [2, 3]||[cons 0 xs]|| ||[[# head]][#head-note head] _ -@< >@||List.hd [1, 2, 3]||List.hd [1; 2; 3]||List.head [1; 2; 3]||head [1, 2, 3]|| +@< >@||List.hd [1, 2, 3]||List.hd [1; 2; 3]||List.head [1; 2; 3]||head [1, 2, 3]||[first xs]|| ||[[# tail]][#tail-note tail] _ -@< >@||List.tl [1, 2, 3]||List.tl [1; 2; 3]||List.tail [1; 2; 3]||tail [1, 2, 3]|| -||[[# head-tail-empty-list]][#head-tail-empty-list-note head and tail of empty list]|| ||##gray|//exceptions//##|| ||##gray|//exceptions//##|| +@< >@||List.tl [1, 2, 3]||List.tl [1; 2; 3]||List.tail [1; 2; 3]||tail [1, 2, 3]||[drop 1 xs]|| +||[[# head-tail-empty-list]][#head-tail-empty-list-note head and tail of empty list]|| ||##gray|//exceptions//##|| ||##gray|//exceptions//##||[first #[]] ##gray|//; ()//##|| ||[[# list-length]][#list-length-note length] _ -@< >@||List.length [1, 2, 3]||List.length [1; 2; 3]||List.length [1; 2; 3]||length [1, 2, 3]|| +@< >@||List.length [1, 2, 3]||List.length [1; 2; 3]||List.length [1; 2; 3]||length [1, 2, 3]||[len xs]|| ||[[# nth-elem-of-list]][#nth-elem-of-list-note nth element] _ -@< >@||List.nth ([1, 2, 3], 0)||List.nth [1; 2; 3] 0||List.nth [1; 2; 3] 0||[1, 2, 3] !! 0|| +@< >@||List.nth ([1, 2, 3], 0)||List.nth [1; 2; 3] 0||List.nth [1; 2; 3] 0||[1, 2, 3] !! 0||[nth xs 2]|| ||[[# list-elem-index]][#list-elem-index-note element index]|| || || ||import Data.list _ _ ##gray|@@--@@ Just 1:## _ elemIndex 8 [7, 8, 9] _ _ ##gray|@@--@@ Nothing:## _ -elemIndex 10 [7, 8, 9]|| -||[[# update-list]][#update-list-note update]|| || || || || +elemIndex 10 [7, 8, 9]||##gray|//none//##|| +||[[# update-list]][#update-list-note update]|| || || || ||##gray|//none//##|| ||[[# concat-list]][#concat-list-note concatenate] _ ##gray|//two lists, list of lists//##||[1, 2] @ [3, 4] _ List.concat [[1, 2], [3, 4]]||[1; 2] @ [3; 4] _ @@ -488,14 +495,14 @@ List.append [1; 2] [3; 4] _ _ List.concat [[1; 2]; [3; 4]]||[1, 2] ++ [3, 4] _ _ -concat [[1, 2], [3, 4]]|| +concat [[1, 2], [3, 4]]||[concat xs ys]|| ||[[# list-last]][#list-last-note last] _ ##gray|//and butlast//##|| || || ||last [1, 2, 3] _ -init [1, 2, 3]|| +init [1, 2, 3]||[last xs]|| ||[[# list-take]][#list-take-note take] _ -@< >@|| || || ||take 2 [1, 2, 3]|| +@< >@|| || || ||take 2 [1, 2, 3]||[take 2 xs]|| ||[[# list-drop]][#list-drop-note drop] _ -@< >@|| || || ||drop 2 [1, 2, 3]|| +@< >@|| || || ||drop 2 [1, 2, 3]||[drop 2 xs]|| ||[[# iterate-over-list]][#iterate-over-list-note iterate]||fun f i = print ((Int.toString i) ^ "\n"); _ List.app f [1, 2, 3];||let f i = _ @<  >@print_endline (string_of_int i);; _ @@ -503,43 +510,43 @@ List.app f [1, 2, 3];||let f i = _ List.iter f [1; 2; 3];;||let f i = _ @<  >@System.Console.WriteLine(string i) _ _ -List.iter f [1; 2; 3]||mapM_ print [1, 2, 3]|| +List.iter f [1; 2; 3]||mapM_ print [1, 2, 3]||[each [fn [x] [println x]] xs]|| ||[[# reverse-list]][#reverse-list-note reverse] _ -@< >@||List.rev [1, 2, 3]||List.rev [1; 2; 3]||List.rev [1; 2; 3]||reverse [1, 2, 3]|| +@< >@||List.rev [1, 2, 3]||List.rev [1; 2; 3]||List.rev [1; 2; 3]||reverse [1, 2, 3]||[reverse xs]|| ||[[# sort-list]][#sort-list-note sort]|| ||List.sort min [1; 3; 2; 4] _ List.sort max [1; 3; 2; 4]||List.sort [1; 3; 2; 4]||import Data.List _ _ -sort [1, 3, 2, 4]|| -||[[# map-list]][#map-list-note map]||List.map (fn (x) => x + 2) [1, 2, 3];||List.map (( * ) 2) [1; 2; 3]||List.map (( * ) 2) [1; 2; 3]||map (\x -> x * x) [1, 2, 3]|| +sort [1, 3, 2, 4]||[sort xs]|| +||[[# map-list]][#map-list-note map]||List.map (fn (x) => x + 2) [1, 2, 3];||List.map (( * ) 2) [1; 2; 3]||List.map (( * ) 2) [1; 2; 3]||map (\x -> x * x) [1, 2, 3]||[map [fn [x] [* x x]] xs]|| ||[[# filter-list]][#filter-list-note filter] _ -@< >@||List.filter (fn (x) => x > 2) [1, 2, 3];||List.filter ((<) 2) [1; 2; 3]||List.filter ((<) 2) [1; 2; 3]||filter (\x -> x > 2) [1, 2, 3]|| -||[[# fold-list-left]][#fold-list-left-note fold from left]||List.foldl (op +) 0 [1, 2, 3];||List.fold_left (+) 0 [1; 2; 3]||List.fold (-) 0 [1; 2; 3]||foldl (+) 0 [1, 2, 3]|| +@< >@||List.filter (fn (x) => x > 2) [1, 2, 3];||List.filter ((<) 2) [1; 2; 3]||List.filter ((<) 2) [1; 2; 3]||filter (\x -> x > 2) [1, 2, 3]||[filter [fn [x] [> x 0]] xs]|| +||[[# fold-list-left]][#fold-list-left-note fold from left]||List.foldl (op +) 0 [1, 2, 3];||List.fold_left (+) 0 [1; 2; 3]||List.fold (-) 0 [1; 2; 3]||foldl (+) 0 [1, 2, 3]||[fold 0 [fn [a b] [+ a b]] xs]|| ||[[# fold-list-right]][#fold-list-right-note fold from right] _ -@< >@|| ||List.fold_right (-) [1; 2; 3] 0||List.foldr (op -) 0 [1, 2, 3];||foldr (-) 0 [1, 2, 3]|| +@< >@|| ||List.fold_right (-) [1; 2; 3] 0||List.foldr (op -) 0 [1, 2, 3];||foldr (-) 0 [1, 2, 3]||[fold 0 [fn [a b] [+ a b]] [reverse xs]]|| ||[[# list-member]][#list-member-note membership] _ -@< >@|| ||List.mem 3 [1; 2; 3]|| ||elem 3 [1, 2, 3]|| +@< >@|| ||List.mem 3 [1; 2; 3]|| ||elem 3 [1, 2, 3]||[contains? xs 3]|| ||[[# universal-test-list]][#universal-test-list-note universal test] _ -@< >@|| ||List.for_all (fun x -> x > 2) [1; 2; 3];;||List.forall (fun x -> x > 2) [1; 2; 3]||all (\x -> x > 2) [1, 2, 3]|| +@< >@|| ||List.for_all (fun x -> x > 2) [1; 2; 3];;||List.forall (fun x -> x > 2) [1; 2; 3]||all (\x -> x > 2) [1, 2, 3]||[all? [fn [x] [> x 0]] xs]|| ||[[# existential-test-list]][#existential-test-list-note existential test] _ -@< >@|| ||List.exists (fun x -> x > 2) [1; 2; 3];;||List.exists (fun x -> x > 2) [1; 2; 3]||any (\x -> x > 2) [1, 2, 3]|| +@< >@|| ||List.exists (fun x -> x > 2) [1; 2; 3];;||List.exists (fun x -> x > 2) [1; 2; 3]||any (\x -> x > 2) [1, 2, 3]||[any? [fn [x] [> x 0]] xs]|| ||[[# zip-list]][#zip-list-note zip lists]|| ||##gray|@@(*@@ list of tuples *)## _ List.combine [1; 2; 3] ['a'; 'b'; 'c'] _ || ||##gray|@@--@@ list of tuples:## _ -zip [1, 2, 3] ['a', 'b', 'c']|| -||||||||||~ [[# tuples]][#tuples-note tuples]|| -||~ ||~ sml||~ ocaml||~ f#||~ haskell|| -||[[# tuple-literal]][#tuple-literal-note literal]||(1, "hello", true)||(1, "hello", true)||(1, "hello", true)||(1, "hello", True)|| -||[[# tuple-lookup]][#tuple-lookup-note lookup]||#1 (1, "hello", true)||match (1, "hello", true) with _, x, _ -> x||match (1, "hello", true) with _, x, _ -> x||(\(a, _, _) -> a) (1, "hello", True)|| +zip [1, 2, 3] ['a', 'b', 'c']||[zip xs ys]|| +||||||||||||~ [[# tuples]][#tuples-note tuples]|| +||~ ||~ sml||~ ocaml||~ f#||~ haskell||~ loon|| +||[[# tuple-literal]][#tuple-literal-note literal]||(1, "hello", true)||(1, "hello", true)||(1, "hello", true)||(1, "hello", True)||##gray|//none; pairs via//## [zip xs ys]|| +||[[# tuple-lookup]][#tuple-lookup-note lookup]||#1 (1, "hello", true)||match (1, "hello", true) with _, x, _ -> x||match (1, "hello", true) with _, x, _ -> x||(\(a, _, _) -> a) (1, "hello", True)||##gray|//destructure://## [fn [[a b]] a]|| ||[[# pair-lookup]][#pair-lookup-note pair lookup]||#1 (12,"December") _ #2 (12,"December")||fst (12, "December") _ snd (12, "December")||fst (12, "December") _ snd (12, "December")||fst (12, "December") _ -snd (12, "December")|| -||||||||||~ [[# dictionaries]][#dictionaries-note dictionaries]|| -||~ ||~ sml||~ ocaml||~ f#||~ haskell|| -||||||||||~ [[# functions]][#functions-note functions]|| -||~ ||~ sml||~ ocaml||~ f#||~ haskell|| -||[[# def-func]][#def-func-note define function]||fun average a b = ( a + b ) / 2.0;||let average a b = ( a +. b ) /. 2.0;;||let average a b = ( a + b ) / 2.0||average a b = (a + b) / 2.0|| +snd (12, "December")||##gray|//destructure://## [fn [[a b]] b]|| +||||||||||||~ [[# dictionaries]][#dictionaries-note dictionaries]|| +||~ ||~ sml||~ ocaml||~ f#||~ haskell||~ loon|| +||||||||||||~ [[# functions]][#functions-note functions]|| +||~ ||~ sml||~ ocaml||~ f#||~ haskell||~ loon|| +||[[# def-func]][#def-func-note define function]||fun average a b = ( a + b ) / 2.0;||let average a b = ( a +. b ) /. 2.0;;||let average a b = ( a + b ) / 2.0||average a b = (a + b) / 2.0||[fn add [a b] [+ a b]]|| ||[[# invoke-func]][#invoke-func-note invoke function]|| ||##gray|@@(*@@ 4.5: *)## _ average 1.0 2.0 +. 3.0;; _ _ @@ -553,52 +560,55 @@ average 1 2 + 3 _ _ ##gray|@@--@@ 3.0:## _ average 1 (2 + 3) _ -average 1 $ 2 + 3|| +average 1 $ 2 + 3||[add 1 2]|| ||[#named-parameter named parameter]|| ||let subtract ~m ~s = m - s;; _ _ -subtract ~s: 3 ~m: 7;;|| ||##gray|//none//##|| +subtract ~s: 3 ~m: 7;;|| ||##gray|//none//##||##gray|//none//##|| ||[#default-value named parameter default value]|| ||let logarithm ?(base = (exp 1.0)) x = log x /. (log base);; _ _ logarithm 2.718;; _ -logarithm ~base: 2.0 10.0;;|| ||##gray|//none//##|| +logarithm ~base: 2.0 10.0;;|| ||##gray|//none//##||##gray|//none; use multi-arity//##|| ||[#piecewise-defined-function piecewise defined function]||val to_s = fn Red => "red" _ @<  >@| Green => "green" _ @<  >@| Blue => "blue";||let to_s = function Red -> "red" _ @<  >@| Green -> "green" _ @<  >@| Blue -> "blue";;|| ||to_s Red = "red" _ to_s Green = "green" _ -to_s Blue = "blue"|| +to_s Blue = "blue"||[fn to-s [c] _ + [match c Red "red" Green "green"]]|| ||[#recursive-function recursive function]||fun range a b = _ @<  >@if a > b then [] _ @<  >@else a :: range (a + 1) b;||let rec range a b = _ if a > b then [] _ -else a :: range (a+1) b;;|| ||range a b = if a > b then [] else a : range (a+1) b|| +else a :: range (a+1) b;;|| ||range a b = if a > b then [] else a : range (a+1) b||[fn fact [n] _ + [if [< n 2] 1 [* n [fact [- n 1]]]]]|| ||[#mutually-recursive-functions mutually-recursive-functions]|| ||let rec even n = if n = 0 then true else odd (n-1) _ -and odd n = if n = 0 then false else even (n-1);;|| || || -||[#anonymous-func anonymous function]||fn x => fn y => (x + y) / 2.0||fun x -> fun y -> (x +. y) /. 2.0||fun x -> fun y -> (x + y) / 2.0||\x y -> (x+y) / 2.0|| -||[#infix-prefix infix operator in prefix position]||(op * ) (3, 4)||( * ) 3 4;;|| ||( * ) 3 4|| +and odd n = if n = 0 then false else even (n-1);;|| || ||[fn ev? [n] [if [= n 0] true [od? [- n 1]]]] _ +[fn od? [n] [if [= n 0] false [ev? [- n 1]]]]|| +||[#anonymous-func anonymous function]||fn x => fn y => (x + y) / 2.0||fun x -> fun y -> (x +. y) /. 2.0||fun x -> fun y -> (x + y) / 2.0||\x y -> (x+y) / 2.0||[fn [x y] [/ [+ x y] 2.0]]|| +||[#infix-prefix infix operator in prefix position]||(op * ) (3, 4)||( * ) 3 4;;|| ||( * ) 3 4||##gray|//operators are prefix://## [* 3 4]|| ||[#function-infix function in infix position]|| ||##gray|//none//##|| ||add x y = x + y _ -3 `add` 4|| +3 `add` 4||##gray|//none; all calls are prefix//##|| ||[#currying currying]||un plus x y = x + y; _ val plus2 = plus 2; _ -plus2 7;||let plus2 = (+) 2;;|| ||plus2 = (+) 2|| +plus2 7;||let plus2 = (+) 2;;|| ||plus2 = (+) 2||##gray|//none; use a closure://## [fn [x] [+ 2 x]]|| ||[#composition composition]|| || || ||f x = x + 2 _ g x = x * 3 _ -(f . g ) 4|| +(f . g ) 4||[fn [x] [f [g x]]]|| ||[#function-composition function composition operator]||fun double x = 2 * x; _ val quadruple = double o double;||##gray|//none//##|| ||double x = 2 * x _ -quadruple x = double . double|| +quadruple x = double . double||[pipe x g f] ##gray|//; via pipe//##|| ||[#lazy-evaluation lazy evaluation]|| ||let arg1 x y = x;; _ _ arg1 7 (lazy (1/0) );;|| ||##gray|//lazy evaluation is default://## _ arg1 x y = x _ _ -arg1 7 (error "bam!")|| +arg1 7 (error "bam!")||##gray|//none; strict evaluation//##|| ||[#strict-evaluation strict evaluation]|| ||##gray|//default behavior//##||##gray|//default behavior//##||arg1 x y = seq y x _ _ -arg1 7 (error "bam!")|| -||||||||||~ [[# execution-control]][#execution-control-note execution control]|| -||~ ||~ sml||~ ocaml||~ f#||~ haskell|| +arg1 7 (error "bam!")||##gray|//default (strict)//##|| +||||||||||||~ [[# execution-control]][#execution-control-note execution control]|| +||~ ||~ sml||~ ocaml||~ f#||~ haskell||~ loon|| ||[#if if]||f x > 0 then _ @<  >@print "pos\n" _ else _ @@ -606,7 +616,7 @@ else _ @<  >@print_endline "pos";;||if x > 0 then _ @<  >@printfn "pos"||if x > 0 _ @<  >@then putStrLn "pos" _ -@<  >@else return ()|| +@<  >@else return ()||[if [> x 0] [println "pos"] [println "neg"]]|| ||[#if-else-if-else if else-if else]||if x > 0 then print "pos" else if x < 0 then print "neg" else print "zero";||if x > 0 then _ @<  >@print_endline "pos" _ else _ @@ -623,7 +633,8 @@ else _ @<  >@then putStrLn "pos" _ @<  >@else if x < 0 _ @<  >@@<  >@then putStrLn "neg" _ -@<  >@@<  >@else putStrLn "zero"|| +@<  >@@<  >@else putStrLn "zero"||[if [> x 0] "pos" _ + [if [< x 0] "neg" "zero"]]|| ||[#sequencing sequencing]|| ||print_endline "one"; _ print_endline "two"; _ print_endline "three";;||printfn "one" _ @@ -631,7 +642,7 @@ printfn "two" _ printfn "three"||do _ @<  >@putStrLn "one" _ @<  >@putStrLn "two" _ -@<  >@putStrLn "three"|| +@<  >@putStrLn "three"||[do [println "one"] [println "two"]]|| ||[#while while]|| ||let i = ref 0;; _ _ while !i < 10 do _ @@ -641,31 +652,31 @@ done;;||let i = ref 0 _ _ while !i < 10 do _ @<  >@printfn "%d" !i _ -@<  >@i := !i + 1|| || +@<  >@i := !i + 1|| ||##gray|//none; use//## [loop [i 0] [if [< i 3] [recur [+ i 1]] i]]|| ||[#for for]|| ||for i = 1 to 10 do _ @<  >@let s = string_of_int i in _ @<  >@print_endline s _ -done;;|| || || +done;;|| || ||[each [fn [i] [println i]] [range 5]]|| ||[#reverse-for for in reverse]|| ||for i = 10 downto 1 do _ @<  >@let s = string_of_int i in _ @<  >@print_endline s _ -done;;|| || || -||[#list-iteration list iteration]|| ||##gray|//none//##|| || || +done;;|| || ||[each [fn [i] [println i]] [reverse [range 5]]]|| +||[#list-iteration list iteration]|| ||##gray|//none//##|| || ||[each [fn [x] [println x]] xs]|| ||[#loop loop]|| ||let rec loop i = _ @<  >@if i <= 10 then begin _ @<  >@@<  >@print_endline (string_of_int i); _ @<  >@@<  >@loop (i+1) _ @<  >@end in _ -loop 0;;|| || || -||||||||||~ [[# exceptions]][#exceptions-note exceptions]|| -||~ ||~ sml||~ ocaml||~ f#||~ haskell|| +loop 0;;|| || ||[loop [i 0] [if [< i 5] [recur [+ i 1]] i]]|| +||||||||||||~ [[# exceptions]][#exceptions-note exceptions]|| +||~ ||~ sml||~ ocaml||~ f#||~ haskell||~ loon|| ||[#raise-error raise error]|| ||raise (Failure "bam!");; _ ##gray|//or//## _ -failwith "bam!";;|| ||error "bam!"|| -||[#handle-error handle error]|| ||let x = try 1 / 0 with Division_by_zero -> 0;;|| || || -||[#exception-type type of exceptions]|| ||exn|| || || +failwith "bam!";;|| ||error "bam!"||[Fail.raise "bam"]|| +||[#handle-error handle error]|| ||let x = try 1 / 0 with Division_by_zero -> 0;;|| || ||[try [risky]] ##gray|//; -> Result//##|| +||[#exception-type type of exceptions]|| ||exn|| || ||##gray|//none; Result a Str or Fail effect//##|| ||[#user-exception user defined exception]|| ||exception Foo of string;; _ -raise (Foo "invalid input");;|| || || +raise (Foo "invalid input");;|| || ||[effect Err [oops [String] a]]|| ||[#standard-exceptions standard exceptions]|| ||Division_by_zero _ Failure ##gray|//string//## _ Not_found _ @@ -673,33 +684,33 @@ Invalid_argument ##gray|//string//## _ Match_failure (##gray|//string//##, ##gray|//int//##, ##gray|//int//##) _ Assert_failure (##gray|//string//##, ##gray|//int//##, ##gray|//int//##) _ Out_of_memory _ -Stack_overflow|| || || -||[#assert assert]|| ||assert(1 = 0);;|| || || -||||||||||~ [[# concurrency]][#concurrency-note concurrency]|| -||~ ||~ sml||~ ocaml||~ f#||~ haskell|| -||||||||||~ [[# file-handles]][#file-handles-note file handles]|| -||~ ||~ sml||~ ocaml||~ f#||~ haskell|| +Stack_overflow|| || ||##gray|//none; Fail effect//##|| +||[#assert assert]|| ||assert(1 = 0);;|| || ||[assert-eq got 1] ##gray|//; in a test//##|| +||||||||||||~ [[# concurrency]][#concurrency-note concurrency]|| +||~ ||~ sml||~ ocaml||~ f#||~ haskell||~ loon|| +||||||||||||~ [[# file-handles]][#file-handles-note file handles]|| +||~ ||~ sml||~ ocaml||~ f#||~ haskell||~ loon|| ||standard file handles|| ||stdin stdout stderr||stdin stdout stderr||import System.Posix.IO _ _ -stdInput stdOutput stdError|| -||read line from stdin|| ||let line = read_line();;|| ||line <- getLine|| -||end-of-file behavior|| ||##gray|//raises// End_of_file##|| ||##gray|//when last data is returned,// hIsEOF //will return True. Reading after end-of-file throws an exception.//##|| -||chomp|| || || || || -||[#write-line-stdout write line to stdout]|| ||print_endline "lorem ipsum";;||printfn "lorem ipsum"||putStrLn "lorem ipsum"|| -||write formatted string to stdout|| || || || || +stdInput stdOutput stdError||##gray|//none//##|| +||read line from stdin|| ||let line = read_line();;|| ||line <- getLine||[IO.read-line]|| +||end-of-file behavior|| ||##gray|//raises// End_of_file##|| ||##gray|//when last data is returned,// hIsEOF //will return True. Reading after end-of-file throws an exception.//##||##gray|//none//##|| +||chomp|| || || || ||[trim s]|| +||[#write-line-stdout write line to stdout]|| ||print_endline "lorem ipsum";;||printfn "lorem ipsum"||putStrLn "lorem ipsum"||[IO.println "lorem ipsum"]|| +||write formatted string to stdout|| || || || ||[IO.println "x = {x}"]|| ||open file for reading|| ||let f = open_in "/etc/passwd";;|| ||import System.IO _ _ -f <- openFile "/etc/hosts" ReadMode|| +f <- openFile "/etc/hosts" ReadMode||##gray|//none; whole-file://## [IO.read-file p]|| ||open file for writing|| ||let f = open_out "/tmp/ocaml.out";;|| ||import System.IO _ _ -f <- openFile "/tmp/test" WriteMode|| +f <- openFile "/tmp/test" WriteMode||##gray|//none; whole-file://## [IO.write-file p s]|| ||open file for appending|| || || ||import System.IO _ _ -f <- openFile "/tmp/err.log" AppendMode|| +f <- openFile "/tmp/err.log" AppendMode||##gray|//none//##|| ||close file|| || || ||import System.IO _ _ -hClose f|| -||i/o errors|| || || || || +hClose f||##gray|//n/a; no handles//##|| +||i/o errors|| || || || ||[IO.read-file p]? ##gray|//; propagates Err//##|| ||[#read-line read line]||fun displayFile(file: string) = _ @<  >@let _ @<  >@@<  >@val f = TextIO.openIn file _ @@ -728,11 +739,11 @@ readAndPrintLines h = do _ _ main = do _ @<  >@h <- openFile "/etc/passwd" ReadMode _ -@<  >@readAndPrintLines h|| -||iterate over file by line|| || || || || -||read file into array of strings|| || || || || -||read file into string|| || || || || -||write string|| || || || || +@<  >@readAndPrintLines h||[IO.read-line] ##gray|//; stdin//##|| +||iterate over file by line|| || || || ||[each f [split [IO.read-file p] "\n"]]|| +||read file into array of strings|| || || || ||[split [IO.read-file p] "\n"]|| +||read file into string|| || || || ||[IO.read-file p]|| +||write string|| || || || ||[IO.write-file p s]|| ||[#write-file write line]||val file = "/tmp/test-sml"; _ val f = TextIO.openOut file; _ TextIO.output(f, "hello out\n"); _ @@ -741,12 +752,12 @@ let oc = open_out "/tmp/test-ocaml" in _ fprintf oc "hello out\n"; _ close_out oc;;|| ||s = "hello out\n" _ f = "/tmp/test-haskell" _ -main = writeFile f s|| -||flush file handle|| || || || || -||end-of-file test|| || || || || -||get and set filehandle position|| || || || || -||||||||||~ [[# files]][#files-note files]|| -||~ ||~ sml||~ ocaml||~ f#||~ haskell|| +main = writeFile f s||[IO.write-file p "hello\n"]|| +||flush file handle|| || || || ||##gray|//n/a//##|| +||end-of-file test|| || || || ||##gray|//none//##|| +||get and set filehandle position|| || || || ||##gray|//none//##|| +||||||||||||~ [[# files]][#files-note files]|| +||~ ||~ sml||~ ocaml||~ f#||~ haskell||~ loon|| ||file test, regular file test|| ||open Unix _ _ try Some (stat "/etc/hosts") with _ @@ -759,11 +770,11 @@ Directory.doesFileExist "/etc/hosts" _ import Control.Monad _ import System.Posix.Files _ _ -liftM isRegularFile (getFileStatus "/etc/hosts")|| +liftM isRegularFile (getFileStatus "/etc/hosts")||##gray|//none//##|| ||file size|| ||(stat "/etc/hosts").st_size|| ||import Control.Monad _ import System.Posix.Files _ _ -liftM fileSize (getFileStatus "/etc/hosts")|| +liftM fileSize (getFileStatus "/etc/hosts")||##gray|//none//##|| ||is file readable, writable, executable|| ||open Unix _ _ try access "/tmp/bar" [R_OK]; true with _ @@ -778,7 +789,7 @@ liftM readable _ liftM writable _ @<  >@(getPermissions "/etc/hosts") _ liftM executable _ -@<  >@(getPermissions "/etc/hosts")|| +@<  >@(getPermissions "/etc/hosts")||##gray|//none//##|| ||set file permissions|| ||open Unix _ _ chmod "/tmp/foo" 0o755|| ||import System.Posix.Files _ @@ -787,7 +798,7 @@ setFileMode "/tmp/foo" ownerModes _ setFileMode "/tmp/foo" groupReadMode _ setFileMode "/tmp/foo" groupExecuteMode _ setFileMode "/tmp/foo" otherReadMode _ -setFileMode "/tmp/foo" otherExecuteMode|| +setFileMode "/tmp/foo" otherExecuteMode||##gray|//none//##|| ||copy file, remove file, rename file|| ||open Unix _ _ ##gray|//??//## _ @@ -796,7 +807,7 @@ rename "/tmp/bar" "/tmp/foo"|| ||import System.Directory _ _ copyFile "/tmp/foo" "/tmp/bar" _ removeFile "/tmp/foo" _ -renameFile "/tmp/bar" "/tmp/foo"|| +renameFile "/tmp/bar" "/tmp/foo"||##gray|//none//##|| ||create symlink, symlink test, readlink|| ||open Unix _ _ symlink "/etc/hosts" "/tmp/hosts" _ @@ -805,50 +816,50 @@ readlink "/tmp/hosts"|| ||import System.Posix.Files _ _ createSymbolicLink "/etc/hosts" "/tmp/hosts" _ ##gray|//??//## _ -readSymbolicLink "/tmp/hosts"|| +readSymbolicLink "/tmp/hosts"||##gray|//none//##|| ||generate unused file name|| ||open Filename _ _ ##gray|(* prefix and suffix: *)## _ -temp_file "foo" ".txt"|| || || -||||||||||~ [[# directories]][#directories-note directories]|| -||~ ||~ sml||~ ocaml||~ f#||~ haskell|| +temp_file "foo" ".txt"|| || ||##gray|//none//##|| +||||||||||||~ [[# directories]][#directories-note directories]|| +||~ ||~ sml||~ ocaml||~ f#||~ haskell||~ loon|| ||build pathname|| ||open Filename _ _ concat "/etc" "hosts"|| ||import System.FilePath (()) _ _ -let path = "/etc" "hosts"|| +let path = "/etc" "hosts"||[join "/" #["dir" "file"]]|| ||dirname and basename|| ||open Filename _ _ dirname "/etc/hosts" _ basename "/etc/hosts"|| ||import System.FilePath _ _ takeFileName "/etc/hosts" _ -takeDirectory "/etc/hosts"|| +takeDirectory "/etc/hosts"||##gray|//none//##|| ||iterate over directory by file|| || || ||import System _ _ ##gray|@@--@@ returns IO [FilePath]## _ -Directory.getDirectoryContents "/etc"|| +Directory.getDirectoryContents "/etc"||##gray|//none//##|| ||make directory|| ||##gray|(* opam install fileutils *)## _ open FileUtil _ _ mkdir ~parent:true "/tmp/foo/bar"|| ||import System.Directory _ _ createDirectoryIfMissing True _ -@<  >@"/tmp/foo/bar"|| +@<  >@"/tmp/foo/bar"||##gray|//none//##|| ||remove empty directory|| ||open Unix _ _ rmdir "/tmp/foodir"|| ||import System.Directory _ _ -removeDirectory "/tmp/foodir"|| +removeDirectory "/tmp/foodir"||##gray|//none//##|| ||remove directory and contents|| || || ||import System.Directory _ _ -removeDirectoryRecursive "/tmp/foodir"|| +removeDirectoryRecursive "/tmp/foodir"||##gray|//none//##|| ||directory test|| || || ||import System _ _ -Directory.doesDirectoryExist "/tmp"|| -||temporary directory|| || || || || -||||||||||~ [[# processes-environment]][#processes-environment-note processes and environment]|| -||~ ||~ sml||~ ocaml||~ f#||~ haskell|| +Directory.doesDirectoryExist "/tmp"||##gray|//none//##|| +||temporary directory|| || || || ||##gray|//none//##|| +||||||||||||~ [[# processes-environment]][#processes-environment-note processes and environment]|| +||~ ||~ sml||~ ocaml||~ f#||~ haskell||~ loon|| ||[#command-line-arg command line arguments]|| ||for i = 0 to Array.length Sys.argv - 1 do _ @<  >@print_endline i Sys.argv.(i) _ done|| ||import System _ @@ -861,12 +872,12 @@ printArgs args = do _ @<  >@@<  >@@<  >@printArgs (tail args) _ main = do _ @<  >@a <- getArgs _ -@<  >@printArgs a|| +@<  >@printArgs a||[IO.args] ##gray|//; #[Str]//##|| ||[[# program-name]][#program-name-note program name] _ @< >@|| || || ||import System _ _ -s <- getProgName|| -||[[# getopt]][#getopt-note getopt]|| || || || || +s <- getProgName||[nth [IO.args] 0]|| +||[[# getopt]][#getopt-note getopt]|| || || || ||##gray|//none//##|| ||[[# env-var]][#env-var-note get and set environment variable] _ @< >@|| ||open Unix _ _ @@ -874,20 +885,21 @@ s = getenv "HOME" _ putenv "PATH" "/bin"|| ||import System.Posix.Env _ _ s <- getEnv "HOME" _ -putEnv "PATH=/bin"|| +putEnv "PATH=/bin"||[IO.env "HOME"] _ +##gray|//set: none//##|| ||[[# pid]][#pid-note get pid, parent pid]|| ||open Unix _ _ let pid = getpid() _ let ppid = getppid()|| ||import System.Posix.Process _ _ pid <- getProcessID _ -ppid <- getParentProcessID|| +ppid <- getParentProcessID||##gray|//none//##|| ||[[# user-id-name]][#user-id-name-note get user id and name]|| ||let uid = getuid() _ let username = _ @<  >@(getpwuid (getuid())).pw_name|| ||import System.Posix.User _ _ uid <- getRealUserID _ -username <- getLoginName|| +username <- getLoginName||##gray|//none//##|| ||[[# exit]][#exit-note exit] _ @< >@|| ||exit 0 _ _ @@ -896,19 +908,20 @@ exit 1|| ||import System.Exit _ exitWith ExitSuccess _ _ ##gray|//to return nonzero status://## _ -exitWith (ExitFailure 1)|| +exitWith (ExitFailure 1)||##gray|//none//##|| ||[[# signal-handler]][#signal-handler-note set signal handler] _ -@< >@|| || || || || +@< >@|| || || || ||##gray|//none//##|| ||[[# external-cmd]][#external-cmd-note external command] _ @< >@|| || || ||import System.Cmd _ _ -rawSystem "ls" ["-l", "/tmp"]|| +rawSystem "ls" ["-l", "/tmp"]||[IO.exec "ls" #["-l"]]|| ||[[# escaped-external-cmd]][#escaped-external-cmd-note escaped external command] _ -@< >@|| || || || || +@< >@|| || || || ||[IO.exec "ls" #["-l"]] _ +##gray|//args are a vector//##|| ||[[# backticks]][#backticks-note backticks] _ -@< >@|| || || || || -||||||||||~ [[# libraries-namespaces]][#libraries-namespaces-note libraries and namespaces]|| -||~ ||~ sml||~ ocaml||~ f#||~ haskell|| +@< >@|| || || || ||[IO.exec "date" #[]] ##gray|//; Result Str//##|| +||||||||||||~ [[# libraries-namespaces]][#libraries-namespaces-note libraries and namespaces]|| +||~ ||~ sml||~ ocaml||~ f#||~ haskell||~ loon|| ||[#namespace-example namespace example]|| || || ||##gray|//Foo/Bar.hs//## _ module Foo.Bar where _ @<  >@data Baz = Baz _ @@ -924,13 +937,13 @@ main = say baz _ $ ghc -c Foo/Bar.hs _ $ ghc Main.hs _ $ ./Main _ -hello|| -||[#namespaces namespaces]|| || || ||values, constructors, type variables, type constructors, type classes, modules|| -||[#file-name file name restrictions]|| ||##gray|//module// Foo.Bar //must be in// Foo.ml##|| ||##gray|//module// Foo.Bar //must be in// Foo/Bar.hs##|| -||[#import namespace]|| ||open Graphics;;|| ||import Data.Bytestring|| -||[#namespace-creation namespace creation]|| ||##gray|//put code in file// MODULE_NAME//.ml//##|| || || -||[#namespace-alias namespace alias]|| ||module Gr = Graphics;;|| ||import qualified Data.Bytestring as B|| -||[#namespace-separator namespace separator]|| ||.|| ||.|| +hello||##gray|//math.oo://## [pub fn add [a b] [+ a b]]|| +||[#namespaces namespaces]|| || || ||values, constructors, type variables, type constructors, type classes, modules||##gray|//one module per file//##|| +||[#file-name file name restrictions]|| ||##gray|//module// Foo.Bar //must be in// Foo.ml##|| ||##gray|//module// Foo.Bar //must be in// Foo/Bar.hs##||##gray|//module name = file name//##|| +||[#import namespace]|| ||open Graphics;;|| ||import Data.Bytestring||[use math]|| +||[#namespace-creation namespace creation]|| ||##gray|//put code in file// MODULE_NAME//.ml//##|| || ||##gray|//implicit (the file)//##|| +||[#namespace-alias namespace alias]|| ||module Gr = Graphics;;|| ||import qualified Data.Bytestring as B||[use math as m]|| +||[#namespace-separator namespace separator]|| ||.|| ||.||. ##gray|//; e.g. math.add//##|| ||[#subnamespace subnamespace]|| ||##gray|//in A.ml://## _ module B = _ sig _ @@ -941,23 +954,24 @@ struct _ @<  >@let display_instruction () = print_endline msg _ end _ ##gray|//in client source://## _ -A.B.display_instruction;;|| || || +A.B.display_instruction;;|| || ||[use utils/string]|| ||[[# pkg-manager-setup]][#pkg-manager-setup-note package manager setup]|| ||##gray|//do this once://## _ $ opam init _ _ ##gray|//for each shell session://## _ -$ eval $(opam config env)|| || || +$ eval $(opam config env)|| || ||$ loon init|| ||[[# pkg-manager]][#pkg-manager-note package manager] _ ##gray|//search; install; list installed//##|| ||$ opam search utop _ $ opam install utop _ $ opam list @@--@@installed|| ||$ cabal list parsec _ $ cabal install parsec _ -$ cabal list @@--@@installed|| -||[[# pkg-compile]][#pkg-compile-note compile app using package]|| || || || || -||||||||||~ [[# user-defined-types]][#user-defined-types-note user-defined types]|| -||~ ||~ sml||~ ocaml||~ f#||~ haskell|| +$ cabal list @@--@@installed||$ loon add ##gray|//pkg//## _ +$ loon update|| +||[[# pkg-compile]][#pkg-compile-note compile app using package]|| || || || ||$ loon build|| +||||||||||||~ [[# user-defined-types]][#user-defined-types-note user-defined types]|| +||~ ||~ sml||~ ocaml||~ f#||~ haskell||~ loon|| ||[[# type-synonym]][#type-synonym-note type synonym] _ -@< >@||type name = string;||type name = string;;||type name = string||type Name = String|| +@< >@||type name = string;||type name = string;;||type name = string||type Name = String||##gray|//none//##|| ||[[# sum-type]][#sum-type-note sum type]||datatype color = Red | Green | Blue;||type color = Red | Green | Blue;; _ _ let col = Red;; _ @@ -973,7 +987,7 @@ col < Green||data Color = Red | Green | Blue _ col = Red _ _ ##gray|@@--@@ this won't compile:## _ -col < Green|| +col < Green||[type Color Red Green Blue]|| ||tuple product type with one field||datatype special_int = SpecialInt of int; _ _ val x = SpecialInt 7;||type special_int = SpecialInt of int;; _ @@ -982,7 +996,7 @@ let n = SpecialInt 7;;||type special_int = SpecialInt of int _ _ let n = SpecialInt 7||data SpecialIntType = SpecialInt Integer _ _ -n = SpecialInt 7|| +n = SpecialInt 7||[type Id [Id Int]]|| ||tuple product type with two fields||datatype int_pair = IntPair of int * int; _ _ val y = IntPair (7, 11);||type int_pair = IntPair of int * int;; _ @@ -991,7 +1005,7 @@ let p = IntPair (7, 11);;||type int_pair = IntPair of int * int _ _ let p = IntPair (7, 11)||data IntPairType = IntPair Integer Integer _ _ -p = IntPair 7 11|| +p = IntPair 7 11||[type Pair [Pair Int Int]]|| ||record product type||type customer = {id:int, name:string, address:string}||type customer = { _ @<  >@id: int; _ @<  >@name: string; _ @@ -1004,7 +1018,7 @@ p = IntPair 7 11|| @<  >@customerId :: Integer, _ @<  >@name :: String, _ @<  >@address :: String _ -}|| +}||##gray|//use a map (row-typed)//##|| ||record product type literal||{id=7, name="John", address="Topeka, KS"}||let cust = { _ @<  >@id=7; _ @<  >@name="John"; _ @@ -1012,7 +1026,7 @@ p = IntPair 7 11|| };;||{id=7; name="John"; address="Topeka, KS"}||Customer { _ @<  >@customerId=7, _ @<  >@name="John", _ -@<  >@address="Topeka, KS" }|| +@<  >@address="Topeka, KS" }||{:id 7 :name "ada"}|| ||[[# generic-type]][#generic-type-note generic type]||datatype ('a, 'b) twosome = _ @<  >@Twosome of 'a * 'b; _ _ @@ -1024,14 +1038,17 @@ let p = Twosome ("pi", 3.14);;||type ('a, 'b) twosome = _ _ let p = Twosome ("pi", 3.14)||data TwosomeType a b = Twosome a b _ _ -p = Twosome ("pi", 3.14)|| +p = Twosome ("pi", 3.14)||[type Tree _ + [Leaf a] _ + [Node [Tree a] [Tree a]]]|| ||[#recursive-type recursive type]||datatype binary_tree = _ @<  >@Leaf of int _ @<  >@| Tree of binary_tree * binary_tree;||type binary_tree = _ @<  >@| Leaf of int _ @<  >@| Tree of binary_tree * binary_tree;;||type binary_tree = _ @<  >@| Leaf of int _ -@<  >@| Tree of binary_tree * binary_tree||data BinaryTree = Leaf Integer | Tree BinaryTree BinaryTree|| +@<  >@| Tree of binary_tree * binary_tree||data BinaryTree = Leaf Integer | Tree BinaryTree BinaryTree||[type Tree _ + [Leaf Int] [Node Tree Tree]]|| ||pattern match sum type||val c = Red; _ _ case c of Red => "red" _ @@ -1044,35 +1061,35 @@ let s = match col with _ @<  >@| Green -> "green";;|| ||c = Red _ case c of Red -> "red" _ @<  >@Green -> "green" _ -@<  >@Blue -> "blue"|| -||pattern match product type|| || || || || -||[#match-guard pattern match guard]||##gray|//none; use// if##||match i with j when i < 0 -> -j | j -> j;;|| ||##gray|//none, use if or piecewise function definition//##|| +@<  >@Blue -> "blue"||[match c Red "red" Green "green"]|| +||pattern match product type|| || || || ||[match p [Pair a b] [+ a b]]|| +||[#match-guard pattern match guard]||##gray|//none; use// if##||match i with j when i < 0 -> -j | j -> j;;|| ||##gray|//none, use if or piecewise function definition//##||[match n x [if [> x 0] "pos" "neg"]]|| ||[#match-catchall pattern match catchall]||fun to_s c = case c of Red => "red" | _ => "not red";||let to_s c = match c with Red -> "red" | _ -> "not red";; _ to_s Green;;|| ||c = Green _ -case c of Red -> "red"; _ -> "not red"|| -||||||||||~ [[# objects]][#objects-note objects]|| -||~ ||~ sml||~ ocaml||~ f#||~ haskell|| +case c of Red -> "red"; _ -> "not red"||[match c Red "red" _ "other"]|| +||||||||||||~ [[# objects]][#objects-note objects]|| +||~ ||~ sml||~ ocaml||~ f#||~ haskell||~ loon|| ||[#class-definition class definition]|| ||class counter = object _ @<  >@val mutable n = 0 _ @<  >@method incr = n <- n+1 _ @<  >@method get = n _ -end;;|| || || -||[#object-creation object creation]|| ||let c = new counter;;|| || || +end;;|| || ||##gray|//none; use type + functions//##|| +||[#object-creation object creation]|| ||let c = new counter;;|| || ||##gray|//none; construct a value//##|| ||[#method-invocation method invocation]|| ||c#incr;; _ -c#get;;|| || || -||[#field-access field access]|| ||##gray|//none//##|| || || -||||||||||~ [[# inheritance-polymorphism]][#inheritance-polymorphism-note inheritance and polymorphism]|| -||~ ||~ sml||~ ocaml||~ f#||~ haskell|| -||overload function|| || || || || -||[#inheritance inheritance]|| || || || || -||||||||||~ [[# net-web]][#net-web-note net and web]|| -||~ ||~ sml||~ ocaml||~ f#||~ haskell|| -||||||||||~ [[# unit-tests]][#unit-tests-note unit test]|| -||~ ||~ sml||~ ocaml||~ f#||~ haskell|| -||||||||||~ [[# debugging-profiling]][#debugging-profiling-note debugging and profiling]|| -||~ ||~ sml||~ ocaml||~ f#||~ haskell|| -||||||||||~ [[# repl]][#repl-note repl]|| -||~ ||~ sml||~ ocaml||~ f#||~ haskell|| +c#get;;|| || ||##gray|//none; call a function//##|| +||[#field-access field access]|| ||##gray|//none//##|| || ||[get rec :field] ##gray|//; map field//##|| +||||||||||||~ [[# inheritance-polymorphism]][#inheritance-polymorphism-note inheritance and polymorphism]|| +||~ ||~ sml||~ ocaml||~ f#||~ haskell||~ loon|| +||overload function|| || || || ||[fn f ([a] ...) ([a b] ...)] ##gray|//; multi-arity//##|| +||[#inheritance inheritance]|| || || || ||##gray|//none//##|| +||||||||||||~ [[# net-web]][#net-web-note net and web]|| +||~ ||~ sml||~ ocaml||~ f#||~ haskell||~ loon|| +||||||||||||~ [[# unit-tests]][#unit-tests-note unit test]|| +||~ ||~ sml||~ ocaml||~ f#||~ haskell||~ loon|| +||||||||||||~ [[# debugging-profiling]][#debugging-profiling-note debugging and profiling]|| +||~ ||~ sml||~ ocaml||~ f#||~ haskell||~ loon|| +||||||||||||~ [[# repl]][#repl-note repl]|| +||~ ||~ sml||~ ocaml||~ f#||~ haskell||~ loon|| ||[#invoke-repl invoke repl]||$ sml||$ ocaml _ _ ##gray|//Use this if you want history://## _ @@ -1081,23 +1098,24 @@ $ rlwrap ocaml _ ##gray|//The utop toplevel, which can be installed via opam, also provides history.//##||##gray|//Mono://## _ $ fsharpi _ _ -##gray|//In visual studio, highlight code and press ALT+ENTER.//##||$ ghci|| -||[#repl-limitations repl limitations]|| || || ||##gray|//Must use let to define values and functions; when defining functions with multiple equations the equations must be separated by semicolons; the clauses of case/of statements must be separated by semicolons; it is not possible to define data types.//##|| -||[#repl-last-value repl last value]||it||##gray|//none//##||it||it|| -||[#help help]|| ||##gray|//none//##|| ||:?|| -||[#quit quit]|| ||^D||#quit;;|| || +##gray|//In visual studio, highlight code and press ALT+ENTER.//##||$ ghci||$ loon repl|| +||[#repl-limitations repl limitations]|| || || ||##gray|//Must use let to define values and functions; when defining functions with multiple equations the equations must be separated by semicolons; the clauses of case/of statements must be separated by semicolons; it is not possible to define data types.//##||##gray|//none//##|| +||[#repl-last-value repl last value]||it||##gray|//none//##||it||it||##gray|//none//##|| +||[#help help]|| ||##gray|//none//##|| ||:?||##gray|//none//##|| +||[#quit quit]|| ||^D||#quit;;|| ||:quit|| ||[#inspect-type inspect type]|| ||##gray|//repl displays the type of any expression entered//##|| ||let a = 3 _ -:type a|| -||[#inspect-namespace inspect namespace]|| ||module Unix = Unix;;|| || || +:type a||##gray|//LSP hover, or//## $ loon check|| +||[#inspect-namespace inspect namespace]|| ||module Unix = Unix;;|| || ||##gray|//none//##|| ||[#load-source load source file]||use "hello.ml";||#use "hello";;|| ||:edit hello.hs _ -:load hello|| +:load hello||$ loon run file.oo|| ||[#load-pkg-note load package]|| ||##gray|//consider adding to// .ocamlinit:## _ #use "topfind";; _ # thread;; _ #require "core";; _ -open Core.Std;;|| || || -||[#search-path search path]|| ||#directory "libdir";;|| || || -||[#search-path-command-line set search path on command line]|| ||ocaml -Ilibdir|| || || +open Core.Std;;|| || ||$ loon add pkg _ +[use pkg]|| +||[#search-path search path]|| ||#directory "libdir";;|| || ||##gray|//none//##|| +||[#search-path-command-line set search path on command line]|| ||ocaml -Ilibdir|| || ||##gray|//none//##|| ||~ ||~ ##EFEFEF|@@_______________________________________________@@##||~ ##EFEFEF|@@_______________________________________________@@##||~ ##EFEFEF|@@_______________________________________________@@##||~ ##EFEFEF|@@_______________________________________________@@##||