@shd101wyy/yo 0.1.28 → 0.1.29

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (55) hide show
  1. package/.github/skills/yo-async-effects/SKILL.md +15 -15
  2. package/.github/skills/yo-async-effects/async-effects-recipes.md +110 -121
  3. package/.github/skills/yo-syntax/SKILL.md +2 -2
  4. package/.github/skills/yo-syntax/syntax-cheatsheet.md +49 -75
  5. package/README.md +2 -0
  6. package/out/cjs/index.cjs +622 -611
  7. package/out/cjs/yo-cli.cjs +727 -716
  8. package/out/cjs/yo-lsp.cjs +637 -626
  9. package/out/esm/index.mjs +515 -504
  10. package/out/types/src/codegen/functions/declarations.d.ts +1 -1
  11. package/out/types/src/doc/model.d.ts +0 -1
  12. package/out/types/src/env.d.ts +0 -2
  13. package/out/types/src/evaluator/context.d.ts +1 -1
  14. package/out/types/src/evaluator/exprs/{escape.d.ts → unwind.d.ts} +1 -1
  15. package/out/types/src/evaluator/types/function.d.ts +1 -2
  16. package/out/types/src/evaluator/utils.d.ts +0 -1
  17. package/out/types/src/expr.d.ts +5 -6
  18. package/out/types/src/types/creators.d.ts +4 -6
  19. package/out/types/src/types/definitions.d.ts +7 -16
  20. package/out/types/src/types/guards.d.ts +1 -2
  21. package/out/types/src/types/tags.d.ts +0 -1
  22. package/out/types/src/types/utils.d.ts +1 -0
  23. package/out/types/tsconfig.tsbuildinfo +1 -1
  24. package/package.json +1 -1
  25. package/std/async.yo +1 -1
  26. package/std/crypto/random.yo +6 -6
  27. package/std/encoding/base64.yo +4 -4
  28. package/std/encoding/hex.yo +2 -2
  29. package/std/encoding/json.yo +3 -3
  30. package/std/encoding/utf16.yo +1 -1
  31. package/std/error.yo +14 -2
  32. package/std/fs/dir.yo +56 -62
  33. package/std/fs/file.yo +118 -124
  34. package/std/fs/metadata.yo +11 -17
  35. package/std/fs/temp.yo +21 -27
  36. package/std/fs/walker.yo +10 -16
  37. package/std/http/client.yo +25 -29
  38. package/std/http/index.yo +4 -4
  39. package/std/io/reader.yo +1 -1
  40. package/std/io/writer.yo +2 -2
  41. package/std/net/addr.yo +1 -1
  42. package/std/net/dns.yo +10 -14
  43. package/std/net/errors.yo +1 -1
  44. package/std/net/tcp.yo +67 -71
  45. package/std/net/udp.yo +36 -40
  46. package/std/os/signal.yo +2 -2
  47. package/std/prelude.yo +27 -21
  48. package/std/process/command.yo +32 -38
  49. package/std/regex/parser.yo +10 -10
  50. package/std/sys/bufio/buf_reader.yo +14 -14
  51. package/std/sys/bufio/buf_writer.yo +17 -17
  52. package/std/sys/errors.yo +1 -1
  53. package/std/thread.yo +2 -2
  54. package/std/url/index.yo +2 -2
  55. package/std/worker.yo +2 -2
@@ -78,7 +78,7 @@ if(done, println("done"), println("pending"));
78
78
  - Always write `match(...)`, never bare `match ...`
79
79
  - `if(a, b)` and `if(a, b, c)` are macro forms over `cond`
80
80
  - Write `return(value)` or `return()`; `return value` is invalid.
81
- - Write `escape(value)` or `escape()`; `escape value` is invalid.
81
+ - Write `unwind(value)` or `unwind()`; `unwind value` is invalid.
82
82
  - If a `match`/`cond` branch returns an enum variant and inference fails, qualify
83
83
  the variant with its enum type: `TypeValue.Unit` instead of `.Unit`.
84
84
  - Do not match enum payload literals directly, e.g. avoid `.Some(false)` and
@@ -121,7 +121,7 @@ masked := ((A | B) | C);
121
121
  - Yo has no operator precedence; fully parenthesize binary expressions
122
122
  - Preserve grouping around infix expressions on operator RHS positions: `true => (x / y)`, `value := (x + y)`, `(ptr &+ 1).*`
123
123
  - Line breaks can disambiguate operator chains; keep line-leading operators like `(4\n| 5\n| 6)` and newlines after `:` before a lambda unless you add equivalent grouping
