~repos /plum
git clone https://pyrossh.dev/repos/plum.git
A statically typed, imperative programming language inspired by rust, python
22a1eb06
—
pyrossh 1 year ago
update readme
readme.md
CHANGED
|
@@ -42,6 +42,10 @@ fn firstItem(items: list[int]): option[int] =
|
|
|
42
42
|
fn toCelsius(f: float): float =
|
|
43
43
|
(f - 32) * (5 / 9)
|
|
44
44
|
|
|
45
|
+
// Variadic function
|
|
46
|
+
fn addItems(items ...str) =
|
|
47
|
+
list.add(items)
|
|
48
|
+
|
|
45
49
|
record Cat(
|
|
46
50
|
name: str
|
|
47
51
|
age: int
|
|
@@ -52,39 +56,74 @@ fn Cat.withName(name: str): Cat =
|
|
|
52
56
|
Cat(name: name, age: 0)
|
|
53
57
|
|
|
54
58
|
// A simple method
|
|
55
|
-
fn (c: Cat)
|
|
59
|
+
fn fullname(c: Cat): str =
|
|
56
60
|
c.name + c.age.toStr()
|
|
57
61
|
|
|
58
|
-
fn (c: Cat)
|
|
62
|
+
fn talk(c: Cat) =
|
|
59
63
|
printLn("cat ${c.name} says meow")
|
|
60
64
|
|
|
61
|
-
fn (c: Cat)
|
|
65
|
+
fn toStr(c: Cat): str =
|
|
62
66
|
"Cat<{c.fullname()}, ${c.age}>"
|
|
63
67
|
|
|
68
|
+
trait Stringable where
|
|
69
|
+
fn toStr(): str
|
|
70
|
+
|
|
71
|
+
// `Cat is a speciecs of felidae
|
|
72
|
+
struct Cat is Stringable, Equal, Comparable =
|
|
73
|
+
| name: str
|
|
74
|
+
| age: int
|
|
75
|
+
|
|
76
|
+
fn Cat(name: str, age: int) =
|
|
77
|
+
self.name = name
|
|
78
|
+
self.age = age
|
|
79
|
+
|
|
80
|
+
fn Cat.withName(name: str): Cat =
|
|
81
|
+
`Create a cat with only name
|
|
82
|
+
Cat(name: name, age: 0)
|
|
83
|
+
|
|
84
|
+
fn fullname(): str =
|
|
85
|
+
name + age.toStr()
|
|
86
|
+
|
|
87
|
+
fn talk() =
|
|
88
|
+
printLn("cat ${name} says meow")
|
|
89
|
+
|
|
90
|
+
fn toStr(): str =
|
|
91
|
+
"Cat<${fullname()}, ${age}>"
|
|
92
|
+
|
|
64
|
-
enum Temperature
|
|
93
|
+
enum Temperature where
|
|
65
94
|
| celsius(float)
|
|
66
95
|
| fahrenheit(float)
|
|
67
96
|
|
|
68
|
-
fn
|
|
97
|
+
fn toStr(): str =
|
|
69
|
-
|
|
98
|
+
match self
|
|
70
|
-
|
|
99
|
+
celsius(t) && t > 30 -> "${t}C is above 30 celsius"
|
|
71
|
-
|
|
100
|
+
celsius(t) -> "${t}C is below 30 celsius"
|
|
72
|
-
|
|
101
|
+
fahrenheit(t) && t > 86 -> "${t}F is above 86 fahrenheit"
|
|
73
|
-
|
|
102
|
+
fahrenheit(t) -> "${t}F is below 86 fahrenheit"
|
|
74
103
|
|
|
75
104
|
type MapCallback = fn(v: a): v
|
|
76
105
|
|
|
77
|
-
|
|
106
|
+
struct DB(conn_url: str) where
|
|
78
|
-
fn compare(left: A, right: A): bool
|
|
79
|
-
)
|
|
80
107
|
|
|
108
|
+
fn connect(): Result[unit, DatabaseError] =
|
|
109
|
+
`connect to the database
|
|
81
|
-
|
|
110
|
+
online := status()
|
|
82
|
-
|
|
111
|
+
if !online
|
|
112
|
+
Err(NotOnline(conn_url))
|
|
113
|
+
else
|
|
83
|
-
)
|
|
114
|
+
Ok(unit)
|
|
84
115
|
|
|
116
|
+
fn status(): bool =
|
|
117
|
+
`check if the database is running
|
|
118
|
+
res := exec("select 1")
|
|
85
|
-
|
|
119
|
+
if res == None
|
|
120
|
+
false
|
|
121
|
+
else
|
|
122
|
+
true
|
|
123
|
+
|
|
124
|
+
fn exec(q: str): Result[unit] =
|
|
86
|
-
|
|
125
|
+
`exec some stuff
|
|
87
|
-
)
|
|
126
|
+
printLn("Going to exec q")
|
|
88
127
|
|
|
89
128
|
#[error]
|
|
90
129
|
enum DatabaseError =
|
|
@@ -99,53 +138,47 @@ fn newDB(conn_url: str) result[DB, DatabaseError] =
|
|
|
99
138
|
else
|
|
100
139
|
db
|
|
101
140
|
|
|
102
|
-
fn (d: DB) status(
|
|
141
|
+
fn (d: DB) status(): bool =
|
|
103
142
|
res := d.exec("select 1")
|
|
104
143
|
if res == None
|
|
105
144
|
false
|
|
106
145
|
else
|
|
107
146
|
true
|
|
108
147
|
|
|
109
|
-
|
|
148
|
+
suite "Cat" do
|
|
110
|
-
test
|
|
149
|
+
test "talks" do
|
|
111
|
-
|
|
150
|
+
c := Cat(name: "123", age: 1)
|
|
151
|
+
c2 := Cat(...c, age: c.age + 1)
|
|
112
|
-
|
|
152
|
+
c.talk()
|
|
113
|
-
|
|
114
|
-
test("fullname") |t|
|
|
115
|
-
Cat("rabby", 21).fullname() == "rabby21"
|
|
116
|
-
c2 := Cat(...c, age: c.age + 1)
|
|
117
|
-
|
|
118
|
-
test("ToStr") |t|
|
|
119
|
-
items := [Cat("Molly", 9), Cat("Fenton", 6)]
|
|
120
|
-
.retain(|p| p.name.size > 5)
|
|
121
|
-
.map(|p| describe(p))
|
|
122
|
-
.each(|d| printLn(d))
|
|
123
|
-
assert items[0].toStr() == "Cat<Fenton, 6>"
|
|
124
|
-
|
|
125
|
-
bench("1231") |n|
|
|
126
|
-
for i := range n
|
|
127
|
-
printLn(i)
|
|
128
|
-
```
|
|
129
153
|
|
|
130
|
-
|
|
154
|
+
test "fullname" do
|
|
155
|
+
Assert.equal(Cat("rabby", 21).fullname(), "rabby21")
|
|
131
156
|
|
|
157
|
+
test "ToStr" do
|
|
158
|
+
items := [Cat("Molly", 9), Cat("Fenton", 6)]
|
|
159
|
+
.retain(|p| p.name.size > 5)
|
|
132
|
-
|
|
160
|
+
.map(|p| describe(p))
|
|
161
|
+
.each(|d| printLn(d))
|
|
162
|
+
Assert.equal(items[0].toStr(), "Cat<Fenton, 6>")
|
|
133
163
|
|
|
164
|
+
suite "diagonal" do
|
|
134
|
-
|
|
165
|
+
test "3 4 5" do
|
|
135
|
-
|
|
166
|
+
Assert.equal 5.0 (diagonal 3.0 4.0)
|
|
167
|
+
test "5 12 13" do
|
|
168
|
+
Assert.equal 5.0 (diagonal 3.0 4.0)
|
|
136
169
|
```
|
|
137
170
|
|
|
138
|
-
#
|
|
171
|
+
# Types
|
|
139
172
|
|
|
140
|
-
|
|
173
|
+
### any
|
|
141
174
|
|
|
142
175
|
The any type is an empty trait and is used to represent all types
|
|
143
176
|
|
|
144
|
-
|
|
177
|
+
### error
|
|
145
178
|
|
|
146
179
|
The error type is a trait that represents all Error types
|
|
147
180
|
|
|
148
|
-
|
|
181
|
+
## bool
|
|
149
182
|
|
|
150
183
|
A bool can be either `true` or `false`. It is used in logical operations and conditional statements.
|
|
151
184
|
|
|
@@ -156,58 +189,47 @@ if true || false
|
|
|
156
189
|
print("works")
|
|
157
190
|
```
|
|
158
191
|
|
|
159
|
-
|
|
192
|
+
## byte
|
|
160
193
|
|
|
161
194
|
A byte represents an unsigned 8-bit number. It is mainly used to represent strings and binary data.
|
|
162
195
|
|
|
163
|
-
```
|
|
196
|
+
```go
|
|
197
|
+
up_event := 'a'
|
|
164
|
-
|
|
198
|
+
key_code := 102
|
|
165
|
-
data = [104, 101, 197, 130, 197, 130, 111, 0]
|
|
166
199
|
```
|
|
167
200
|
|
|
168
|
-
|
|
201
|
+
## int
|
|
169
202
|
|
|
170
203
|
An int is a signed 64-bit number. It can be represented in various ways,
|
|
171
204
|
|
|
172
|
-
|
|
205
|
+
| Notation | Type | Base | Example |
|
|
206
|
+
| -------- | ----------- | ------- | ------------------------- |
|
|
173
|
-
0b
|
|
207
|
+
| 0b | Binary | Base 2 | `0b00101010`, `0b1_1111` |
|
|
174
|
-
0x
|
|
208
|
+
| 0x | Hexadecimal | Base 16 | `0xff00ff`, `0xFF80_0000` |
|
|
175
|
-
|
|
209
|
+
| number | Standard | Base 10 | `98762`, `98_762` |
|
|
176
|
-
```
|
|
177
|
-
|
|
178
|
-
```rb
|
|
179
|
-
0b00101010
|
|
180
|
-
0b1_1111_1
|
|
181
|
-
0xff00ff
|
|
182
|
-
0xFF00FF
|
|
183
|
-
0xFF80_0000_0000_0000
|
|
184
|
-
98762
|
|
185
|
-
1_000_000
|
|
186
|
-
```
|
|
187
210
|
|
|
188
|
-
|
|
211
|
+
## float
|
|
189
212
|
|
|
190
213
|
A float represents a 64-bit floating point [IEEE-754-2008](https://en.wikipedia.org/wiki/Double-precision_floating-point_format).
|
|
191
214
|
|
|
215
|
+
| Type | Example |
|
|
216
|
+
| ----------- | ----------------- |
|
|
192
|
-
```
|
|
217
|
+
| Normal | `1.2`, `-0.4` |
|
|
193
|
-
1.2
|
|
194
|
-
-0.4
|
|
195
|
-
12.0f
|
|
196
|
-
15.03f
|
|
218
|
+
| With suffix | `15.03f`, `12.0f` |
|
|
197
|
-
```
|
|
219
|
+
| E notation | `2.7e-12`, `1e10` |
|
|
198
220
|
|
|
199
|
-
|
|
221
|
+
## dec
|
|
200
222
|
|
|
201
223
|
A dec is a decimal floating-point numbering format which is 64-bit data type.
|
|
202
224
|
It is intended for applications where it is necessary to emulate decimal rounding exactly, such as financial and tax computations.
|
|
203
225
|
It supports 16 decimal digits of significand and an exponent range of −383 to +384.
|
|
204
226
|
|
|
205
|
-
|
|
227
|
+
| Type | Example |
|
|
206
|
-
|
|
228
|
+
| ---------- | ----------------- |
|
|
207
|
-
-13.3d
|
|
229
|
+
| Normal | `2.4d`, `-13.3d` |
|
|
208
|
-
```
|
|
230
|
+
| E notation | `2.7e-12`, `1e10` |
|
|
209
231
|
|
|
210
|
-
|
|
232
|
+
## str
|
|
211
233
|
|
|
212
234
|
A str represents an array of runes or unicode code points. It is encoded to UTF-8 by default.
|
|
213
235
|
It supports interpolation of variables/values that implement the ToStr interface.
|
|
@@ -284,16 +306,14 @@ An option is a type that represents either value present `some` or nothing prese
|
|
|
284
306
|
```go
|
|
285
307
|
import std/option
|
|
286
308
|
|
|
287
|
-
record Car(wheels: int)
|
|
288
|
-
|
|
289
|
-
c := some(
|
|
309
|
+
c := some(2)
|
|
290
310
|
|
|
291
311
|
match c
|
|
292
312
|
none -> print("no car")
|
|
293
|
-
some(
|
|
313
|
+
some(c) -> print("${c}")
|
|
294
314
|
|
|
295
|
-
if
|
|
315
|
+
if some(count) = c
|
|
296
|
-
printLn("Hello ${
|
|
316
|
+
printLn("Hello ${count}")
|
|
297
317
|
else
|
|
298
318
|
printLn("nothing")
|
|
299
319
|
```
|
|
@@ -347,7 +367,9 @@ fn main(): result[int] =
|
|
|
347
367
|
ok(0)
|
|
348
368
|
```
|
|
349
369
|
|
|
370
|
+
# Declarations
|
|
371
|
+
|
|
350
|
-
|
|
372
|
+
## constants
|
|
351
373
|
|
|
352
374
|
Constants can be declared at the top level of a program. They cannot be reassigned.
|
|
353
375
|
|
|
@@ -370,20 +392,115 @@ const COUNTRY_CODES = map.of(
|
|
|
370
392
|
fn count(n: int): int = n * 1
|
|
371
393
|
```
|
|
372
394
|
|
|
395
|
+
## variables
|
|
396
|
+
|
|
397
|
+
Variables can be declared only at the local scope of a function as they are mutable. They are references/pointers to data.
|
|
398
|
+
We use the Short Variable Declaration Operator `:=` to declare a variable
|
|
399
|
+
|
|
400
|
+
```go
|
|
401
|
+
fn calculate(n: int): int =
|
|
402
|
+
a := 1 + n
|
|
403
|
+
b := 1 * n
|
|
404
|
+
a * b
|
|
405
|
+
```
|
|
406
|
+
|
|
407
|
+
## Functions
|
|
408
|
+
|
|
409
|
+
```rs
|
|
410
|
+
fn fib(n: int): int =
|
|
411
|
+
match n
|
|
412
|
+
0 | 1 -> n
|
|
413
|
+
_ -> fib(n - 1) + fib(n - 2)
|
|
414
|
+
|
|
415
|
+
fn log(level: str, msg: str) =
|
|
416
|
+
printLn("${level}: ${msg}")
|
|
417
|
+
|
|
418
|
+
fn info(msg: str) =
|
|
419
|
+
printLn("INFO", msg)
|
|
420
|
+
|
|
421
|
+
fn warning(msg: str) =
|
|
422
|
+
printLn("WARN", msg)
|
|
423
|
+
|
|
424
|
+
fn addLists[T](a: List[T], b: List[T]): List[T] =
|
|
425
|
+
a.concat(b)
|
|
426
|
+
|
|
427
|
+
// Variadic function
|
|
428
|
+
fn addItems(items ...str) =
|
|
429
|
+
for i, v := range items
|
|
430
|
+
printLn("${i} ${v}")
|
|
431
|
+
```
|
|
432
|
+
|
|
433
|
+
## Records
|
|
434
|
+
|
|
435
|
+
A record is a collect of data indexed by fields. It is a reference type and reference counted.
|
|
436
|
+
|
|
437
|
+
```rs
|
|
438
|
+
struct Cat is Stringable =
|
|
439
|
+
| name: str
|
|
440
|
+
| age: int
|
|
441
|
+
|
|
442
|
+
fn Cat.withName(name: str): Cat =
|
|
443
|
+
Cat(name: name, age: 0)
|
|
444
|
+
|
|
445
|
+
fn fullname(): str =
|
|
446
|
+
name + age.toStr()
|
|
447
|
+
|
|
448
|
+
fn talk() =
|
|
449
|
+
printLn("cat ${name} says meow")
|
|
450
|
+
|
|
451
|
+
fn toStr(): str =
|
|
452
|
+
"Cat<${fullname()}, ${age}>"
|
|
453
|
+
```
|
|
454
|
+
|
|
455
|
+
## Traits
|
|
456
|
+
|
|
457
|
+
```rs
|
|
458
|
+
trait Equatable[A] where
|
|
459
|
+
fn eq(left: A, right: A): bool
|
|
460
|
+
fn neq(left: A, right: A): bool
|
|
461
|
+
|
|
462
|
+
trait Comparable[A: Ord] where
|
|
463
|
+
fn compare(left: A, right: A): Ordering
|
|
464
|
+
```
|
|
465
|
+
|
|
466
|
+
## Enums
|
|
467
|
+
|
|
468
|
+
An Algebraic Data Type
|
|
469
|
+
|
|
470
|
+
```rs
|
|
471
|
+
enum Ordering is Stringable =
|
|
472
|
+
| LT
|
|
473
|
+
| EQ
|
|
474
|
+
| GT
|
|
475
|
+
|
|
476
|
+
fn toStr(): str =
|
|
477
|
+
match self
|
|
478
|
+
LT -> "LT"
|
|
479
|
+
EQ -> "EQ"
|
|
480
|
+
GT -> "GT"
|
|
481
|
+
```
|
|
482
|
+
|
|
483
|
+
## Type
|
|
484
|
+
|
|
485
|
+
```rs
|
|
486
|
+
type Size = int
|
|
487
|
+
type Metre = float
|
|
488
|
+
type MapString[T] = Map[String, T]
|
|
489
|
+
```
|
|
490
|
+
|
|
491
|
+
# Statements
|
|
492
|
+
|
|
373
|
-
|
|
493
|
+
## Assignment statement
|
|
374
494
|
|
|
375
495
|
```rb
|
|
376
496
|
low, mid, high := 0, 0, n.numItems
|
|
377
497
|
x := 10
|
|
378
498
|
y := 20
|
|
379
|
-
xy_list :=
|
|
499
|
+
xy_list := List.of(1, 2, 3)
|
|
380
|
-
xy_map := [x: x, y: y]
|
|
381
|
-
|
|
500
|
+
xy_map := Map.of(1 => "one", 2 => "two")
|
|
382
|
-
assoc_list[:a]
|
|
383
|
-
assoc_list["b"]
|
|
384
501
|
```
|
|
385
502
|
|
|
386
|
-
|
|
503
|
+
## while statement
|
|
387
504
|
|
|
388
505
|
```rb
|
|
389
506
|
low, mid, high := 0, 0, n.size
|
|
@@ -396,9 +513,12 @@ while low < high
|
|
|
396
513
|
|
|
397
514
|
while a > b
|
|
398
515
|
a += 1
|
|
516
|
+
|
|
517
|
+
while Some(top) = stack.pop()
|
|
518
|
+
printLn(top)
|
|
399
519
|
```
|
|
400
520
|
|
|
401
|
-
|
|
521
|
+
## for statement
|
|
402
522
|
|
|
403
523
|
```rb
|
|
404
524
|
for i := range 10
|
|
@@ -415,7 +535,7 @@ for v := range list
|
|
|
415
535
|
sum += k + v
|
|
416
536
|
```
|
|
417
537
|
|
|
418
|
-
|
|
538
|
+
## if expression/statement
|
|
419
539
|
|
|
420
540
|
```py
|
|
421
541
|
if name == "Andreas"
|
|
@@ -435,7 +555,7 @@ fn getPerimeter(shape: Shape): Result[float] =
|
|
|
435
555
|
match shape
|
|
436
556
|
Rectangle(r) -> Ok(2 * r.length() + 2 * r.width())
|
|
437
557
|
Circle(c) -> Ok(2 * c.radius() * PI)
|
|
438
|
-
|
|
558
|
+
_ -> Err(RuntimeError("expected shape but found ${@TypeName(shape)}"))
|
|
439
559
|
|
|
440
560
|
match x, y
|
|
441
561
|
1, 1 -> "both are 1"
|
|
@@ -456,6 +576,23 @@ match
|
|
|
456
576
|
|
|
457
577
|
## Operators
|
|
458
578
|
|
|
579
|
+
**assignment operator**
|
|
580
|
+
|
|
581
|
+
```go
|
|
582
|
+
x := 5
|
|
583
|
+
y := 3
|
|
584
|
+
x += y // 8
|
|
585
|
+
x -= y // 5
|
|
586
|
+
x *= y // 15
|
|
587
|
+
x /= y // 5
|
|
588
|
+
x %= y // 2
|
|
589
|
+
x &= y // 2
|
|
590
|
+
x |= y // 3
|
|
591
|
+
x <<= y // 24
|
|
592
|
+
x >>= y // 3
|
|
593
|
+
a ?= 2 // elvis assignment operator
|
|
594
|
+
```
|
|
595
|
+
|
|
459
596
|
**not operator**
|
|
460
597
|
|
|
461
598
|
```rb
|
|
@@ -466,7 +603,7 @@ match
|
|
|
466
603
|
**ternary operator**
|
|
467
604
|
|
|
468
605
|
```rb
|
|
469
|
-
x ?
|
|
606
|
+
x ? a : b
|
|
470
607
|
```
|
|
471
608
|
|
|
472
609
|
**safe navigation operator**
|
|
@@ -475,37 +612,13 @@ x ? x : y
|
|
|
475
612
|
a?.b?.c?.d
|
|
476
613
|
```
|
|
477
614
|
|
|
478
|
-
**double-bang operator/not-null assertion operator**
|
|
479
|
-
|
|
480
|
-
```rb
|
|
481
|
-
a!!.b
|
|
482
|
-
```
|
|
483
|
-
|
|
484
615
|
**elvis operator**
|
|
485
616
|
|
|
486
617
|
```rb
|
|
487
618
|
x ?: y
|
|
488
619
|
```
|
|
489
620
|
|
|
490
|
-
**elvis assignment operator**
|
|
491
|
-
|
|
492
|
-
```rb
|
|
493
|
-
atomic_number ?= 2
|
|
494
|
-
```
|
|
495
|
-
|
|
496
|
-
**spread operator**
|
|
497
|
-
|
|
498
|
-
```
|
|
499
|
-
list := [1, 2, 3]
|
|
500
|
-
list2 := [0, ...list]
|
|
501
|
-
assert list2.length == 4
|
|
502
|
-
|
|
503
|
-
list = nil
|
|
504
|
-
list3 := [0, ...list?];
|
|
505
|
-
assert list2.length == 1
|
|
506
|
-
```
|
|
507
|
-
|
|
508
|
-
**cascade operator**
|
|
621
|
+
**cascade operator (remove??)**
|
|
509
622
|
|
|
510
623
|
```dart
|
|
511
624
|
paint := Paint()
|
|
@@ -518,62 +631,31 @@ v := list.of(1, 2, 3)
|
|
|
518
631
|
..get(0)
|
|
519
632
|
```
|
|
520
633
|
|
|
521
|
-
**variadic operator**
|
|
522
|
-
|
|
523
|
-
```go
|
|
524
|
-
fn add(items ...str) =
|
|
525
|
-
list.add(items)
|
|
526
|
-
```
|
|
527
|
-
|
|
528
|
-
**assignment operator**
|
|
529
|
-
|
|
530
|
-
```go
|
|
531
|
-
x := 5
|
|
532
|
-
y := 3
|
|
533
|
-
x += y // 8
|
|
534
|
-
x -= y // 5
|
|
535
|
-
x *= y // 15
|
|
536
|
-
x /= y // 5
|
|
537
|
-
x %= y // 2
|
|
538
|
-
x &= y // 2
|
|
539
|
-
x |= y // 3
|
|
540
|
-
x <<= y // 24
|
|
541
|
-
x >>= y // 3
|
|
542
|
-
```
|
|
543
|
-
|
|
544
634
|
**range operator**
|
|
545
635
|
|
|
546
|
-
```
|
|
636
|
+
```rs
|
|
547
637
|
type Seq0 = fn(yield: fn(): bool): bool
|
|
548
638
|
type Seq1[V] = fn(yield: fn(V): bool): bool
|
|
549
639
|
type Seq2[K, V] = fn(yield: fn(K, V): bool): bool
|
|
550
640
|
|
|
551
|
-
|
|
641
|
+
struct Tree[E] =
|
|
552
|
-
value E
|
|
642
|
+
| value E
|
|
553
|
-
left: Option[Tree]
|
|
643
|
+
| left: Option[Tree]
|
|
554
|
-
right: Option[Tree]
|
|
644
|
+
| right: Option[Tree]
|
|
555
|
-
)
|
|
556
645
|
|
|
557
|
-
fn
|
|
646
|
+
fn op_range(yld: fn(E): bool): bool =
|
|
558
|
-
|
|
647
|
+
t ? true : t.left?.in_order(yld) && yld(t.val) && t.right?.in_order(yld)
|
|
559
648
|
|
|
560
|
-
tree
|
|
649
|
+
let tree = Tree(
|
|
561
650
|
value: 10,
|
|
562
651
|
left: Tree(20, Tree(30), Tree(39)),
|
|
563
652
|
right: Tree(40),
|
|
564
653
|
)
|
|
565
654
|
|
|
566
|
-
for t := range tree
|
|
655
|
+
for t := range tree:
|
|
567
656
|
printLn(v)
|
|
568
657
|
```
|
|
569
658
|
|
|
570
|
-
## Generics
|
|
571
|
-
|
|
572
|
-
```
|
|
573
|
-
fn add[T: int | float](a: List[T], b: List[T]): List[T] =
|
|
574
|
-
pass
|
|
575
|
-
```
|
|
576
|
-
|
|
577
659
|
## Rules
|
|
578
660
|
|
|
579
661
|
- Function parameters are passed by value only. You cannot modify a parameter. The compiler will throw an error if you try to.
|
|
@@ -590,7 +672,3 @@ fn add[T: int | float](a: List[T], b: List[T]): List[T] =
|
|
|
590
672
|
| Local variables | snake_case |
|
|
591
673
|
| Constants | SCREAMING_SNAKE_CASE |
|
|
592
674
|
| Generics | single uppercase letter |
|
|
593
|
-
|
|
594
|
-
## Todo
|
|
595
|
-
|
|
596
|
-
linter, formatter, test runner, language server, package manager
|