Skip to content

Commit 1a8e4a7

Browse files
committed
Implement infix notation
This commit also involves rewriting many parsers and refactoring the end-to-end tests.
1 parent aebee21 commit 1a8e4a7

File tree

9 files changed

+701
-291
lines changed

9 files changed

+701
-291
lines changed

README.md

Lines changed: 27 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -164,6 +164,32 @@ and `@runtime`.
164164
Currently only `@function`, `@lookup`, `@index`, and `@apply` have syntax
165165
sugars.
166166

167+
#### Infix notation
168+
169+
Infix notation can be used to apply binary functions (like `a => b => …`). For
170+
example, the expression `x f y` desugars to `:f(y)(x)`. Here's another example:
171+
172+
```
173+
{
174+
cons: b => a => { :a, :b }
175+
list: 1 cons (2 cons 3) // evaluates to `{ 1, { 2, 3 } }`
176+
}
177+
```
178+
179+
The standard library contains symbolically-named functions for arithmetic and
180+
other familiar binary operations. For example, `1 + 2 - 3` is `0`. Also
181+
included in the standard library are the functions`|>` (pipe) and `>>` (flow):
182+
183+
```
184+
{
185+
// `>>` composes functions from left to right
186+
append_bc: :atom.append(b) >> :atom.append(c)
187+
188+
// `|>` pipes an argument into a function
189+
abc: a |> :append_bc
190+
}
191+
```
192+
167193
### Semantics
168194

169195
Please is a functional programming language. Currently all functions are pure,
@@ -197,7 +223,7 @@ possible. For example, this program compiles to the literal value `2` (no
197223
computation will occur at runtime):
198224

199225
```
200-
:integer.add(1)(1)
226+
1 + 1
201227
```
202228

203229
There's currently no module system and all Please programs are single files, but

examples/fibonacci.plz

Lines changed: 16 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -1,24 +1,23 @@
11
{
22
fibonacci: n => {
3-
@if, :integer.less_than(2)(:n)
3+
@if
4+
condition: :n < 2
45
then: :n
5-
else: :integer.add(
6-
:fibonacci(:integer.subtract(2)(:n))
7-
)(
8-
:fibonacci(:integer.subtract(1)(:n))
9-
)
6+
else: :fibonacci(:n - 1) + :fibonacci(:n - 2)
107
}
118

12-
input: { @runtime, context => :context.arguments.lookup(input) }
9+
input: {
10+
@runtime
11+
context => :context.arguments.lookup(input)
12+
}
1313

14-
output: :apply(:input)(
15-
:match({
16-
none: _ => "missing input argument"
17-
some: input => {
18-
@if, :natural_number.is(:input)
19-
then: :fibonacci(:input)
20-
else: "input must be a natural number"
21-
}
22-
})
23-
)
14+
output: :input match {
15+
none: _ => "missing input argument"
16+
some: input => {
17+
@if
18+
condition: :natural_number.is(:input)
19+
then: :fibonacci(:input)
20+
else: "input must be a natural number"
21+
}
22+
}
2423
}.output

examples/kitchen-sink.plz

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44
bar: :foo
55
sky_is_blue: :boolean.not(false)
66
colors: { red, green, blue }
7-
two: :integer.add(1)(1)
7+
two: 1 + 1
88
add_one: :integer.add(1)
99
three: :add_one(:two)
1010
function: x => { value: :x }
Lines changed: 13 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -1,17 +1,15 @@
1-
{@runtime, context =>
2-
:flow(
3-
:match({
1+
/**
2+
* Given CLI arguments like `--variable=FOO`, looks up the environment
3+
* variable named `FOO`.
4+
*/
5+
{
6+
@runtime
7+
context =>
8+
:context.arguments.lookup(variable) match {
49
none: {}
5-
some: :flow(
6-
:match({
7-
none: {}
8-
some: :identity
9-
})
10-
)(
11-
:context.environment.lookup
12-
)
13-
})
14-
)(
15-
:context.arguments.lookup
16-
)(variable)
10+
some: :context.environment.lookup >> :match({
11+
none: {}
12+
some: :identity
13+
})
14+
}
1715
}

0 commit comments

Comments
 (0)