124
- - When an operator ends a line, indent its RHS one level as a continuation: `(given(x) : T) =\n (v) -> { ... }`
124
+ - When an operator ends a line, indent its RHS one level as a continuation: `(x : T) =\n (v) -> { ... }`
125
125
  - Prefix operators (`!`, `&`, `-`, `~`) require parenthesized operands: `func(&(s), a, b)`, `!(ready)`, `-(value)`.
126
126
  - Tight special forms also require immediate parentheses: `#(expr)`, `?*(u8)`, `T <: !(Runtime)`
127
127
  - Dynamic field access with unquote must keep grouping after the dot: `value.(#(field_expr))`, not `value.#(field_expr)`.
@@ -180,12 +180,12 @@ create_user(name: `Bob`, age: 30);
180
180
  - Named arguments must keep the same order as the definition
181
181
  - Default values use `?=` and must be compile-time known
182
182
 
183
- ### Implicit parameters (`using` / `given`)
183
+ ### Effect parameters (explicit)
184
184
 
185
185
  ```rust
186
- Raise :: (fn(msg : String) -> i32);
186
+ Raise :: (ctl(msg : String) -> i32);
187
187
 
188
- safe_divide :: (fn(x : i32, y : i32, using(raise : Raise)) -> i32)(
188
+ safe_divide :: (fn(x : i32, y : i32, raise : Raise) -> i32)(
189
189
  cond(
190
190
  (y == i32(0)) => raise(`divide by zero`),
191
191
  true => (x / y)
@@ -193,18 +193,20 @@ safe_divide :: (fn(x : i32, y : i32, using(raise : Raise)) -> i32)(
193
193
  );
194
194
 
195
195
  caller :: (fn() -> i32)({
196
- (given(raise) : Raise) = (fn(msg : String) -> i32)({
197
- return(i32(0));
196
+ // Handler value bound to a local. Lambdas on the RHS of `=` need outer parens.
197
+ (raise : Raise) = ((msg) -> {
198
+ unwind(i32(0));
198
199
  });
199
200
 
200
- safe_divide(i32(10), i32(0))
201
+ safe_divide(i32(10), i32(0), raise)
201
202
  });
202
203
  ```
203
204
 
204
- - `using(name : Type)` declares an implicit parameter (effect)
205
- - `given(name) := Type(fields...)` installs a handler in the caller's scope
206
- - Effects are matched by **type**, not by name
207
- - The handler is auto-resolved at call sites; pass explicitly with `using(name)`
205
+ - Effect handlers are regular parameters pass them explicitly at the call site.
206
+ - `ctl(args) -> R` types a handler that may `unwind` (discard the continuation).
207
+ Use plain `fn(args) -> R` for handlers that always resume.
208
+ - Bundle multiple effects into a struct (`Ctx :: struct(raise : Raise, log : Log)`)
209
+ and pass one parameter when there are many.
208
210
 
209
211
  ### Closures and anonymous functions
210
212
 
@@ -724,46 +726,38 @@ if(!cond, { do_thing(); });
724
726
  if((!cond), { do_thing(); });
725
727
  ```
726
728
 
727
- ### `escape` requires a nested-function context
729
+ ### `unwind` requires a nested-function context
728
730
 
729
- `escape(value)` exits the **enclosing function** — the nearest `fn(...)` that
730
- wraps the current code. It requires that the code is inside a nested function
731
- (e.g., a closure or `given` handler lambda), NOT at the top level of a
732
- standalone function definition.
731
+ `unwind(value)` exits the **install frame** — the function that bound the
732
+ `ctl(...) -> R` value being called. It is only valid inside the body of a
733
+ `ctl(...) -> R` value (an effect handler).
733
734
 
734
735
  ```rust
735
- // CORRECT escape inside a given handler lambda (lambda has enclosing fn):
736
- given(exn) := Exception(throw: ((err) -> {
737
- escape(result); // exits the outer function that contains this given()
738
- }));
739
- do_something(using(exn));
736
+ Raise :: (ctl(msg : String) -> i32);
740
737
 
741
- // CORRECT even after process-exit helpers, satisfy the handler's resume type:
742
- given(exn2) := Exception(throw: ((err) -> {
743
- eprintln(err.to_string());
744
- exit(int(1));
745
- escape(); // required because exit() returns unit, not the handler ResumeType
746
- }));
738
+ caller :: (fn() -> i32)({
739
+ // The handler is a `ctl` value bound in `caller`. `unwind` exits `caller`.
740
+ (raise : Raise) = ((msg) -> {
741
+ eprintln(msg);
742
+ unwind(i32(-1));
743
+ });
744
+ safe_divide(i32(10), i32(0), raise) // call site: handler is passed explicitly
745
+ });
747
746
 
