// ── delegates_and_pointers ── // E# — a verified example from the E# language corpus (CLR language; .es, not ECMAScript). // provenance: delegates_and_pointers.es topic: delegates-events status: verified // hand-authored, idiomatic E# — verified through the E# compiler namespace Demo // ═════════════════════════════════════════════════════════════════════════════ // Passing behavior as a value: E# has three callable forms, chosen by intent. // // 1. Function pointer — `&func`, type `&(int, int -> int)`. Zero allocation, no GC: // `ldftn` + `calli`. The systems tier — hot paths, dispatch tables. (C# needs // `unsafe` + `delegate*` for this; E# makes it safe by construction.) // 2. Nominal delegate — `delegate func Name(...)`. A named `MulticastDelegate` type, // distinct from any structurally-identical delegate. Intent-named, interop-friendly. // 3. BCL delegate — `Func<...>` / `Action<...>`. Structural, heap, multicast. The // framework-callback tier. // // A bare function name converts to whichever delegate type is expected (method-group // conversion), and a lambda's parameter types are inferred from the target. // ═════════════════════════════════════════════════════════════════════════════ // (2) A NOMINAL delegate type. `BinOp` is its own type — a `Func` is NOT a // `BinOp`, even though both wrap (int, int) -> int. delegate func BinOp(a: int, b: int) -> int func add(a: int, b: int) -> int = a + b func mul(a: int, b: int) -> int = a * b // Parameter typed as the nominal delegate. A bare `add` passed here converts (method group). func apply(op: BinOp, a: int, b: int) -> int = op(a, b) // Parameter typed as a BCL `Func`. A lambda converts, its `x` inferred as int. func applyFunc(f: Func, x: int) -> int = f(x) // Parameter typed as a function POINTER. `&name` takes the address; the call is a `calli`, // with no delegate object allocated. func applyPtr(f: &(int, int -> int), a: int, b: int) -> int = f(a, b) func main() -> int { let viaDelegate = apply(add, 3, 4) // 7 — method group → nominal delegate let viaLambda = applyFunc((x) => x * 2, 10) // 20 — lambda → Func let viaPointer = applyPtr(&mul, 5, 6) // 30 — &mul → ldftn + calli, zero alloc return viaDelegate + viaLambda + viaPointer // 57 } // ── events ── // E# — a verified example from the E# language corpus (CLR language; .es, not ECMAScript). // provenance: events.es topic: delegates-events status: verified // hand-authored, idiomatic E# — verified through the E# compiler namespace Demo // ═════════════════════════════════════════════════════════════════════════════ // Events — a controlled subscription point over a delegate. The delegate is the payload; // the event only governs who may subscribe (`+=`) and unsubscribe (`-=`). Outside code // can't invoke or replace it. Events are declared on `ref data` (they imply identity), // fired with the null-safe `raise` statement, and emit exactly what C# emits for // `public event Action OnChanged;` — so a C# consumer subscribes with `+=` unchanged. // ═════════════════════════════════════════════════════════════════════════════ // A counter that announces every change. `event OnChanged: Action` declares the // subscription point, typed by the `Action` delegate. ref data Counter { var total: int event OnChanged: Action init() { self.total = 0 } func add(n: int) { self.total = self.total + n // `raise` captures the handler list then invokes it — a no-op when there are no // subscribers, and safe against a handler unsubscribing mid-raise. raise OnChanged(self.total) } } func main() -> int { var lastSeen = 0 // mutable local, captured by the handler below let c = Counter() // Subscribe a lambda whose shape matches the event's Action. Closures capture // outer `var`s mutably, so each raise writes the new total back into `lastSeen`. c.OnChanged += func(v: int) -> void { lastSeen = v } c.add(5) // total 5 → OnChanged(5) → lastSeen = 5 c.add(3) // total 8 → OnChanged(8) → lastSeen = 8 return lastSeen // 8 — proof the event fired and the handler ran } // ── ILEmitterTests_Delegates__DelegateFunc_AsParam_MethodGroupArg_Invoked ── // E# — a verified example from the E# language corpus (CLR language; .es, not ECMAScript). // provenance: ILEmitterTests_Delegates.cs::DelegateFunc_AsParam_MethodGroupArg_Invoked topic: delegates-events status: verified // verified behavior: Test.test(...) == 42 namespace Test delegate func BinOp(a: int, b: int) -> int func apply(f: BinOp, a: int, b: int) -> int = f(a, b) func add(a: int, b: int) -> int = a + b func test() -> int = apply(add, 20, 22) // ── ILEmitterTests_Delegates__DelegateFunc_EmitsMulticastDelegateSubclass_WithInvoke ── // E# — a verified example from the E# language corpus (CLR language; .es, not ECMAScript). // provenance: ILEmitterTests_Delegates.cs::DelegateFunc_EmitsMulticastDelegateSubclass_WithInvoke topic: delegates-events status: verified // compiles cleanly (no auto-run claim was extracted) namespace Test delegate func BinOp(a: int, b: int) -> int // ── ILEmitterTests_Delegates__DelegateFunc_IsNominal_NotAForwarder_NotAFunc ── // E# — a verified example from the E# language corpus (CLR language; .es, not ECMAScript). // provenance: ILEmitterTests_Delegates.cs::DelegateFunc_IsNominal_NotAForwarder_NotAFunc topic: delegates-events status: verified // compiles cleanly (no auto-run claim was extracted) namespace Test delegate func BinOp(a: int, b: int) -> int func add(a: int, b: int) -> int = a + b func get_op() -> BinOp = add // ── ILEmitterTests_Delegates__DelegateFunc_Lambda_Let_Invoked ── // E# — a verified example from the E# language corpus (CLR language; .es, not ECMAScript). // provenance: ILEmitterTests_Delegates.cs::DelegateFunc_Lambda_Let_Invoked topic: delegates-events status: verified // verified behavior: Test.test(...) == 42 namespace Test delegate func BinOp(a: int, b: int) -> int func test() -> int { let op: BinOp = (a, b) => a + b return op(40, 2) } // ── ILEmitterTests_Delegates__DelegateFunc_MethodGroup_Let_Invoked ── // E# — a verified example from the E# language corpus (CLR language; .es, not ECMAScript). // provenance: ILEmitterTests_Delegates.cs::DelegateFunc_MethodGroup_Let_Invoked topic: delegates-events status: verified // verified behavior: Test.test(...) == 42 namespace Test delegate func BinOp(a: int, b: int) -> int func add(a: int, b: int) -> int = a + b func test() -> int { let op: BinOp = add return op(19, 23) } // ── ILEmitterTests_Delegates__DelegateFunc_ReturnedAndInvoked ── // E# — a verified example from the E# language corpus (CLR language; .es, not ECMAScript). // provenance: ILEmitterTests_Delegates.cs::DelegateFunc_ReturnedAndInvoked topic: delegates-events status: verified // verified behavior: Test.test(...) == 42 namespace Test delegate func BinOp(a: int, b: int) -> int func add(a: int, b: int) -> int = a + b func get_op() -> BinOp = add func test() -> int { let op = get_op() return op(13, 29) } // ── ILEmitterTests_Delegates__DelegateFunc_ThreeParams_MethodGroup_Invoked ── // E# — a verified example from the E# language corpus (CLR language; .es, not ECMAScript). // provenance: ILEmitterTests_Delegates.cs::DelegateFunc_ThreeParams_MethodGroup_Invoked topic: delegates-events status: verified // verified behavior: Test.test(...) == 42 namespace Test delegate func Tri(a: int, b: int, c: int) -> int func add3(a: int, b: int, c: int) -> int = a + b + c func test() -> int { let f: Tri = add3 return f(10, 20, 12) } // ── ILEmitterTests_Delegates__DelegateFunc_VoidReturn_CapturingLambda_Invoked ── // E# — a verified example from the E# language corpus (CLR language; .es, not ECMAScript). // provenance: ILEmitterTests_Delegates.cs::DelegateFunc_VoidReturn_CapturingLambda_Invoked topic: delegates-events status: verified // verified behavior: Test.test(...) == 3 namespace Test delegate func Tick() func run(t: Tick, n: int) { var i = 0 while i < n { t() i += 1 } } func test() -> int { var count = 0 let t: Tick = func() { count += 1 } run(t, 3) return count } // ── ILEmitterTests_Delegates__MethodGroup_AsArgument_Invoked ── // E# — a verified example from the E# language corpus (CLR language; .es, not ECMAScript). // provenance: ILEmitterTests_Delegates.cs::MethodGroup_AsArgument_Invoked topic: delegates-events status: verified // verified behavior: Test.test(...) == 10 namespace Test func dbl(x: int) -> int = x * 2 func apply(x: int, f: Func) -> int = f(x) func test() -> int = apply(5, dbl) // ── ILEmitterTests_Delegates__MethodGroup_BindsRealMethod_NotAForwarder ── // E# — a verified example from the E# language corpus (CLR language; .es, not ECMAScript). // provenance: ILEmitterTests_Delegates.cs::MethodGroup_BindsRealMethod_NotAForwarder topic: delegates-events status: verified // compiles cleanly (no auto-run claim was extracted) namespace Test func dbl(x: int) -> int = x * 2 func get() -> Func = dbl // ── ILEmitterTests_Delegates__MethodGroup_ToExternalNamedDelegate_Bridges ── // E# — a verified example from the E# language corpus (CLR language; .es, not ECMAScript). // provenance: ILEmitterTests_Delegates.cs::MethodGroup_ToExternalNamedDelegate_Bridges topic: delegates-events status: verified // verified behavior: Test.test(...) == true namespace Test func is_even(x: int) -> bool = x % 2 == 0 func test() -> bool { let p: Predicate = is_even return p(4) } // ── ILEmitterTests_Delegates__MethodGroup_ToFunc_Local_Invoked ── // E# — a verified example from the E# language corpus (CLR language; .es, not ECMAScript). // provenance: ILEmitterTests_Delegates.cs::MethodGroup_ToFunc_Local_Invoked topic: delegates-events status: verified // verified behavior: Test.test(...) == 42 namespace Test func dbl(x: int) -> int = x * 2 func test() -> int { let f: Func = dbl return f(21) } // ── ILEmitterTests_Events__Event_Declared_EmitsCanonicalClrShape ── // E# — a verified example from the E# language corpus (CLR language; .es, not ECMAScript). // provenance: ILEmitterTests_Events.cs::Event_Declared_EmitsCanonicalClrShape topic: delegates-events status: verified // compiles cleanly (no auto-run claim was extracted) namespace Test delegate func Notify(value: int) pub ref data Server { pub event OnReady: Notify } // ── ILEmitterTests_Events__Event_EsharpSideSubscription_AddAndRemove ── // E# — a verified example from the E# language corpus (CLR language; .es, not ECMAScript). // provenance: ILEmitterTests_Events.cs::Event_EsharpSideSubscription_AddAndRemove topic: delegates-events status: verified // compiles cleanly (no auto-run claim was extracted) namespace Test pub ref data Counter { var total: int pub event OnChanged: Action pub func wire(h: Action) { self.OnChanged += h } pub func unwire(h: Action) { self.OnChanged -= h } pub func add(n: int) { self.total = self.total + n raise OnChanged(self.total) } } // ── ILEmitterTests_Events__Event_Interface_EmitsAbstractAccessorsAndEventDef ── // E# — a verified example from the E# language corpus (CLR language; .es, not ECMAScript). // provenance: ILEmitterTests_Events.cs::Event_Interface_EmitsAbstractAccessorsAndEventDef topic: delegates-events status: verified // compiles cleanly (no auto-run claim was extracted) namespace Test pub interface IRuntime { event OnReady: Action } // ── ILEmitterTests_Events__Event_MultipleEvents_AreIndependent ── // E# — a verified example from the E# language corpus (CLR language; .es, not ECMAScript). // provenance: ILEmitterTests_Events.cs::Event_MultipleEvents_AreIndependent topic: delegates-events status: verified // compiles cleanly (no auto-run claim was extracted) namespace Test pub ref data Bus { pub event OnA: Action pub event OnB: Action pub func fireA(v: int) { raise OnA(v) } pub func fireB(v: int) { raise OnB(v) } } // ── ILEmitterTests_Events__Event_Raise_InvokesSubscribers ── // E# — a verified example from the E# language corpus (CLR language; .es, not ECMAScript). // provenance: ILEmitterTests_Events.cs::Event_Raise_InvokesSubscribers topic: delegates-events status: verified // compiles cleanly (no auto-run claim was extracted) namespace Test pub ref data Counter { var total: int pub event OnChanged: Action pub func add(n: int) { self.total = self.total + n raise OnChanged(self.total) } } // ── ILEmitterTests_Events__Event_Raise_NoSubscribers_DoesNotThrow ── // E# — a verified example from the E# language corpus (CLR language; .es, not ECMAScript). // provenance: ILEmitterTests_Events.cs::Event_Raise_NoSubscribers_DoesNotThrow topic: delegates-events status: verified // compiles cleanly (no auto-run claim was extracted) namespace Test pub ref data Bell { pub event OnRing: Action pub func ring() { raise OnRing() } } // ── ILEmitterTests_Events__Event_TypedByEventHandlerGeneric_EmitsCorrectShape ── // E# — a verified example from the E# language corpus (CLR language; .es, not ECMAScript). // provenance: ILEmitterTests_Events.cs::Event_TypedByEventHandlerGeneric_EmitsCorrectShape topic: delegates-events status: verified // compiles cleanly (no auto-run claim was extracted) namespace Test pub ref data Widget { pub event OnResize: EventHandler } // ── ILEmitterTests_Events__Event_Unsubscribe_StopsDelivery ── // E# — a verified example from the E# language corpus (CLR language; .es, not ECMAScript). // provenance: ILEmitterTests_Events.cs::Event_Unsubscribe_StopsDelivery topic: delegates-events status: verified // compiles cleanly (no auto-run claim was extracted) namespace Test pub ref data Hub { pub event OnPing: Action pub func ping(v: int) { raise OnPing(v) } } // ── ILEmitterTests2__Field_With_Function_Pointer_Type_Pin ── // E# — a verified example from the E# language corpus (CLR language; .es, not ECMAScript). // provenance: ILEmitterTests2.cs::Field_With_Function_Pointer_Type_Pin topic: delegates-events status: verified // verified behavior: Test.test(...) == 42 namespace Test data Dispatch { handler: &(int -> int) } func double_it(x: int) -> int = x * 2 func test() -> int { let d = Dispatch { handler: double_it } return d.handler(21) } // ── ILEmitterTests2__Function_Literal_Inline_Argument ── // E# — a verified example from the E# language corpus (CLR language; .es, not ECMAScript). // provenance: ILEmitterTests2.cs::Function_Literal_Inline_Argument topic: delegates-events status: verified // verified behavior: Test.test(...) == 42 namespace Test func apply(f: &(int -> int), n: int) -> int = f(n) func test() -> int = apply(func(x: int) -> int = x + 1, 41) // ── ILEmitterTests2__Function_Literal_Passed_To_Function ── // E# — a verified example from the E# language corpus (CLR language; .es, not ECMAScript). // provenance: ILEmitterTests2.cs::Function_Literal_Passed_To_Function topic: delegates-events status: verified // verified behavior: Test.test(...) == 42 namespace Test func apply(f: &(int -> int), n: int) -> int = f(n) func test() -> int { let double: &(int -> int) = func(x: int) -> int = x * 2 return apply(double, 21) } // ── ILEmitterTests3__Arrow_Lambda_Single_Param ── // E# — a verified example from the E# language corpus (CLR language; .es, not ECMAScript). // provenance: ILEmitterTests3.cs::Arrow_Lambda_Single_Param topic: delegates-events status: verified // verified behavior: Test.test(...) == 25 namespace Test func apply(x: int, f: &(int -> int)) -> int = f(x) func test() -> int { let sq: &(int -> int) = (x) => x * x return apply(5, sq) } // ── ILEmitterTests3__Arrow_Lambda_Two_Params ── // E# — a verified example from the E# language corpus (CLR language; .es, not ECMAScript). // provenance: ILEmitterTests3.cs::Arrow_Lambda_Two_Params topic: delegates-events status: verified // verified behavior: Test.test(...) == 10 namespace Test func apply(a: int, b: int, f: &(int, int -> int)) -> int = f(a, b) func test() -> int { let add: &(int, int -> int) = (a, b) => a + b return apply(3, 7, add) } // ── ILEmitterTests3__Data_Field_Function_Pointer_Pin ── // E# — a verified example from the E# language corpus (CLR language; .es, not ECMAScript). // provenance: ILEmitterTests3.cs::Data_Field_Function_Pointer_Pin topic: delegates-events status: verified // verified behavior: Test.test(...) == 42 namespace Test data Op { apply: &(int -> int) } func add_one(x: int) -> int = x + 1 func double_it(x: int) -> int = x * 2 func test() -> int { let op = Op { apply: &add_one } return op.apply(41) } // ── ILEmitterTests3__Function_Pointer_Param_Called_Via_Calli ── // E# — a verified example from the E# language corpus (CLR language; .es, not ECMAScript). // provenance: ILEmitterTests3.cs::Function_Pointer_Param_Called_Via_Calli topic: delegates-events status: verified // verified behavior: Test.test(...) == 42 namespace Test func apply(f: &(int -> int), n: int) -> int = f(n) func double_it(x: int) -> int = x * 2 func test() -> int = apply(&double_it, 21) // ── ILEmitterTests3__Function_Pointer_Two_Args ── // E# — a verified example from the E# language corpus (CLR language; .es, not ECMAScript). // provenance: ILEmitterTests3.cs::Function_Pointer_Two_Args topic: delegates-events status: verified // verified behavior: Test.test(...) == 37 namespace Test func apply(f: &(int, int -> int), a: int, b: int) -> int = f(a, b) func add(x: int, y: int) -> int = x + y func mul(x: int, y: int) -> int = x * y func test() -> int = apply(&add, 3, 4) + apply(&mul, 5, 6) // ── ILEmitterTests_Delegates__MethodGroup_Unannotated_Let_IsRejected ── // E# — a verified example from the E# language corpus (CLR language; .es, not ECMAScript). // provenance: ILEmitterTests_Delegates.cs::MethodGroup_Unannotated_Let_IsRejected topic: delegates-events status: unverified // compiles cleanly (no auto-run claim was extracted) namespace Test func dbl(x: int) -> int = x * 2 func test() -> int { let f = dbl return f(21) } // ── ILEmitterTests_Events__Event_NonDelegateType_IsRejected ── // E# — a verified example from the E# language corpus (CLR language; .es, not ECMAScript). // provenance: ILEmitterTests_Events.cs::Event_NonDelegateType_IsRejected topic: delegates-events status: unverified // compiles cleanly (no auto-run claim was extracted) namespace Test ref data Bad { event OnX: int } // ── ILEmitterTests_Events__Event_OnValueData_IsRejected ── // E# — a verified example from the E# language corpus (CLR language; .es, not ECMAScript). // provenance: ILEmitterTests_Events.cs::Event_OnValueData_IsRejected topic: delegates-events status: unverified // compiles cleanly (no auto-run claim was extracted) namespace Test data Bad { event OnX: Action }