1. Overview (empty)

1.1. Evaluation

1.2. Expression and Value

1.3. Declaration and Environment

1.4. Function and Message

1.5. Type and Class

2. Atom

2.1. Integer

umu:1> 3
val it : Int = 3
umu:2> 3 + 4
val it : Int = 7
umu:3>

2.2. Float

umu:1> 3.0
val it : Float = 3.0
umu:2> 3.0 + 4.0
val it : Float = 7.0
umu:3>

2.3. String

umu:1> "Hello"
val it : String = "Hello"
umu:2> "Hello" ^ " world"
val it : String = "Hello world"
umu:3>

2.4. Symbol

umu:1> @hello
val it : Symbol = @hello
umu:2> to-s @hello
val it : String = "hello"
umu:3> show @hello
val it : String = "@hello"
umu:4>

2.5. Bool

umu:1> TRUE
val it : Bool = TRUE
umu:2> 3 == 3
val it : Bool = TRUE
umu:3> 3 == 4
val it : Bool = FALSE
umu:4>

3. Direct Propuct (empty)

3.1. Tuple

3.2. Named Tuple

4. Disjoint Union (empty)

4.1. Option

4.2. Result

4.3. Taged Data

5. List (empty)

6. List Comprehension

umu:1> [|x| val x <- [1 .. 10]]
val it : Cons = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
umu:2> [|x| val x <- [1 .. 10] if odd? x]
val it : Cons = [1, 3, 5, 7, 9]
umu:3> [|to-s x| val x <- [1 .. 10] ]
val it : Cons = ["1", "2", "3", "4", "5", "6", "7", "8", "9", "10"]
umu:4> [|to-s x| val x <- [1 .. 10] if odd? x]
val it : Cons = ["1", "3", "5", "7", "9"]
umu:1> [|k, v| val k <- [@a, @b] val v <- [1 .. 3]]
val it : Cons = [(@a, 1), (@a, 2), (@a, 3), (@b, 1), (@b, 2), (@b, 3)]
umu:2> [|k: v:| val k <- [@a, @b] val v <- [1 .. 3]]
val it : Cons = [(k:@a v:1), (k:@a v:2), (k:@a v:3), (k:@b v:1), (k:@b v:2), (k:@b v:3)]
umu:3>

For advanced usage of the list comprehension, please refer to the database examples.

7. Lambda expression and Function definition

7.1. Lambda expression

umu:1> { x y -> x + y }
fun it = #<{ x y -> (+ x y) }>
umu:2> it 3 4
val it : Int = 7
umu:3>
umu:1> { x y -> x + y } 3
fun it = #<{ y -> (+ x y) }>
umu:2> it 4
val it : Int = 7
umu:3>
umu:1> { (x, y) -> 3 + 4 }
fun it = #<{ %a1 : Product -> %LET { %VAL x = (%a1)$1 %VAL y = (%a1)$2 %IN (+ 3 4) } }>
umu:2> it (3, 4)
val it : Int = 7
umu:3>

7.2. Function definition

7.2.1. Simple function

The declaration val binds a value to an identifier. Here, the value is a function object.

umu:1> val add = { x y -> x + y }
fun add = #<{ x y -> (+ x y) }>
umu:2> add 3 4
val it : Int = 7
umu:3>

The declaration fun is syntactic sugar for binding function objects.

umu:1> fun add' = x y -> x + y
fun add' = #<add': { x y -> (+ x y) }>
umu:2> add' 3 4
val it : Int = 7
umu:3>
umu:1> fun add'' = (x, y) -> x + y
fun add'' = #<add'': { %a1 : Product
    -> %LET { %VAL x = (%a1)$1 %VAL y = (%a1)$2 %IN (+ x y) }
    }>
umu:2> add'' (3, 4)
val it : Int = 7
umu:3>

7.2.2. Recursive function

A recursive function is defined with the declaration fun rec.

umu:1> fun rec factorial = x -> (    # Copy&Paste: 'umu/example/factorial.umu'
umu:2*     if x <= 1 then
umu:3*         1
umu:4*     else
umu:5*         x * factorial (x - 1)
umu:6* )
fun factorial = #<factorial: { x -> (%IF (<= x 1) %THEN 1 %ELSE (* x (factorial (- x 1)))) }>
umu:7> factorial 3
val it : Int = 6
umu:8>

8. Message and Send Expression

8.1. Message

