Introduction

Koume is a programming language described by JSON.
Koume has features as follows.

  • first class functions and anonymous functions

  • first class continuations

  • tail recursion optimization

  • LISP like macros

  • message passing mechanism

Install

Browser

You can load Koume by using script tag.
Package of Koume is registered in global variable Koume.

<script src="koume.js"></script>

Node.js

If you want to use CLI, you add -g option.

npm install koume

You can load Koume package in Node.js.

var Koume = require('koume');

How to use

CLI

koume [-n] program.json

If you do not want to display the evaluated value, you can use -n option.

JavaScript

Now, package of Koume is loaded into variable Koume.

Koume.eval([ ["+", 1, 2] ]);

Syntax Reference

Literals

Numbers, Boolean values and null of JSON are literals.
Unquoted strings are not literals.

Reference to variable

A quoted JSON String is a reference of variable.

function call

[ "add", 1, 2 ]
[ { "q": [1, 2, 3] }, 0 ]
[ { "q": { "obj1": 1 } }, { "q": "obj1" } ]
[ { "q": "abc" }, 0 ]

You can call a function by an array of which function name or an object to apply specifies by first element and arguments specify by rest element.
To get an element of an array, object or string, the array is specified the object and the index is specified by then arguments.

Quote

{
  "q": {
    "obj": 1
  }
}

The object surrounded by "q" is the quoted object.

Constructing object

{
  "cons": {
    "obj1": [ "add", 1, 2 ],
    "obj2": 3
  }
}

The object is constructed by giving the pair of object name and a value.
The value is evaluated.
Only JSON object is the value of object.

Construction tuple

{
  "cons": {
    "obj1": {
      "function": {
        "args": [],
        "begin": [
          [ "add", 1, 2 ]
        ]
      }
    }
  }
}

The tuple is constructed by giving the pair of object name and a value.
The value is evaluated.
Any object is the value of object.

Blocks

{
  "begin": [
    [ "add", 1, 2 ],
    [ "add", 2, 3 ]
  ]
}

Expressions are blocked by surrounding "begin".
Last value of the expression will be return value.

Functions

{
  "function": {
    "args": [ "x", "y" ],
    "rest": "r",
    "begin": [
      [ "add", "x", "y", [ "r", 0 ] ]
    ]
  }
}

The function is created by "function". Arguments are specified by "args" and rest arguments specified by "rest".
To get the rest argument, you apply the index to rest variable.

Condition

{
  "if": {
    "cond": [ "eqv", "x", 0 ],
    "then": 1,
    "else": 2
  }
}

Evaluates "then" clause if the value of "cond" is not false, or "else" if the value is false.
Else clause is optional.

Multiple condition

{
  "cond": [
    {
      "case": ["eqv", "x", 2],
      "then": 4
    },
    {
      "case": ["eqv", "x", 3],
      "then": 6
    },
    {
      "case": true,
      "then": 0
    }
  ]
}

Appling case clause and evaluates then clause if the case clause is not false.

Variable definition

{
  "define": {
  	"x": 1,
  	"y": 2
  }
}

The values of object are bound to the keys of object.

Setting value to variable

{
  "set": {
  	"x": 1,
  	"y": 2
  }
}

The values of object are set to the keys of object.

Local varaible definition

{
  "let": {
    "vars": {
      "x": 1,
      "y": 2
    },
    "begin": [
      [ "add", "x", "y" ]
    ]
  }
}

The pairs of vars clause are the name and value of local variables.

Loop (named let)

{
  "let": {
    "name": "sum",
    "vars": {
      "x": 10,
      "y": 0
    },
    "begin": [
      {
        "if": {
          "cond": ["eqv", "x", 0],
          "then": "y",
          "else": ["sum", ["sub", "x", 1], ["add", "x", "y"]]
        }
      }
    ]
  }
}

Local function definition

{
  "letrec": {
    "vars": {
      "sum": {
        "function": {
          "args": ["x", "y"],
          "begin": [
            {
              "if": {
                "cond": ["eqv", "x", 0],
                "then": "y",
                "else": ["sum", ["sub", "x", 1], ["add", "x", "y"]]
              }
            }
          ]
        }
      }
    },
    "begin": [
      ["sum", 10, 0]
    ]
  }
}

The pairs of vars clause are the name and value of local functions.

Quasiquote

{
  "qq": {
    "obj1": "string",
    "obj2": {
      "obj3": { "uq": [ "add", 1, 2 ] }
    }
  }
}

Quasiquote is almost the same as quoting, an object surrounded by uq is evaluated.

Quasiquote of tuple

{
  "tq": {
    "obj1": "string",
    "obj2": {
      "obj3": { "uq": [ "add", 1, 2 ] }
    }
  }
}

Pattern matching

