An M-expression-based Lisp descendant implemented on top of Python3.6 and SLY
Misp supports both the Lisp-like S-expression syntax as well as what I'm calling "M-expression syntax":
M-expression Syntax | S-expression Syntax |
---|---|
+[1 2 3] |
(+ 1 2 3) |
Def[x 100] |
(Def x 100) |
side-effects-please[] |
(side-effects-please) |
The following is an implementation of a function that recursively generates the n-th fibnonacci number:
Defn[fib[n]
If[Or[=[n 0] =[n 1]]
n
+[ fib[-[n 1]] fib[-[n 2]] ]
]
]
fib[20]
The program returns 6765
.
An expression of the form
f[a b c d]
can also be written in postfix form by putting the function at the end of the list and separating it from the arguments with the double-pipe (||
) delimiter:
[a b c d || f]
As an example, the following two expressions both return 10
:
+[1 2 3 4]
[1 2 3 4 || +]
- Truthiness
:F
- A keyword representing the boolean false value
Nil
- A symbol bound to the empty list
- Is also considered false
:T
- A keyword representing the boolean true value
- Not uniquely "true" since anything that is not
:F
orNil
is considered true.
-
+
,-
,*
,/
- Arithmetic operators. Each can take a variable number of arguments
-
=[x y z ...]
- Returns
:T
if all arguments are equal
- Returns
-
Head[list]
- Like
car
. Returns the first element of the list argument
- Like
-
Body[list]
- Like
cdr
. Returns a list of all but the first elements in a list
- Like
-
Fn[{x y z ...} body]
- Replaces Lisp's
lambda
. - Accepts a list of formal parameters, and a body.
Fn[{x} *[x x]][12]
returns144
- Replaces Lisp's
-
Def[symbol value]
- Declares and assigns to
symbol
the value of the expressionvalue
Def[x 100]
binds the symbolx
to the number100
in the current environment (scope)- Returns the
value
- Declares and assigns to
-
Defn[f[x y z ...] body]
- Equivalent to
Def[f Fn[{x y z ...} body]]
- Returns the procedure that gets assigned to
f
- Equivalent to
-
Set![x v]
- Sets the previously-defined symbol
x
to the value ofv
- Returns
v
- Sets the previously-defined symbol
-
Do[e1 e2 e3 ... en]
-
Evaluates
e1
,e2
, ...en
in order -
Returns the value of
en
-
The following program returns
1
after settingx
to3
andy
to1
:Do[ Def[x 1] Def[y x] Set![x 3] y ]
-
-
Let[{x v1 y v2 ...} body]
- Binds
x
tov1
,y
tov2
, etc., then evaluatesbody
- The variable bindings are only valid during the execution of
body
- Equivalent to the immediately invoked lambda expression:
Fn[{x y ...} body][v1 v2 ...]
- Binds
-
Eval[expr]
- Evaluates a quoted expression
Eval[{+ 1 2 3}]
andEval['(+ 1 2 3)]
both return6
-
Apply[f {arg1 arg2 arg3 ...}]
- Applies the callable function bound to
f
upon the argument list - Eqivalent to
f[arg1 arg2 arg3 ...]
- Applies the callable function bound to
-
Quote[expression]
or'expression
- Returns
expression
, unevaluated, as an abstract syntax tree
- Returns
-
List[v1 v2 v3 ...]
or{v1 v2 v3 ...}
- Returns the abstract syntax tree representing a list which contains the specified values
- Not the same as
'(v1 v2 v3 ...)
orQuote[(v1 v2 v3)]
sinceList
evaluates each of its argumentsvi
before putting putting them in a quoted list
-
Quasiquote[expression]
or~expression
- Returns
expression
with every instance ofUnquote[subexpression]
replaced with the value ofsubexpression
- Note: A quasiquoted expression -- in general -- evaluates to an abstract syntax tree
- Returns
-
Unquote[expression]
or$expression
- Cannot be evaluated outside of a quasiquote expression
- When inside of a quasiquote expression,
Unquote[expression]
will be replaced with the valueexpression
evaluates to
-
If[condition e1 e2]
- Returns the value of
e1
ifcondition
is "truthy" (neither:F
norNil
), otherwise, returns the value ofe2
- Returns the value of
-
Print[v1 v2 v3 ... vn]
- Prints
v1
,v2
, etc to stdout. - Returns the value of
vn
- Prints