748
- // CORRECTescape inside a closure passed as argument:
749
- result := match(opt, .Some(x) => x, .None => {
750
- // This is NOT a nested function — use return:
751
- // WRONG: escape(default_val) // ERROR: no enclosing fn
752
- return(default_val); // CORRECT: return exits the enclosing fn directly
747
+ // WRONG`unwind` in a regular `fn` body (no install frame here) is rejected.
748
+ bad :: (fn() -> unit)({
749
+ unwind(()); // ERROR: unwind requires a ctl(...) body
753
750
  });
754
751
 
755
- // WRONG — escape inside a match arm (not a nested fn):
756
- match(opt,
757
- .Some(x) => { escape(x); } // ERROR: "can only be used inside a function that has an enclosing function"
752
+ // WRONG — capturing a `ctl` value into a closure is rejected (closures escape).
753
+ make_closure :: (fn(raise : Raise) -> Impl(Fn() -> unit))(
754
+ () => { raise(`x`); } // ERROR: closure captures a control-bound value
758
755
  );
759
756
  ```
760
757
 
761
- **Rule of thumb**: Use `escape` only inside lambdas passed to `given()` handlers.
762
- In all other contexts (match arms, if blocks, begin blocks, top-level fn bodies),
763
- use `return` for early exit.
764
-
765
- `return` inside a lambda exits that lambda only; `escape` exits the OUTER function
766
- (the one that installed the `given` handler).
758
+ **Rule of thumb**: `unwind` belongs only inside the lambda bound to a
759
+ `ctl(...) -> R` handler. From any other position, use `return` to exit the
760
+ current `fn`.
767
761
 
768
762
  ### Parameter reassignment
769
763
 
@@ -818,19 +812,19 @@ fn_taking_str((`prefix_${value}`).as_str());
818
812
 
819
813
  These features are powerful but less commonly used. Consult the linked docs for full details.
820
814
 
821
- | Feature | Syntax hint | Documentation |
822
- | ---------------------- | -------------------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------- |
823
- | Higher-Kinded Types | `forall(F : (fn(comptime(T) : Type) -> comptime(Type)))` | [DESIGN.md § HKT](https://github.com/shd101wyy/Yo/blob/develop/docs/en-US/DESIGN.md#higher-kinded-types-hkt) |
824
- | GADTs | `enum(IntVal(i : i32) -> recur(i32))` | [GADTS.md](https://github.com/shd101wyy/Yo/blob/develop/docs/en-US/GADTS.md) |
825
- | Derive traits | `derive(MyType, Eq, Hash, Clone, Ord, ToString)` | [DERIVE_TRAITS.md](https://github.com/shd101wyy/Yo/blob/develop/docs/en-US/DERIVE_TRAITS.md) |
826
- | Type reflection | `Type.get_info(T)` returns `TypeInfo` | [TYPE_REFLECTION.md](https://github.com/shd101wyy/Yo/blob/develop/docs/en-US/TYPE_REFLECTION.md) |
827
- | Inline assembly | `asm("mov {0}, #42", out(reg, i32))` | [INLINE_ASSEMBLY.md](https://github.com/shd101wyy/Yo/blob/develop/docs/en-US/INLINE_ASSEMBLY.md) |
828
- | Metaprogramming | `quote(...)`, `unquote(...)`, `unquote_splicing(...)` | [DESIGN.md § Meta](https://github.com/shd101wyy/Yo/blob/develop/docs/en-US/DESIGN.md#meta-programming) |
829
- | Effect row variables | `forall(...(E))` with `using(...(E))` | [ALGEBRAIC_EFFECTS.md](https://github.com/shd101wyy/Yo/blob/develop/docs/en-US/ALGEBRAIC_EFFECTS.md) |
830
- | Custom derive rules | `derive_rule(MyTrait, (fn(...) -> unquote(Expr)){...})` | [DERIVE_TRAITS.md](https://github.com/shd101wyy/Yo/blob/develop/docs/en-US/DERIVE_TRAITS.md#user-defined-derive-rules) |
831
- | Isolated types | `Iso(T)` for data-race-free parallelism | [ISOLATED.md](https://github.com/shd101wyy/Yo/blob/develop/docs/en-US/ISOLATED.md) |
832
- | Arc (atomic ref count) | `arc(value)`, `shared.(*)` for cross-thread sharing | [ARC.md](https://github.com/shd101wyy/Yo/blob/develop/docs/en-US/ARC.md) |
833
- | Parallelism | Thread pool, `io.spawn` for parallel work | [PARALLELISM.md](https://github.com/shd101wyy/Yo/blob/develop/docs/en-US/PARALLELISM.md) |
815
+ | Feature | Syntax hint | Documentation |
816
+ | -------------------------- | -------------------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------- |
817
+ | Higher-Kinded Types | `forall(F : (fn(comptime(T) : Type) -> comptime(Type)))` | [DESIGN.md § HKT](https://github.com/shd101wyy/Yo/blob/develop/docs/en-US/DESIGN.md#higher-kinded-types-hkt) |
818
+ | GADTs | `enum(IntVal(i : i32) -> recur(i32))` | [GADTS.md](https://github.com/shd101wyy/Yo/blob/develop/docs/en-US/GADTS.md) |
819
+ | Derive traits | `derive(MyType, Eq, Hash, Clone, Ord, ToString)` | [DERIVE_TRAITS.md](https://github.com/shd101wyy/Yo/blob/develop/docs/en-US/DERIVE_TRAITS.md) |
820
+ | Type reflection | `Type.get_info(T)` returns `TypeInfo` | [TYPE_REFLECTION.md](https://github.com/shd101wyy/Yo/blob/develop/docs/en-US/TYPE_REFLECTION.md) |
821
+ | Inline assembly | `asm("mov {0}, #42", out(reg, i32))` | [INLINE_ASSEMBLY.md](https://github.com/shd101wyy/Yo/blob/develop/docs/en-US/INLINE_ASSEMBLY.md) |
822
+ | Metaprogramming | `quote(...)`, `unquote(...)`, `unquote_splicing(...)` | [DESIGN.md § Meta](https://github.com/shd101wyy/Yo/blob/develop/docs/en-US/DESIGN.md#meta-programming) |
823
+ | Effect bundle polymorphism | `forall(E : Type.Struct)` over a bundle struct | [ALGEBRAIC_EFFECTS.md](https://github.com/shd101wyy/Yo/blob/develop/docs/en-US/ALGEBRAIC_EFFECTS.md) |
824
+ | Custom derive rules | `derive_rule(MyTrait, (fn(...) -> unquote(Expr)){...})` | [DERIVE_TRAITS.md](https://github.com/shd101wyy/Yo/blob/develop/docs/en-US/DERIVE_TRAITS.md#user-defined-derive-rules) |
825
+ | Isolated types | `Iso(T)` for data-race-free parallelism | [ISOLATED.md](https://github.com/shd101wyy/Yo/blob/develop/docs/en-US/ISOLATED.md) |
826
+ | Arc (atomic ref count) | `arc(value)`, `shared.(*)` for cross-thread sharing | [ARC.md](https://github.com/shd101wyy/Yo/blob/develop/docs/en-US/ARC.md) |
827
+ | Parallelism | Thread pool, `io.spawn` for parallel work | [PARALLELISM.md](https://github.com/shd101wyy/Yo/blob/develop/docs/en-US/PARALLELISM.md) |
834
828
 
835
829
  ---
836
830
 
@@ -997,26 +991,6 @@ Always merge them into a single destructuring import:
997
991
  { Foo, Bar } :: import("../../mod.yo");
998
992
  ```
999
993
 
1000
- ### Implicit (`using`) parameters cannot be used with `:=` assignment
1001
-
1002
- Implicit effect parameters introduced via `using(name : Type)` cannot be bound
1003
- to a discarded variable with `:= name`. They can only be passed via `using()`.
1004
- To suppress "unused parameter" warnings for an implicit param, simply omit the
1005
- discard assignment — implicit params never trigger unused-variable errors.
1006
-
1007
- ```rust
1008
- // WRONG — implicit variable cannot be used in assignment:
1009
- foo :: (fn(using(exn : Exception)) -> unit)({
1010
- _ := exn; // ERROR: Cannot use implicit variable "exn" in assignment
1011
- ()
1012
- });
1013
-
1014
- // CORRECT — just omit the discard line:
1015
- foo :: (fn(using(exn : Exception)) -> unit)({
1016
- ()
1017
- });
1018
- ```
1019
-
1020
994
  ### Nested `Option` patterns require staging
1021
995
 
1022
996
  `match` does not support nested destructuring patterns like `.Some(.TypeVal(x))`.
package/README.md CHANGED
@@ -8,6 +8,8 @@
8
8
 
9
9
  https://shd101wyy.github.io/Yo
10
10
 
11
+ **LLM-friendly to write, human-friendly to read.**
12
+
11
13
  A multi-paradigm, general-purpose, compiled programming language.
12
14
  Yo aims to be **Simple** and **Fast** (around 0% - 15% slower than C).
13
15