Skip to content

Getting Started

Just Drag, Drop, and Attach the block

To start constructing a program in MNL, drag a block from the toolbox to the playground area and attach it to another block. A main block (1) acts as the parent block. The main block holds the declaration block only.

  1. 🙋‍♂️ The black block with MNL on the top.

workspace workspace

Fig. 1: Drag, drop, and attach the block

Declaration

A declaration means binding a name to a value. In MNL, there are two declaration blocks: variable and function. The function block is a simple model of binding a variable block with a lambda block.

Variable

Creating a complete variable block requires an identity block and an expression block. The example below shows how to give a variable_in_MNL name to the string MNL is easy to learn. When users need the MNL is easy to learn value, they access the bound variable by name variable_in_MNL.

workspace

Fig. 2: Variable binding

val variable_in_MNL = "MNL is easy to learn"
val variable_in_MNL = "MNL is easy to learn"

Expression

Expression is a value. Every expression block has its value, including operators, constants, and constructors.

Operator

There are two types of primitive operators based on input: unary (1) and binary (2) operators.

  1. 🙋‍♂️ Take one input.
  2. 🙋‍♂️ Take two inputs.

Unary

workspace

Fig. 3: Boolean Operator Not

(not false)
(!false)

workspace

Fig. 4: Boolean Operator Not - binding

val unary_operator = (not false)
val unary_operator = (!false)

Binary

workspace

Fig. 5: Arithmetic Operator

(111 + 222)
(111 + 222)

workspace

Fig. 6: Arithmetic Operator - binding

fun increment (n) = (1 + n)
  val three = increment(2)
def increment (n: Float) : Float = (1 + n)
val three = increment(2)

Selection

workspace

Fig. 7: Selection

(* SML does not support type inference for a tuple as a parameter. 
Other ML languages may support the syntax below. *)
fun the_greater (pair) = if ((#1 pair) < (#2 pair))
  then
    (#2 pair)
  else
    (#1 pair)

val two_or_three = the_greater((2, 3))
def the_greater (pair: (Float, Float)) : Float = if ((pair(0)) < (pair(1)))
  then
    (pair(1))
  else
    (pair(0))

val two_or_three = the_greater((2, 3))

Sequence

A sequence is a collection of expressions that are evaluated sequentially. The last expression is the type and value of a sequence block.

workspace workspace

Fig. 8: Sequence

val sequence = (
  "Hi, there!";
  "I am MNL"
)
val sequence = (() =>{
  "Hi, there!"
  "I am MNL"
})()

Pattern Matching

workspace

Fig. 9: Pattern Matching

fun translator_good_morning (lang_code) = case lang_code
  of "en" => "Good Morning"
  | "de" => "Guten Morgen"
  | "jp" => "おはよう"
  | "id" => "Selamat Pagi"
  |  _   => "Unknown"

val greetings = translator_good_morning("de")
def translator_good_morning (lang_code: String) : String = lang_code match
  case "en" => "Good Morning"
  case "de" => "Guten Morgen"
  case "jp" => "おはよう"
  case "id" => "Selamat Pagi"
  case _   => "Unknown"

val greetings = translator_good_morning("de")

Let-in

Let-in is a local binding of the declaration(s) in the expression.

workspace

Fig. 10: Let-in

val let_in = let
  val hello = "Hello "
  fun speech (name) = (hello ^ name)
  in
    speech("MNL")
  end
val let_in = (() => {
  val hello = "Hello "
  def speech (name: String) : String = (hello + name)

  speech("MNL")
})()