pipes
This commit is contained in:
32
specs.md
32
specs.md
@@ -72,6 +72,7 @@ GLSL;
|
||||
| `and` | logical AND (short-circuit) |
|
||||
| `or` | logical OR (short-circuit) |
|
||||
| `in` | membership test (tuples) |
|
||||
| `\|>` | pipe (function application) |
|
||||
| `+=` | add-assign |
|
||||
| `-=` | sub-assign |
|
||||
| `*=` | mul-assign |
|
||||
@@ -1024,6 +1025,26 @@ calc :: ufcs compute;
|
||||
1.calc(2, 3, 4); // normal UFCS → compute(1, 2, 3, 4)
|
||||
```
|
||||
|
||||
### Pipe Operator
|
||||
|
||||
The pipe operator `|>` inserts the left-hand side as the first argument of the right-hand side call. It is desugared at parse time.
|
||||
|
||||
```sx
|
||||
a |> f(b, c) // → f(a, b, c)
|
||||
a |> f // → f(a)
|
||||
a |> f(b) |> g(c) // → g(f(a, b), c)
|
||||
```
|
||||
|
||||
The pipe is left-associative with the lowest precedence of all binary operators, so expressions like `x + 1 |> f(2)` are parsed as `f(x + 1, 2)`.
|
||||
|
||||
This is especially useful with namespaced imports:
|
||||
```sx
|
||||
pkg :: #import "modules/math";
|
||||
|
||||
3 |> pkg.add(4) // → pkg.add(3, 4) → 7
|
||||
3 |> pkg.add(4) |> pkg.mul(2) // → pkg.mul(pkg.add(3, 4), 2) → 14
|
||||
```
|
||||
|
||||
### Field Access
|
||||
```sx
|
||||
object.field
|
||||
@@ -1214,7 +1235,7 @@ This works for any function, not just `format`. The mechanism is general: the VM
|
||||
|
||||
### `#import` Directive
|
||||
|
||||
The `#import` directive brings declarations from another `.sx` file into the current file. Paths are resolved relative to the importing file's directory.
|
||||
The `#import` directive brings declarations from another `.sx` file or directory into the current file. Paths are resolved relative to the importing file's directory.
|
||||
|
||||
**Flat import** — splices all declarations from the imported file into the current scope:
|
||||
```sx
|
||||
@@ -1226,6 +1247,14 @@ The `#import` directive brings declarations from another `.sx` file into the cur
|
||||
std :: #import "modules/std.sx";
|
||||
```
|
||||
|
||||
**Directory import** — when the path refers to a directory, all `.sx` files in that directory are aggregated into a single module:
|
||||
```sx
|
||||
pkg :: #import "modules/testpkg"; // namespaced — all .sx files merged under pkg
|
||||
#import "modules/testpkg"; // flat — all declarations spliced into scope
|
||||
```
|
||||
|
||||
Directory imports scan only the top level of the specified directory (non-recursive). Files are processed in alphabetical order for deterministic builds. Files within the directory may `#import` each other or external files.
|
||||
|
||||
Namespaced declarations are accessed with dot notation:
|
||||
```sx
|
||||
std.print("hello");
|
||||
@@ -1235,6 +1264,7 @@ std.print("hello");
|
||||
|
||||
- Imports are resolved after parsing and before code generation.
|
||||
- Paths are relative to the directory of the file containing the `#import`.
|
||||
- If the path resolves to a file, it is imported directly. If it resolves to a directory, all `.sx` files in that directory are aggregated.
|
||||
- Nested imports are supported (imported files may themselves contain `#import`).
|
||||
- Circular imports are detected and silently skipped (each file is imported at most once).
|
||||
- Generic functions in namespaced imports are supported (e.g., `std.mul(5, 2)` where `mul` is generic).
|
||||
|
||||
Reference in New Issue
Block a user