Messages are classified as follows:

  • Instance message

    • Simple instance message

      • Unary Instance message

        • [Example] Int#to-s : String

        • [Example] Bool#not : Bool

        • [Example] List#join : String

      • Binary instance message

        • [Example] Int#+ : Int → Int

        • [Example] Int#to : Int → Interval

        • [Example] String#^ : String → String

        • [Example] List#cons : Top → List

        • [Example] List#join-by : String → String

        • [Example] Fun#apply : Top → Top

      • N-ary instance message

        • [Example] Int#to-by : Int → Int → Interval

        • [Example] List#foldr : Top → Fun → Top

        • [Example] Fun#apply-binary : Top → Top → Top

        • [Example] Fun#apply-nary : Top → Top → Morph → Top

    • Keyword instance message

      • [Example] Int#(to:Int) → Interval

      • [Example] Int#(to:Int by:Int) → Interval

      • [Example] List#(join:String) → String

  • Class message

    • Simple class message

      • [Example] &Bool.true : Bool

      • [Example] &Float.nan : Float

      • [Example] &Some.make : Top → Some

      • [Example] &Datum.make : Symbol → Top → Datum

      • [Example] &List.cons : Top → Morph → Morph

      • [Example] &Interval.make : Int → Int → Interval

      • [Example] &Interval.make-by : Int → Int → Int → Interval

    • Keyword class message

      • [Example] &Datum.(tag:Symbol contents:Top) → Datum

      • [Example] &List.(head:Top tail:Morph) → Morph

      • [Example] &Interval.(from:Int to:Int) → Interval

      • [Example] &Interval.(from:Int to:Int by:Int) → Interval

8.2. Instance message and Class message

Instance messages are ordinary messages.

A class message is a message to the class object created by the class expression &Foo. This is often used to create an instance of a class.

[!NOTE] Currently, the reserved word new for instantiation found in Java and Ruby is defined but not used. In the future, when user-defined functionality for classes is provided, the syntax will be new Foo x.

8.3. Simple message and Keyword message

Simple messages are messages that are curried and are suitable for mixed object-oriented and functional programming styles.

Keyword messages are non-curried messages and are more readable than simple messages when they involve complex arguments.

8.4. Function application and Message sending

umu:1> 3 + 4             # Infix orepator expression
val it : Int = 7
umu:2> (+) 3 4           # Infix operator as function object
val it : Int = 7
umu:3> ((+) 3) 4         # Partial application for first parameter
val it : Int = 7
umu:4> (+ 4) 3           # Partial application for second parameter
val it : Int = 7
umu:5> 3.(+ 4)           # Send binary message '+ 4' to integer object 3
val it : Int = 7
umu:6> 3.+ 4             # Brakets are optional
val it : Int = 7
umu:7> (3.+) 4           # Send only binary message keyword '+'
val it : Int = 7
umu:8> &(+) 3 4          # Binary message as function object
val it : Int = 7
umu:9> (&(+) 3) 4        # Partial application for first parameter
val it : Int = 7
umu:10> (+).apply-binary 3 4    # Send apply message to function object
val it : Int = 7
umu:11> (+).[3, 4]       # Another apply message notation (syntactic sugar)
val it : Int = 7

8.5. Message chaining, Pipelined application and Function composition

8.5.1. Message Chaining

OOP(object oriented programming) style

umu:1> [1, 4, 3, 2]
val it : Cons = [1, 4, 3, 2]
umu:2> [1, 4, 3, 2].sort
val it : Cons = [1, 2, 3, 4]
umu:3> [1, 4, 3, 2].sort.reverse
val it : Cons = [4, 3, 2, 1]
umu:4> [1, 4, 3, 2].sort.reverse.map to-s
val it : Cons = ["4", "3", "2", "1"]
umu:5> [1, 4, 3, 2].sort.reverse.map to-s.join-by "-"
val it : String = "4-3-2-1"
umu:6>

8.5.2. Pipelined Application

Like F#, Ocaml, Scala, Elixir …​ etc

umu:1> [1, 4, 3, 2] |> sort |> reverse |> map to-s |> join-by "-"
val it : String = "4-3-2-1"
umu:2>

8.5.3. Another Pipelined Application

Like a Haskell’s $-operator

umu:1> join-by "-" <| map to-s <| reverse <| sort [1, 4, 3, 2]
val it : String = "4-3-2-1"
umu:2>

8.5.4. Function Composition

umu:1> (sort >> reverse >> map to-s >> join-by "-") [1, 4, 3, 2]
val it : String = "4-3-2-1"
umu:2> [1, 4, 3, 2] |> sort >> reverse >> map to-s >> join-by "-"
val it : String = "4-3-2-1"
umu:3>

8.5.5. Another Function Composition

Like a Haskell’s point-free style

umu:1> (join-by "-" << map to-s << reverse << sort) [1, 4, 3, 2]
val it : String = "4-3-2-1"
umu:2> join-by "-" << map to-s << reverse << sort <| [1, 4, 3, 2]
val it : String = "4-3-2-1"
umu:3>

8.5.6. Traditional nested function application

Like Lisp, Python, Pascal, Fortran, …​ etc

umu:1> join-by "-" (map to-s (reverse (sort [1, 4, 3, 2])))
val it : String = "4-3-2-1"
umu:2>

9. Pattern (empty)

10. Branch Expression (empty)