{
  "match": {
    "target": "x",
    "patterns": [
  	  {
  	    "pattern": {
  	  	  "aaaa": "a",
  	  	  "bbbb": {
  	  	    "cccc": "c",
  	  	  },
  	  	  "iiii": ["d", "e"]
  	  	},
  	    "begin": [["list", "a", "c", "d", "e"]]
  	  },
  	  {
  	    "pattern": {
  	      "jjjj": "a"
  	    },
  	    "begin": ["a"]
  	  }
  	]
  }
}

Maching the object of target clause.
Matched object will be bounded to the string in values of pattern.

String quote

{ "sq": "Welcome to ${y}, $x.aaaa.cccc and $x.dddd production" }

Replaces ${Variable name} in the given object to the string representation of the bounded variable.

delay

{
  "delay": ["+", "x", "y"]
}

Evaluates code given property of delay lazily.
The delayed code can be evaluated by force.
The evaluated result by executing force is memorized. The result of code shown as follows will be 765.

[
  {
    "define": {
      "x": 765,
      "promise": {
        "delay": "x"
      }
    }
  },
  ["force", "promise"],
  {
    "set": {
      "x": 961
    }
  },
  ["force", "promise"]
]

Macro

[
  {
    "defmacro": {
      "name": "aMacro",
      "patterns": [
        {
          "pattern": {
            "obj1": "a"
          },
          "begin": [
            {
              "qq": ["list", { "uq": "a" }]
            }
          ]
        }
      ]
    }
  },
  {
    "aMacro": {
      "obj1": 1
    }
  }
]

Replaces the syntax of macro to the value which matched the given pattern.

and

{ "and": [1, 2, 3] }

The last element of the given array is acquired if all values of the array are not false.
False is acquired if at least one value is false.
True is acquited if the array is empty.

or

{ "or": [false, 2, 3] }

The first non-false value is acquired if at least one value is not false.
False is acquired if all values is false or the array is empty.

Message Passing

{
  "message": {
    "extends": false,
    "messages": {
      "aaaa": 765,
      "bbbb": 346
    }
  }
}

Defines a function which has one argument and returns the value correspond to the key of the given object.
If any message is not found, the message is passed to extends clause.
If the extends clause is false, the function reports an error.

Tiny object-oriented programming can be realized by this mechanism.

[
  {
    "define": {
      "class": {
        "function": {
          "args": ["x"],
          "begin": [
            {
              "message": {
                "extends": false,
                "messages": {
                  "add": {
                    "function": {
                      "args": ["y"],
                      "begin": [
                        ["add", "x", "y"]
                      ]
                    }
                  }
                }
              }
            }
          ]
        }
      }
    }
  },
  {
    "define": {
      "obj": ["class", 765]
    }
  },
  [["obj", { "q": "add" }], 346]
]

Library Reference

Arithmetic Operations

Addition, Multiplication

[ "add", 1, 2, 3 ]
[ "+", 1, 2, 3 ]
[ "mul", 1, 2, 3 ]
[ "*", 1, 2, 3 ]

Adds or multiplys the arguments.

Subtraction, Division

[ "sub", 1, 2, 3 ]
[ "-", 1, 2, 3 ]
[ "div", 1, 2, 3 ]
[ "-", 1, 2, 3 ]

Subtracts or divides rest arguments from first arguments.

Division of Integer

[ "quotient", 13, 4 ]
[ "remainder", 13, 4 ]
[ "modulo", 13, 4 ]

"quotient" is the division of integer.
"remainder" and "modulo" returns the remainder of division.
The difference of "remainder" and "modulo" is as follows.

Table 1. The difference of remainder and modulo
First Second remainder modulo

13

4

1

1

-13

4

-1

3

13

-4

1

-3

-13

-4

-1

-1

Comparison

Equivalence

[ "eqv", 1, 2 ]
[ "equal", { "q": { "obj1": 222 } }, { "q": { "obj1": 222 } } ]

"eqv" returns true if the arguments are equal without considering data structure.
"equal" returns true if the arguments are equal with data structure.

Numbers

[ "=", 1, 1, 1, 1 ]
[ "!=", 1, 5, 3, 4 ]
[ "<", 1, 2, 3, 4 ]
[ "<=", 1, 2, 2, 3 ]
[ ">", 4, 3, 2, 1 ]
[ ">=", 3, 2, 2, 1 ]

Returns true if the arguments are equal, not equal, monotonically increasing, monotonically nondecreasing, monotonically decreasing, or monotonically nonincreasing.

Strings

