You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Copy file name to clipboardExpand all lines: docs/bindings.md
+39Lines changed: 39 additions & 0 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -3,3 +3,42 @@ slug: /bindings
3
3
---
4
4
5
5
# Bindings
6
+
7
+
Rue is a [purely-functional](https://en.wikipedia.org/wiki/Purely_functional_programming) programming language, and doesn't directly support mutation.
8
+
9
+
Practically, this means a few things:
10
+
11
+
1. The output of a function will remain the same every time, as long as its arguments don't change
12
+
2. There is no support for mutable variables
13
+
3. A function cannot change the outer scope in any way
14
+
15
+
However, even though _mutation_ isn't supported, you can still define `let` bindings:
16
+
17
+
```rue
18
+
fn main(num: Int) -> Int {
19
+
let squared = num * num;
20
+
let doubled = squared * 2;
21
+
doubled + 100
22
+
}
23
+
```
24
+
25
+
In this example, we declare two bindings to make the code more readable. These can be reused multiple times to avoid calculating the same value twice or writing duplicate code.
26
+
27
+
## Inline Bindings
28
+
29
+
You can mark a `let` binding as `inline`, which forces its value to be inserted everywhere it's referenced rather than being defined a single time and reused.
30
+
31
+
As an example, this will insert `num * num` multiple times, rather than computing it once up front:
32
+
33
+
```rue
34
+
fn main(num: Int) -> Int {
35
+
inline let squared = num * num;
36
+
square + squared
37
+
}
38
+
```
39
+
40
+
This should be used sparingly, since it can come with either a performance hit, an increase in compiled output size, or both.
41
+
42
+
:::tip
43
+
The compiler will automatically inline `let` bindings if they are only referenced a single time. You almost never need to explicitly mark them as `inline`.
Copy file name to clipboardExpand all lines: docs/functions.md
+140Lines changed: 140 additions & 0 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -3,3 +3,143 @@ slug: /functions
3
3
---
4
4
5
5
# Functions
6
+
7
+
A [function](<https://en.wikipedia.org/wiki/Function_(computer_programming)>) is a self contained part of a program. You can break up complex code into multiple programs to make it more readable, or use recursive functions to implement looping.
8
+
9
+
Function items can be declared at the top level:
10
+
11
+
```rue
12
+
fn add(a: Int, b: Int) -> Int {
13
+
a + b
14
+
}
15
+
```
16
+
17
+
And they can be called by other functions:
18
+
19
+
```rue
20
+
add(42, 34)
21
+
```
22
+
23
+
## Main
24
+
25
+
The `main` function is special, in that it's the entrypoint to every compiled program. It's used to determine which symbols are used in the program, and its body is compiled verbatim (along with any functions and constants it depends on) rather than being called.
26
+
27
+
For example, the following program:
28
+
29
+
```rue
30
+
fn main() -> Int {
31
+
42
32
+
}
33
+
```
34
+
35
+
Will compile to the CLVM `(q . 42)`.
36
+
37
+
## Inline Functions
38
+
39
+
You can mark a function as `inline`. This will change the behavior of the compiler to insert the function body everywhere it's referenced, substituting each of the parameters with the corresponding arguments in the function call, instead of defining the function separately and calling it.
40
+
41
+
As an example, this will insert the parameter value `num + 10` four times, twice for each multiplication, rather than defining the function once and calling it twice:
42
+
43
+
```rue
44
+
fn main(num: Int) -> Int {
45
+
square(num + 10) + square(num + 10)
46
+
}
47
+
48
+
inline fn square(num: Int) -> Int {
49
+
num * num
50
+
}
51
+
```
52
+
53
+
This should be used sparingly, since it can come with either a performance hit, an increase in compiled output size, or both.
54
+
55
+
A recursive function cannot be marked as `inline`.
56
+
57
+
:::tip
58
+
The compiler will automatically inline functions if they are referenced a single time and their parameters are referenced a single time. You almost never need to explicitly mark them as `inline`.
59
+
:::
60
+
61
+
## Spread Syntax
62
+
63
+
Typically, there is a fixed number of arguments in a function. However, if you want to allow a variable number of arguments, or extend the argument list with another type, you can use the spread operator.
64
+
65
+
For example, the following function accepts any number of arguments:
66
+
67
+
```rue
68
+
fn sum(...numbers: List<Int>) -> Int {
69
+
if numbers is nil {
70
+
0
71
+
} else {
72
+
numbers.first + sum(...numbers.rest)
73
+
}
74
+
}
75
+
```
76
+
77
+
And can be called as such:
78
+
79
+
```rue
80
+
let zero = sum();
81
+
let added = sum(42, 34);
82
+
83
+
// You can spread arguments too
84
+
let list = [1, 2, 3, 4, 5];
85
+
let total = sum(42, ...list);
86
+
```
87
+
88
+
It's also possible to use the spread operator with non-list types, which allows for compatibility with arbitrary functions:
let message = tree_hash(solution.conditions as Any);
109
+
let agg_sig = AggSigMe {
110
+
public_key: solution.public_key,
111
+
message: message,
112
+
};
113
+
[agg_sig, ...solution.conditions]
114
+
}
115
+
```
116
+
117
+
## Lambdas
118
+
119
+
Because functions can be passed around as values, it's sometimes useful to be able to write a function inline.
120
+
121
+
You can do this with a lambda:
122
+
123
+
```rue
124
+
let adder = fn(a: Int, b: Int) => a + b;
125
+
let sum = adder(42, 34);
126
+
```
127
+
128
+
### Closures
129
+
130
+
Lambdas can automatically capture values that are defined in their parent scope, much like how functions in general capture other functions or constants that are defined externally.
131
+
132
+
Here's an example of a lambda that captures its environment in a closure:
133
+
134
+
```rue
135
+
fn main() -> Int {
136
+
let adder = create_adder(42);
137
+
adder(100)
138
+
}
139
+
140
+
fn create_adder(a: Int) -> fn(b: Int) -> Int {
141
+
fn(b) => a + b
142
+
}
143
+
```
144
+
145
+
In this case, `create_adder` returns a closure which captures the value of `a` into the lambda function.
0 commit comments