Wisp is a lisp like language written in C.
λwisp> + 1 2 4
7
λwisp> ** 2 2 2 2
256.000000
λwisp> list (/ 5 2) (// 5 2) (% 5 2)
(2.500000 2 1)
λwisp> = {x} 5
()
λwisp> x
5
Functions are defined using the f keyword. Functions are first class citizens and can be passed around. Lambda functions are defined using the \ keyword.
λwisp> f {is-even?} {n} {== (% n 2) 0}
()
λwisp> is-even? 4
true
λwisp> is-even? 5
false
λwisp> = {is-odd?} (\ {n} {not (is-even? n)})
()
λwisp> is-odd? 4
false
Functions support multiple arguments and support partial application. If a function is called with fewer arguments than it expects, it returns a new function which is bound to the arguments passed, and can be called with the remaining arguments later. This can be repeated until all arguments are passed, only then the function is evaluated.
λwisp> f {triplet-app} {a b c} {+ a b c}
()
λwisp> = {pair-add-5} {triplet-add 5}
()
λwisp> = {add-15} (pair-add-5 10)
()
λwisp> add-15 10
25
Pipes can be created with |> (|> is the ligature for |>) allow composition of functions in an ergonomic way. They also support templates using the ? syntax. ? in statements is replaced with the result of the previous statement, or the initial value if it is the first statement. If there is no ? in the statement, the result is appended to the end of the statement.
(print (|> "hello" {
{+ ? " world!!"}
{+ "!!"}
{str-split}
{reduce-left
( {acc e} {+ acc " " e})}
}))"! ! h e l l o w o r l d ! !"The builtin |> eagerly evaluates pipes but lazily evaluated pipes can be made in wisp itself.
(f {+>} {pipe-line init} {
(|> init pipe-line)
})Pipes created using +> are lazily evaluated. and can be executed separately from creation.
wisp> f {double} {x} {* n 2}
()
wisp> f {square} {x} {** n 2}
()
wisp> f {halve} {a b} {/ n 2}
()
wisp> = {double-square-halve} (+> {{double} {square} {halve}})
()
wisp> double-square-halve 10
200.000000
wisp> = {double-cube-quarter} (+> {{+ ? ?} {** ? 3} {/ ? 4}})
()
wisp> double-cube-quarter 2
16.000000λwisp> f {double} {x} {* n 2}
()
λwisp> f {square} {x} {** n 2}
()
λwisp> f {halve} {a b} {/ n 2}
()
λwisp> = {double-square-halve} (+> {{double} {square} {halve}})
()
λwisp> double-square-halve 10
200.000000
λwisp> = {double-cube-quarter} (+> {{+ ? ?} {** ? 3} {/ ? 4}})
()
λwisp> double-cube-quarter 2
16.000000
λwisp> filter is-even? {1 2 3 4 5 7 8 9 10}
{2 4 8 10}
λwisp> = {strings} {"a" "nice" "list" "of" "strings"}
()
λwisp> map len strings
{1 4 4 2 7}
λwisp> reduce-left + strings
"anicelistofstrings"
λwisp> reduce-right (\ {acc e} {+ acc " " e}) strings
"strings of list nice a"
λwisp> f {add-with-space} {a b} {+ a " " b}
()
λwisp> fold-left add-with-space "Start:" strings
"Start: a nice list of strings"
λwisp> fold-right add-with-space "End:" strings
"End: strings of list nice a"
(f {fib} {n} {
if (< n 2)
{n}
{+ (fib (- n 1)) (fib (- n 2))}
})
# (== name "main") is used to check if the script is being run as a script or being imported as a module, like in python
(if (== name "main")
{print (fib 30)}
)55220 smtp.example.com ESMTP Postfix HELO client.example.com 250 smtp.example.com MAIL FROM: <me@mydomain.com> 250 Ok RCPT TO: <hi@zaeem.dev> 250 Ok DATA 354 End data with <CR><LF>.<CR><LF> From: "Me" <me@mydomain.com> To: "Jasir" <hi@zaeem.dev> Date: $Tue, 16 Sep 2025 17:17:43 GMT Subject: Complaint Mail Hi Jasir,Your site gave me a virus. I am very upset.
Yours truly,
Me
.
250 Ok: queued as 12345
QUIT
221 Bye
You can reach me at mailto:hi@zaeem.dev