Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 4 additions & 4 deletions editors/vscode/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -67,7 +67,7 @@ fn add(x: Int, y: Int) -> Int {
}

// Impure function with IO effect
fn main() -> Unit / io {
fn main() -> Unit / IO {
println("Hello, AffineScript!");
let result = add(40, 2);
println(int_to_string(result));
Expand All @@ -79,11 +79,11 @@ fn main() -> Unit / io {
```affinescript
// Pure functions cannot call impure functions
fn pure() -> Int {
return read_line(); // ❌ ERROR: Cannot perform effect io in pure context
return read_line(); // ❌ ERROR: Cannot perform effect IO in pure context
}

// Impure functions can call pure or impure
fn impure() -> Int / io {
fn impure() -> Int / IO {
return read_line(); // ✅ OK
}
```
Expand All @@ -95,7 +95,7 @@ fn use_value(x: @affine String) -> Unit {
println(x); // x is consumed here
}

fn main() -> Unit / io {
fn main() -> Unit / IO {
let s = "hello";
use_value(s);
println(s); // ❌ ERROR: use after move
Expand Down
15 changes: 7 additions & 8 deletions lib/effect.ml
Original file line number Diff line number Diff line change
Expand Up @@ -137,14 +137,13 @@ let v1_effects = [ "IO"; "Async"; "Partial"; "Throws"; "Mut" ]
yet wired into the stdlib. *)
let reserved_effects = [ "Random"; "Time"; "Net" ]

(** Legacy lowercase stdlib effects → canonical v1. Kept as aliases so
[stdlib/effects.affine] and existing code compile unchanged
(additive migration; a rename sweep is a later, separate change). *)
let legacy_aliases = [ ("io", "IO"); ("state", "Mut"); ("exn", "Throws") ]

(** Canonical registry name for a source effect name, or [None] if it is
neither a v1/reserved name nor a legacy alias. Callers additionally
accept user-declared effects (`effect <name>;`). *)
neither a v1 nor a reserved name. Callers additionally accept
user-declared effects (`effect <name>;`).

The lowercase [io]/[state]/[exn] migration aliases were retired once
[stdlib/effects.affine] was renamed to the canonical names; legacy
lowercase effect names are now only valid if explicitly declared. *)
let canonical_effect_name (s : string) : string option =
if List.mem s v1_effects || List.mem s reserved_effects then Some s
else List.assoc_opt s legacy_aliases
else None
3 changes: 0 additions & 3 deletions lib/effect.mli
Original file line number Diff line number Diff line change
Expand Up @@ -35,9 +35,6 @@ val v1_effects : string list
(** Reserved-for-v1.x effect names. *)
val reserved_effects : string list

(** Legacy lowercase stdlib effect → canonical v1 name. *)
val legacy_aliases : (string * string) list

(** Canonical registry name for a source effect name, or [None] if
unknown to the registry (caller also accepts declared effects). *)
val canonical_effect_name : string -> string option
26 changes: 13 additions & 13 deletions stdlib/effects.affine
Original file line number Diff line number Diff line change
Expand Up @@ -2,31 +2,31 @@
// AffineScript Standard Library - Effect Declarations

// Core IO effect - file and console operations
effect io;
effect IO;

// State effect - mutable references
effect state;
effect Mut;

// Exception effect - panics and error handling
effect exn;
effect Throws;

// Built-in IO operations
extern fn print(s: String) -> Unit / io;
extern fn println(s: String) -> Unit / io;
extern fn read_line() -> String / io;
extern fn read_file(path: String) -> String / io;
extern fn write_file(path: String, content: String) -> Unit / io;
extern fn print(s: String) -> Unit / IO;
extern fn println(s: String) -> Unit / IO;
extern fn read_line() -> String / IO;
extern fn read_file(path: String) -> String / IO;
extern fn write_file(path: String, content: String) -> Unit / IO;

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

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

// Pure operations (no effects)
extern fn int_to_string(n: Int) -> String;
Expand Down
Loading