$ git clone https://github.com/sukovanej/mplisp
$ cd mplisp
$ pip3 install -U .
(def fact
(lambda (x)
(if (> x 1)
(* x (fact (- x 1)))
1)))
(fact 20)
Generating x^2 function
(map (lambda (x) (list x (* x x))) (range -5 5))
Apply list values as function arguments
(apply + (range 20))
./test/run.sh
$ mplisp-repl
mplisp>
An expression is evaluated if first item in a list is a special form or a function. Other items are evaluated in unspecified order. Symbol is evaluated to it's value in it's environment and a number is evaluated to it's value.
mplisp> 1
-> 1
mplisp> 3
-> 3
Expression (lambda (param1 param2 ...) (body))
creates a new function.
mplisp> (lambda (x) x)
-> <function create_lambda.<locals>.func at 0x10be461e0>
New symbol in an environment can be defined using a special form def
. As every list must be evaluated to
a value, applied def
is evaluated to None.
mplisp> (def a 3)
-> None
mplisp> a
-> 3
Every symbol can be defined only once.
mplisp> (def a 3)
-> None
mplisp> (def a 4)
-> [ error : a already defined ]
Knowing lambda
and def
forms, one can easily create a function in local environment as follow.
mplisp> (def double (lambda (x) (* 2 x)))
-> None
prompt> double
-> <function create_lambda.<locals>.func at 0x10be46268>
prompt> (double 3)
-> 6
*
is a builtin function, it simply multiplies all arguments and returns the result. There similar
functions for basic arithmetic:
+
plus operator-
minus operator*
multiply/
divide%
modulo
An expression can be evaluated to bool. False
, #f
and 0
are
evaluated to false and every other value is evaluated to true.
mplisp> #t
-> True
mplisp> #f
-> False
An expression can be converted to bool using ->bool?
function.
mplisp> (->bool? 3)
-> True
mplisp> (->bool? 0)
-> False
Type can be checked using bool?
function.
mplisp> (bool? 0)
-> False
mplisp> (bool? #t)
-> True
mplisp> (bool? 1)
-> False
mplisp> (bool? #f)
-> True
mplisp> (bool? (->bool? 1))
-> True
Binary logical operators:
(and? a b)
returns a and b(or? a b)
returns a or b(== a b)
returns a equals b(!= a b)
returns a doesnt equal b(> a b)
returns a is greater than b(< a b)
returns a is smaller than b
Unary logical operators:
(not? a)
returns a is#f
if
form evaluates an expression depending on the condition. General form is
(if condition expr1 expr2)
If the condition is evaluated to true, expr1
is evaluated, otherwise expr2
is.
Simple example is max
function.
mplisp> (def max (lambda (a b) (if (> a b) a b)))
-> None
mplisp> (max 1 2)
-> 2
mplisp> (max 2 1)
-> 2
String are recognized by apostrophe ('
or "
). For example
mplisp> "hello world"
-> hello world
mplisp> 'hello world'
-> hello world
mplisp> hello world
[ error : hello not found ]
Lets assume sample code below (file sample.mplisp).
; Check whether the {value} is in the {list}
; Usage: (list-in {list} {value})
(def list-in
(lambda (l val)
(apply or? (map (lambda (x) (== val x)) l))))
One can easily run unittests using builtin function assert!
and assert-equal!
.
Lets and tests to the file.
; TESTS
(assert! (list-in (list 1 2) 1))
(assert! (list-in (list 1 2) 2))
(assert! (not? (list-in (list 1 2) 3)))
; /TESTS
By this bash script sample is run without the tests
mplisp sample.mplisp
and with --test
or -t
flag one can enforce the interpreter
to run also all the tests.
mplisp -t sample.mplisp