[ "string=", "a", "a", "a" ]
[ "string!=", "a", "c", b" ]
[ "string<", "a", "aa", "b" ]
[ "string<=", "a", "a", "b" ]
[ "string>", "b", "aa", "a" ]
[ "string>=", "b", "a", "a" ]

Returns true if the arguments are equal, not equal, monotonically increasing, monotonically nondecreasing, monotonically decreasing, or monotonically nonincreasing.
Strings are compared by lexicographic order.

Strings (Ignoring cases)

[ "stringci=", "a", "A", "a" ]
[ "stringci!=", "a", "C", b" ]
[ "stringci<", "a", "Aa", "b" ]
[ "stringci<=", "a", "A", "b" ]
[ "stringci>", "b", "Aa", "a" ]
[ "stringci>=", "b", "A", "a" ]

Compares the arguments with ignoring cases.

Logical

[ "not", false ]

Returns true if the argument is false, or false if the argument is not false.

Mathematical Functions

Trigonometric Functions

[ "sin", 0 ]
[ "cos", 0 ]
[ "tan", 0 ]

Inverted Trigonometric Functions

[ "asin", 0 ]
[ "acos", 0 ]
[ "atan", 1 ]

Returns NaN if the argument is out of range.

Exponential or Logarithmic Functions

[ "exp", 0 ]
[ "log", 1 ]

Returns NaN if the argument is out of range.

Power

[ "expt", 2, 3 ]

Ceiling or Floor Functions

[ "floor", 2.3 ]
[ "ceiling", 2.3 ]
[ "truncate", 2.3 ]
[ "round", 2.3 ]

Maximum or Minimum

[ "max", 1, 3, 4, 2 ]
[ "min", 1, 3, 4, 2 ]

Returns the largest or smallest value in the given arguments.

Type Predicates

[ "numberp", 2.5 ]
[ "integerp", 2 ]
[ "booleanp", false ]
[ "nullp", null ]
[ "arrayp", { "q": [1] } ]
[ "objectp", { "q": { "obj": 1 } } ]
[ "functionp", { "function": { "args": [], "begin": [1] } } ]

Returns true if the argument is number, integer, boolean value, null, array, object (including array) or function (including continuation) respectively.

Array Operation

Array Construction

[ "list", 1, 2, 3 ]

Constructs an array of the given arguments.

First element or rest elements of Array

[ "first", { "q": [1, 2, 3] } ]
[ "rest", { "q": [1, 2, 3] } ]

Returns first element or rest elements of the given array.

Setting Property

[ "setprop", "obj1", { "q": { "obj1": 1 } }, 2 ]

Sets the value to the given object.

Concatenation

[ "concat", { "q": [1, 2, 3] }, { "q": [4, 5, 6] }, { "q": [7, 8, 9] } ]

Concatenates the given arrays.

map of Array

[ "arraymap", "add", { "q": [1, 2, 3] }, { "q": [4, 5, 6] }, { "q": [7, 8] } ]

"arraymap" applies the first element to the each elements of the arrays.
In this example, it applies [ "add", 1, 4, 7 ] and [ "add", 2, 5, 8 ] and the result is [12, 15].

String Operation

Concatenation of Strings

[ "stringAppend", { "q": "abc" }, { "q": "def" }, { "q": "ghi" } ]

Concatenates the given strings.

Substring

[ "substring", { "q": "abcde" }, 1, 3 ]

Returns substring from the second argument (inclusive) to the third argument (exclusive).

Continuation

[
  "callcc",
  {
    "function": {
      "args": ["k"],
      "begin": [
        ["k", 765]
      ]
    }
  }
]

Calls the function with current continuation.

The result of below example will be 765.

[
  {
    "define": {
      "s": null
    }
  },
  [
    "add",
    346,
    [
      "callcc",
      {
        "function": {
          "args": ["k"],
          "begin": [
            {
              "set": { "s": "k" }
            },
            961
          ]
        }
      }
    ]
  ],
  ["s", 765]
]

Others

Appling Function

[ "apply", "add", { "q": [1, 2, 3] } ]

Applies the arguments given by an array to the given function.

Executing delayed code (promise)

[ "force", "promise" ]

Executes delayed code (promise). The result is memorized.

map Of Object

[ "objectmap", "sub", { "q": { "obj1": 1, "obj2": 2 } } ]

"arraymap" applies the first element to the each elements of the objects.

Conversion from Number to String

[ "numberToString", 100, 16 ]

Converts first argument by radix given by second argument.
The radix must be between 2 to 36.
The radix is 10 if the radix is not given.

Conversion from String to Number

[ "stringToInteger", "100", 8 ]

Converts first argument by radix given by second argument.
The radix must be between 2 to 36.
The radix is 10 if the radix is not given.

Conversion from String to Number

[ "stringToNumber", "100.3" ]

Keys of Object

[ "keys", { "q": { "obj1": 1, "obj2": 2 } } ]

Returns an array of the keys of the given object.

Length

[ "length", { "q": [1, 2, 3] } ]
[ "length", { "q": "abc" } ]

Returns the length of the given array or string.

Multiple Values

[ "value", 1, 2, { "function": { "args": [], "begin": [1] } } ]

All elements of arrays must be JSON representive values.
But elements of multiple values may be non JSON representive values.

Output to Console

[ "p", { "q": "console output" } ]

Outputs to console.

String Representation

[ "toString", { "q": [1, 2, 3] } ]

Returns the string representation of the argument.

Error Report

[ "error", { "q": "Error occurred" } ]

Reports an error and quit the program.

Generating a symbol

[ "gensym" ]

Generates a symbol. This function will be used by generating a variable name which is not captured.