[sc-694] Replace 'go' with 'fork' in 'bend'

This commit is contained in:
Nicolas Abril 2024-05-16 17:56:47 +02:00
parent 6fc386b673
commit faa6bdb9fc
12 changed files with 48 additions and 47 deletions

View File

@ -94,8 +94,8 @@ def MyTree.sum(x):
def main:
bend val = 0 while val < 0:
# 'go' calls the bend recursively with the provided values.
x = Node(val=val, left=go(val + 1), right=go(val + 1))
# 'fork' calls the bend recursively with the provided values.
x = Node(val=val, left=fork(val + 1), right=fork(val + 1))
then:
# 'then' is the base case, when the condition fails.
x = Leaf
@ -133,7 +133,7 @@ def main:
bend val = [0, 1, 2, 3] while val != []:
match val:
List.cons:
x = val.head + go(val.tail)
x = val.head + fork(val.tail)
List.nil:
x = 0
then:

View File

@ -415,7 +415,7 @@ type Tree:
def main():
bend x = 0:
when x < 3:
tree = Tree/Node { lft: go(x + 1), rgt: go(x + 1) }
tree = Tree/Node { lft: fork(x + 1), rgt: fork(x + 1) }
else:
tree = Tree/Leaf { val: 7 }
return tree
@ -423,14 +423,14 @@ def main():
The program above will initialize a state (`x = 0`), and then, for as long as `x
< 3`, it will split that state in two, creating a `Tree/Node`, and continuing
(`go`) with `x + 1`. When `x >= 3`, it will just return a `Tree/Leaf` with `7`.
(`fork`) with `x + 1`. When `x >= 3`, it will just return a `Tree/Leaf` with `7`.
When all is done, the result will be assigned to the `tree` variable:
```python
tree = go(0)
tree = ![go(1), go(1)]
tree = ![![go(2),go(2)], ![go(2),go(2)]]
tree = ![![![go(3),go(3)], ![go(3),go(3)]], ![![go(3),go(3)], ![go(3),go(3)]]]
tree = fork(0)
tree = ![fork(1), fork(1)]
tree = ![![fork(2),fork(2)], ![fork(2),fork(2)]]
tree = ![![![fork(3),fork(3)], ![fork(3),fork(3)]], ![![fork(3),fork(3)], ![fork(3),fork(3)]]]
tree = ![![![7,7], ![7,7]], ![![7,7], ![7,7]]]
```
@ -451,7 +451,7 @@ Could be emulated in Bend with a "sequential bend":
```python
bend idx = 0:
when idx < 10:
sum = idx + go(idx + 1)
sum = idx + fork(idx + 1)
else:
sum = 0
```
@ -541,7 +541,7 @@ example, to add numbers in parallel, we can write:
def main():
bend d = 0, i = 0:
when d < 28:
sum = go(d+1, i*2+0) + go(d+1, i*2+1)
sum = fork(d+1, i*2+0) + fork(d+1, i*2+1)
else:
sum = i
return sum

View File

@ -1,6 +1,6 @@
# CLI arguments
It's possible to pass arguments to a program executed with `bend run` or `bend norm`:
It's possible to pass arguments to a program executed with `bend run`:
```sh
bend run <Path to program> [Arguments in expression form]...
@ -11,11 +11,11 @@ It accepts any expression that would also be valid inside a bend function.
Arguments are passed to programs by applying them to the entrypoint function:
```py
// Core syntax
main(x1, x2, x3):
MainBody(x1 x2 x3)
# Imp syntax
def main(x1, x2, x3):
return MainBody(x1 x2 x3)
// Calling with `bend run <file> arg1 arg2 arg3 argN`, it becomes (in core syntax):
// Calling with `bend run <file> arg1 arg2 arg3 argN`, it becomes (in the "fun" syntax):
main = (x1 λx2 λx3 (MainBody x1 x2 x3) arg1 arg2 arg3 argN)
```
@ -24,18 +24,22 @@ You can even pass more arguments than the function expects, although that can le
```rust
// Expects 2 CLI arguments
def main(x, y):
{x - y, y - x}
// Calling with just one argument
bend norm <path> +5
return {x - y, y - x}
```
```sh
# Calling with just one argument
> bend run <path> +5
λa {(- a 5) (- a +5)}
// Calling with two argument
bend norm <path> +5 +3
# Calling with two argument
> bend run <path> +5 +3
{+2 -2}
// Calling with three argument
// In this case, the third argument doesn't do anything due to the underlying interaction rules.
bend norm <path> +5 +3 +1
# Calling with three argument
# In this case, the third argument doesn't change anything
# due to the underlying interaction rules.
# If this were a variant of simply-typed lambda-calculus
# it wouldn't be well-typed.
> bend run <path> +5 +3 +1
{+2 -2}
```

View File

@ -236,15 +236,15 @@ Bend can be used to create recursive data structures:
```rust
bend x = 0:
when x < 10:
left = go(x + 1)
right = go(x + 1)
left = fork(x + 1)
right = fork(x + 1)
y = Tree/Node(left, right)
else:
y = Tree/Leaf(x)
```
Which binds a variable to the return of an inline recursive function.
The function `go` is available inside the `when` arm of the `bend` and calls it recursively.
The function `fork` is available inside the `when` arm of the `bend` and calls it recursively.
It is possible to pass multiple state variables, which can be initialized:
@ -254,7 +254,7 @@ bend x = 1, y = 2 ...:
...
```
When calling `go`, the function must receive the same number of arguments as the number of state variables.
When calling `fork`, the function must receive the same number of arguments as the number of state variables.
It is equivalent to this inline recursive function:

View File

@ -15,7 +15,7 @@ def sum(tree):
def gen(depth):
bend val = 0:
when val < depth:
tree = MyTree/Node { val: val, left: go(val+1), right: go(val+1) }
tree = MyTree/Node { val: val, left: fork(val+1), right: fork(val+1) }
else:
tree = MyTree/Leaf { val: val }
return tree

View File

@ -128,11 +128,7 @@ impl fmt::Display for Term {
}
write!(f, "{}, ", init)?;
}
write!(f, "while {cond} {{ ")?;
write!(f, "{step} ")?;
write!(f, "}} then {{ ")?;
write!(f, "{base} ")?;
write!(f, "}}")
write!(f, "{{ when {cond}: {step}; else: {base} }}")
}
Term::Fan { fan: FanKind::Tup, tag, els } => write!(f, "{}({})", tag, DisplayJoin(|| els.iter(), ", ")),
Term::Fan { fan: FanKind::Dup, tag, els } => write!(f, "{}{{{}}}", tag, DisplayJoin(|| els, " ")),
@ -410,10 +406,11 @@ impl Term {
}
write!(f, "{}, ", init)?;
}
writeln!(f, "while {cond} {{")?;
writeln!(f, "{:tab$}{}", "", step.display_pretty(tab + 2), tab = tab + 2)?;
writeln!(f, "{:tab$}}} then {{", "")?;
writeln!(f, "{:tab$}{}", "", base.display_pretty(tab + 2), tab = tab + 2)?;
writeln!(f, "{{")?;
writeln!(f, "{:tab$}when {}:", "", cond.display_pretty(tab + 2), tab = tab + 2)?;
writeln!(f, "{:tab$}{}", "", step.display_pretty(tab + 4), tab = tab + 4)?;
writeln!(f, "{:tab$}else:", "", tab = tab + 2)?;
writeln!(f, "{:tab$}{}", "", base.display_pretty(tab + 4), tab = tab + 4)?;
write!(f, "{:tab$}}}", "")
}
Term::Open { typ, var, bod } => {

View File

@ -4,7 +4,7 @@ use crate::{
maybe_grow,
};
const RECURSIVE_KW: &str = "go";
const RECURSIVE_KW: &str = "fork";
const NEW_FN_SEP: &str = "__bend";
impl Ctx<'_> {

View File

@ -61,7 +61,7 @@ def fld(list):
def bnd():
bend x = 0:
when x < 10:
return List/cons(x go(x + 1));
return List/cons(x fork(x + 1));
else:
return List/nil();

View File

@ -9,9 +9,9 @@ main =
let n = 0;
let tree = bend n {
when (< n depth):
(Tree/node (go (+ n 1)) (go (+ n 1)))
else:
(Tree/leaf c)
(Tree/node (fork (+ n 1)) (fork (+ n 1)))
else:
(Tree/leaf c)
}
fold tree {
Tree/node: (+ tree.lft tree.rgt)

View File

@ -13,7 +13,7 @@ def main:
bend x = 1, h = 0:
when h < n:
y = Tree/node { val: x, lft: go(2 * x, h + 1), rgt: go(2 * x + 1, h + 1) }
y = Tree/node { val: x, lft: fork(2 * x, h + 1), rgt: fork(2 * x + 1, h + 1) }
else:
y = Tree/leaf

View File

@ -19,7 +19,7 @@ main =
let depth = 10
let tree = bend n = 0 {
when (< n depth):
(Tree/node (go (+ n 1)) (go (+ n 1)))
(Tree/node (fork (+ n 1)) (fork (+ n 1)))
else:
if (% n 2) { (Tree/leaf Bool/True) } else { (Tree/leaf Bool/False) }
}

View File

@ -28,7 +28,7 @@ input_file: tests/golden_tests/parse_file/imp_program.bend
(fld) = λ%arg0 use list = %arg0; fold list = list { List/cons: 1; List/nil: 2; }
(bnd) = bend x = 0, while (< x 10) { (List/cons x (go (+ x 1))) } then { List/nil }
(bnd) = bend x = 0, { when (< x 10): (List/cons x (fork (+ x 1))); else: List/nil }
(era) = let * = (+ 2 3); let the_expr_killer = *; (the_expr_killer 9)