-
Notifications
You must be signed in to change notification settings - Fork 0
5) Syntax
#. This is a comment.
#. Comments are single-line.
#.Whitespace at the beginning is not necessary.
Spaces and newlines can be used interchangeably – either for readability or parser cues.
#. Readability
a\#["asdf""1324""xyz"]& a1
#. VS
a \ #["asdf" "1324" "xyz"]
& a 1
#. Parser Cues
1234567
#. VS
1234 567
In addition, you may need to use a semicolon to separate an expression.
a\@5;[1 2 a 4;5]
#. VS
a\@5[1 2 a 4 5]
What's the difference? Well, the first line is 2 expressions: a declaration and a list, but the second line is merely an application nested inside a declaration. Also, inside the list, there is a 1-argument application for the first line, but the second line contains a 2-argument application.
This is usually a fallback value for functions that need a separate falsy value from F
itself.
U
T #. true
F #. false
Numbers can have a precision of up to 1000 as set with the E
function. Negation is achieved with _
.
1234
1.234
.234
_0.234
5.8e6
5.8e_6
oo #. Infinity
Hex, binary, and octal literals are also allowed and can have decimals:
0b1011
0o1842
0x1a5f
Strings are a bit strange in terms of escaping.
"asdf" #. => asdf
"a\sdf" #. => a\sdf
"a\\sdf" #. => a\sdf
"a\\\sdf" #. => a\\sdf
"a\\\\sdf" #. => a\\sdf
"\"asdf" #. => "asdf
"asdf\\" #. => asdf\
"as
df" #. Strings can be multiline.
#. You can leave out the trailing quote at the end of a program.
"asdf
Lists are zero-indexed and can contain all data types.
[1 2 3 4]
[1 "asdf" 2 3 4]
[1"asdf"2 3 4] #. Spaces are only necessary for parser cues
#. You can leave out the trailing bracket at the end of a program.
[1 2 3 4 "asdf"
List comprehensions provide an alternate way to construct lists.
[+1 #x ? x\[1 2 3 4]] #. => [2 3 4 5]
#. basic list comprehension
[+1 #x ? x\[1 2 3 4 5 6]; < #x 4] #. => [2 3 4]
#. list comprehension with a filter
[[x;y] ? x\[1 2 3 4]; y\[1 2 3 4]] #. => [[1 1][1 2][1 3][1 4][2 1] ... ]
#. multiple list comprehension
[[x;y] ? x\[1 2 3 4]; y\[1 2 3 4]; < #x #y] #. => [[1 2][1 3][1 4][2 3][2 4] ... ]
#. multiple list comprehension with a filter
Objects can take strings, numbers, and function names as object keys. Keys and values are separated by backslashes.
{
0\5;
a\7;
"#\,"\7
}
#. note that semicolons are optional in most cases
This executes everything inside it before returning the last result. This can also be used as a parser cue.
(5 6 7) #. => 7
("asdf" 7) #. => 7
#. You can leave out the trailing parenthesis at the end of a program.
("asdf" 7
You can force anything to be applied by wrapping it inside an expression list.
Almost the same syntax as an object, but with a leading .
and an optional default expression at the end. These act like functions.
f\ .{
0\ 1;
1\ 3;
5\ ol"ayy";
@["not 0, 1, or 5: "; #0]
}
f 0 #. => 1
f 1 #. => 3
f 5 #. => "ayy"
f "asdf" #. => ["not 0, 1, or 5"; "asdf"]
An alternative way to define pattern matching is to use the following syntax:
f 0\1;
f 1\3;
f 5\ol"ayy";
f ..\@["not 0, 1, or 5: "; #0];
Names are valid function/variable names matched by the regex /[^ \n;0-9".[]\(){}@#TF?`]+/g
. You may need to separate names with spaces; for example, +-
is very different from + -
.
Name applications try to find from user-defined variable names before using builtin function names.
Basically, taking a data type and applying it to another data type. Applications are right-associative, meaning they will be parsed right-to-left when possible. You may need parentheses if you want an application to be parsed from the left.
#. f is the function, x is applied to f
f x
#. f is the function, x is applied to f, y is applied to f x
(f x)y
Builtin functions (such as those in cm
) will always have either 1 or 2 curried arguments. The parser will attempt to apply 2 arguments to any fn
s; however, you can use expression lists to apply more arguments ((((f x y)z)a)b
).
Forces a function name to take exactly one argument through '
. This is considered a parser cue.
(& ! 3) 2
#. VS
& '! 3 2
Forces a function name to apply its arguments in reverse through ^
. This is considered a parser cue.
- 3 2
#. Is equivalent to
^- 2 3
Acts like a partial application to ss
. Each composition can take any applicable datatype.
a.b.c #. => ss [a;b;c]
(+8 . *9 . _) 5 #. => _5 => _45 => _37
All functions with more than one argument curry their arguments, allowing for partial applications.
#. + takes 2 arguments, so this will return a partial application
+5
Wonder's lambda system uses a zero-indexed version of De Bruijn indices. @
is a lambda that takes in one argument to apply to an expression. Lambdas are treated as normal functions. #
in front of an integer n
references the n
th nearest nested lambda's argument.
#. A lambda that takes an argument and returns that argument
@#0
#. aka the I-combinator
#. A lambda that takes 2 arguments via currying and returns the first argument
#. aka the K-combinator
@@#1
For greatly increased readability, you can use lambdas with named arguments.
#. I-combinator using a named argument
a\\#a
#. K-combinator using a named argument
a\\b\\#b
Takes an expression and stores it to a valid name for future use. Variables can be overwritten. The parser will try to guess whether a variable should be applied or not; adding #
in front of a variable will force it to be a value rather than an applicable function.
#. Store 5 to a
a\5
#. Store @#0 to b
b\@#0
#. Calling variables as a value using ref
#a #. => 5
#. Calling variables as functions
b 8 #. => 8
Note that ref
can be used on any applicable datatype that is not pt
.
Takes a condition expression and 2 expressions, evaluating one or the other depending on the condition's truth value.
(T ? T ? F)
#. is the same as
(T ? ? F)
#. or
(T ? T ?)
#. or
(T ? ?)
(T ? 5 ? 6) #. => 5
(F ? 5 ? 6) #. => 6
#. each non-condition part can take multiple expressions
(T ? +4 5;-6 7 ? 9 8 6)
Wonder currently uses the XRegExp flavor, although there are plans to create a custom flavor.
`.+\s` #. A basic regex
`.+\s`g #. A regex with the global flag
Regex applications act as matches using mstr
.
This is an easy way to evaluate an expression with a local scope and custom variable. Each evaluation block takes a series of expressions wrapped in ()
, followed by a valid variable declaration.
(+1x)x\5 #. => 6
((+#x#y)y\6)x\5 #. => 11
((+#x#x)x\6)x\5 #. => 12, because the inner scope overrides the outer scope