Skip to content

Commit ad50525

Browse files
refactor(effects): rename stdlib io/state/exn→IO/Mut/Throws, retire aliases (Refs #59) (#203)
STAGE-B cleanup. PR-1 (#196) added legacy lowercase aliases as a migration bridge; now that nothing depends on them, retire them and move the stdlib to the canonical v1 names. - stdlib/effects.affine: `effect io/state/exn` → `IO/Mut/Throws`; all 10 `/ io|state|exn` annotations → canonical. - effect.ml/.mli: remove `legacy_aliases`; `canonical_effect_name` is now v1 ∪ reserved only. Lowercase effect names are henceforth valid only if explicitly `effect <name>;`-declared (so the user-declared `effect io;` test in test_e2e.ml is unaffected — verified). - editors/vscode/README.md: doc snippets `/ io` → `/ IO` for accuracy now the alias is gone. dune build clean; dune test --force 253/253, zero regression (incl. AOT effects smoke + the user-declared-effect e2e test). Refs #59 Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
1 parent ab810cb commit ad50525

4 files changed

Lines changed: 24 additions & 28 deletions

File tree

editors/vscode/README.md

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -67,7 +67,7 @@ fn add(x: Int, y: Int) -> Int {
6767
}
6868
6969
// Impure function with IO effect
70-
fn main() -> Unit / io {
70+
fn main() -> Unit / IO {
7171
println("Hello, AffineScript!");
7272
let result = add(40, 2);
7373
println(int_to_string(result));
@@ -79,11 +79,11 @@ fn main() -> Unit / io {
7979
```affinescript
8080
// Pure functions cannot call impure functions
8181
fn pure() -> Int {
82-
return read_line(); // ❌ ERROR: Cannot perform effect io in pure context
82+
return read_line(); // ❌ ERROR: Cannot perform effect IO in pure context
8383
}
8484
8585
// Impure functions can call pure or impure
86-
fn impure() -> Int / io {
86+
fn impure() -> Int / IO {
8787
return read_line(); // ✅ OK
8888
}
8989
```
@@ -95,7 +95,7 @@ fn use_value(x: @affine String) -> Unit {
9595
println(x); // x is consumed here
9696
}
9797
98-
fn main() -> Unit / io {
98+
fn main() -> Unit / IO {
9999
let s = "hello";
100100
use_value(s);
101101
println(s); // ❌ ERROR: use after move

lib/effect.ml

Lines changed: 7 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -137,14 +137,13 @@ let v1_effects = [ "IO"; "Async"; "Partial"; "Throws"; "Mut" ]
137137
yet wired into the stdlib. *)
138138
let reserved_effects = [ "Random"; "Time"; "Net" ]
139139

140-
(** Legacy lowercase stdlib effects → canonical v1. Kept as aliases so
141-
[stdlib/effects.affine] and existing code compile unchanged
142-
(additive migration; a rename sweep is a later, separate change). *)
143-
let legacy_aliases = [ ("io", "IO"); ("state", "Mut"); ("exn", "Throws") ]
144-
145140
(** Canonical registry name for a source effect name, or [None] if it is
146-
neither a v1/reserved name nor a legacy alias. Callers additionally
147-
accept user-declared effects (`effect <name>;`). *)
141+
neither a v1 nor a reserved name. Callers additionally accept
142+
user-declared effects (`effect <name>;`).
143+
144+
The lowercase [io]/[state]/[exn] migration aliases were retired once
145+
[stdlib/effects.affine] was renamed to the canonical names; legacy
146+
lowercase effect names are now only valid if explicitly declared. *)
148147
let canonical_effect_name (s : string) : string option =
149148
if List.mem s v1_effects || List.mem s reserved_effects then Some s
150-
else List.assoc_opt s legacy_aliases
149+
else None

lib/effect.mli

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -35,9 +35,6 @@ val v1_effects : string list
3535
(** Reserved-for-v1.x effect names. *)
3636
val reserved_effects : string list
3737

38-
(** Legacy lowercase stdlib effect → canonical v1 name. *)
39-
val legacy_aliases : (string * string) list
40-
4138
(** Canonical registry name for a source effect name, or [None] if
4239
unknown to the registry (caller also accepts declared effects). *)
4340
val canonical_effect_name : string -> string option

stdlib/effects.affine

Lines changed: 13 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -2,31 +2,31 @@
22
// AffineScript Standard Library - Effect Declarations
33

44
// Core IO effect - file and console operations
5-
effect io;
5+
effect IO;
66

77
// State effect - mutable references
8-
effect state;
8+
effect Mut;
99

1010
// Exception effect - panics and error handling
11-
effect exn;
11+
effect Throws;
1212

1313
// Built-in IO operations
14-
extern fn print(s: String) -> Unit / io;
15-
extern fn println(s: String) -> Unit / io;
16-
extern fn read_line() -> String / io;
17-
extern fn read_file(path: String) -> String / io;
18-
extern fn write_file(path: String, content: String) -> Unit / io;
14+
extern fn print(s: String) -> Unit / IO;
15+
extern fn println(s: String) -> Unit / IO;
16+
extern fn read_line() -> String / IO;
17+
extern fn read_file(path: String) -> String / IO;
18+
extern fn write_file(path: String, content: String) -> Unit / IO;
1919

2020
// Built-in State operations
2121
// `make_ref` (not `ref`) because `ref` is a reserved ownership keyword;
2222
// see #135 keyword-as-identifier slice.
23-
extern fn make_ref<T>(x: T) -> Ref<T> / state;
24-
extern fn get<T>(r: Ref<T>) -> T / state;
25-
extern fn set<T>(r: Ref<T>, x: T) -> Unit / state;
23+
extern fn make_ref<T>(x: T) -> Ref<T> / Mut;
24+
extern fn get<T>(r: Ref<T>) -> T / Mut;
25+
extern fn set<T>(r: Ref<T>, x: T) -> Unit / Mut;
2626

2727
// Built-in Exception operations
28-
extern fn panic(msg: String) -> Never / exn;
29-
extern fn error<T>(msg: String) -> T / exn;
28+
extern fn panic(msg: String) -> Never / Throws;
29+
extern fn error<T>(msg: String) -> T / Throws;
3030

3131
// Pure operations (no effects)
3232
extern fn int_to_string(n: Int) -> String;

0 commit comments

Comments
 (0)