10.1. if-Expression

10.2. cond-Expression

10.3. case-Expression

11. Interval

An interval is an object that represents a sequence of integers. Similar to list, but with the following differences:

  • The elements of a list can be any objects, but the elements of an interval can only be integers.

  • Intervals are memory efficient for long sequence because they consist of only three attributes:

    • current: current value

    • stop: stop value

    • step: step value

  • Intervals can be used not only to represent data, but also to control repetition. For example,

    • The procedural loop processing for (i = 1 ; i ⇐ 10 ; i++) { …​ } in C language

    • uses intervals to [1 .. 10].for-each { i → …​ } is written.

11.1. Makeing interval object

11.1.1. By interval-expression

umu:1> [1 .. 10]
val it : Interval = [1 .. 10 (+1)]
umu:2> [1, 3 .. 10]
val it : Interval = [1 .. 10 (+2)]
umu:3> it.contents
val it : Named = (current:1 stop:10 step:2)

11.1.2. By send-expression to instance object

11.1.2.1. Binary instance message

Send binary instance message 'Int#to : Int → Interval'

umu:1> 1.to 10
val it : Interval = [1 .. 10 (+1)]
umu:2> 1.to
fun it = #<{ %x_1 -> (%r).(to %x_1) }>
umu:3> it 10
val it : Interval = [1 .. 10 (+1)]
umu:4>

Send binary instance message 'Int#to-by : Int → Int → Interval'

umu:1> 1.to-by 10 2
val it : Interval = [1 .. 10 (+2)]
umu:2> 1.to-by
fun it = #<{ %x_1 %x_2 -> (%r).(to-by %x_1 %x_2) }>
umu:3> it 10
fun it = #<{ %x_2 -> (%r).(to-by %x_1 %x_2) }>
umu:4> it 2
val it : Interval = [1 .. 10 (+2)]
umu:5>
11.1.2.2. Keyword instance message

Send keyword instance message 'Int#(to:Int) → Interval' and 'Int#(to:Int by:Int) → Interval'

umu:1> 1.(to:10)
val it : Interval = [1 .. 10 (+1)]
umu:2> 1.(to:10 by:2)
val it : Interval = [1 .. 10 (+2)]
umu:3>

11.1.3. By send-expression to class object

11.1.3.1. Binary class message

Send binary class message '&Interval.make : Int → Int → Interval'

umu:1> &Interval.make 1 10
val it : Interval = [1 .. 10 (+1)]
umu:2> &Interval.make
fun it = #<{ %x_1 %x_2 -> (%r).(make %x_1 %x_2) }>
umu:3> it 1
fun it = #<{ %x_2 -> (%r).(make %x_1 %x_2) }>
umu:4> it 10
val it : Interval = [1 .. 10 (+1)]
umu:5>

Send binary class message '&Interval.make-by : Int → Int → Int → Interval'

umu:1> &Interval.make-by 1 10 2
val it : Interval = [1 .. 10 (+2)]
umu:2> &Interval.make-by
fun it = #<{ %x_1 %x_2 %x_3 -> (%r).(make-by %x_1 %x_2 %x_3) }>
umu:3> it 1
fun it = #<{ %x_2 %x_3 -> (%r).(make-by %x_1 %x_2 %x_3) }>
umu:4> it 10
fun it = #<{ %x_3 -> (%r).(make-by %x_1 %x_2 %x_3) }>
umu:5> it 2
val it : Interval = [1 .. 10 (+2)]
umu:6>
11.1.3.2. Keyword class message

Send keyword class message '&Interval.(from:Int to:Int) → Interval' and '&Interval.(from:Int to:Int by:Int) → Interval'

umu:1> &Interval.(from:1 to:10)
val it : Interval = [1 .. 10 (+1)]
umu:2> &Interval.(from:1 to:10 by:2)
val it : Interval = [1 .. 10 (+2)]
umu:3>

11.2. Operation to interval object

Like lists, intervals are a type of collection called morphs, so they can respond to the same messages as lists.

umu:1> [1 .. 10].to-list
val it : Cons = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
umu:2> [1, 3 .. 10].to-list
val it : Cons = [1, 3, 5, 7, 9]
umu:3> [1 .. 10].select odd?
val it : Cons = [1, 3, 5, 7, 9]
umu:4> [1 .. 10].map to-s
val it : Cons = ["1", "2", "3", "4", "5", "6", "7", "8", "9", "10"]
umu:5> [1 .. 10].select odd?.map to-s
val it : Cons = ["1", "3", "5", "7", "9"]
umu:6> [1 .. 3].for-each print
1
2
3
val it : Unit = ()
umu:7>

12. Delayed Evaluation and Stream (empty)

13. Input and Output (empty)

13.1. I/O (empty)

13.2. Sequential Expression

13.3. File and Directory

14. Reference (empty)

15. S-Expression (empty)

16. Module (empty)