Janet is a functional (and imperative) cross-platform interpreted (and compiled) lisp-inspired language with batteries-included api that makes a good system scripting language, or a language to embed in other programs.
The entire language (core library, interpreter, compiler, assembler, PEG) is less than 1MB.
Starting off with minimum required to do anything
Data Types:
Comments start with a
#
nil
true
, false
small-letters
with hypens):symbols
starting with colon1
-1.1
1e10
(unlike js, 4r100
= 16: rn
= base n
)Data Structures:
"strings are in double quotes"
or in n`s like lua’s [[ ... ]]
@
strings[1 2 3]
list of values@
tuples{:keyword "value"}
pairs (or js objects, or clisp plists)@
structsBindings:
anything with paren tuple
(...)
is “called” (conventionally called “forms”)
Variable definition: ([def | var] <name> <expr>)
def
or mutable var
<expr>
to a symbol <name>
(let [<name> <expr> <name2> <expr2>] ...)
for multiple def
bindings sugarVariable reassignment: (set <name> <expr>)
var
name
must exists and be an initialized value or a declared datastructureFunction definition: ([defn | fn] [<name>] <args> <body>)
name
is optional in case of fn
. functions form closure.[...]
but can be destructured from struct
s&
for variadic arguments: [a b c & rest]
(...)
defn
is short for binding fn
to <name>
using def
Conditionals:
If conditional: (if <expr> <true-form> [<false-form>])
false-form
but cond
is false
, then returns nil
Cond conditional: (cond <expr> (body) <expr2> (body2) <expr3> (body3))
Case conditional:
switch
statements elsewhereWhen conditional:
if
without false-form
; returns nil
on false
implicitlyLoops:
OPINION: Avoiding mutable loops and stick to functional paradigm
While loop: (while <cond> <body>)
vars
with side effects in bodyFor loop: (for <var> <start-expr> <end-expr> <body>)
loop loop: (loop [<var> <verb> <values> <modifiers> <cond>] <body>)
Ex1: (loop [i :range [0 10] :when (even? i)] (print i))
i
is a var, :range
is a verb, :when
is a modifierEx2: (loop [name :in names] (print name))
name
is a var, :in
is a verb and names
is a listEx2 can be written using each
and map
resp as:
(each name names (print name))
(map print names)
Ex3: (loop [[k v] :pairs some_struct] (print k " -> " v))
Arithmetic (<op> <expr> <expr2>)
and Comparisons (<cmp> <expr> <expr2>)
work as usual:
(not= <expr> <expr2>)
for checking unequality(deep= <mutable> <mutable>)
for checking contents of mutable structures