Skip to content

5) Syntax

Benjamin Pang edited this page Apr 16, 2018 · 35 revisions

Comments

#. This is a comment.
#. Comments are single-line.
#.Whitespace at the beginning is not necessary.

Separators

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.

Types

Undefined u

This is usually a fallback value for functions that need a separate falsy value from F itself.

U

Boolean bool

T #. true
F #. false

Number num

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

String str

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

List ls

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 Comprehension lsc

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

Object obj

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

Expression List arg

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.

Pattern matching pm

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];

Name fn

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.

Application app

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 fns; however, you can use expression lists to apply more arguments ((((f x y)z)a)b).

Unary Name ufn

Forces a function name to take exactly one argument through '. This is considered a parser cue.

(& ! 3) 2
#. VS
& '! 3 2

Reverse Name tfn

Forces a function name to apply its arguments in reverse through ^. This is considered a parser cue.

- 3 2
#. Is equivalent to
^- 2 3

Composition comp

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

Partial Application pt

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

Lambda def and Argument a

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 nth 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

Variable Declaration var and Variable Reference ref

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.

Conditional cond

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)

Regular Expression rgx

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.

Evaluation Block ev

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