delegates events — examples
← all topics · 33 examples · page 1 of 1 · raw source ↓
Showcase example
// 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<int,int,int>` 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<int, int>, 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<int,int>
let viaPointer = applyPtr(&mul, 5, 6) // 30 — &mul → ldftn + calli, zero alloc
return viaDelegate + viaLambda + viaPointer // 57
}
Showcase example
// 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<int> OnChanged;` — so a C# consumer subscribes with `+=` unchanged.
// ═════════════════════════════════════════════════════════════════════════════
// A counter that announces every change. `event OnChanged: Action<int>` declares the
// subscription point, typed by the `Action<int>` delegate.
ref data Counter {
var total: int
event OnChanged: Action<int>
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<int>. 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
delegates events runnable verifiedRuns `test` → 42
// 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
delegates events unknown verifiedCompiles
// 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) -> intILEmitterTests_Delegates__DelegateFunc_IsNominal_NotAForwarder_NotAFunc
delegates events unknown verifiedCompiles
// 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 = addRuns `test` → 42
// 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)
}Runs `test` → 42
// 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)
}Runs `test` → 42
// 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
delegates events runnable verifiedRuns `test` → 42
// 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
delegates events runnable verifiedRuns `test` → 3
// 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
}Runs `test` → 10
// 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, int>) -> int = f(x)
func test() -> int = apply(5, dbl)ILEmitterTests_Delegates__MethodGroup_BindsRealMethod_NotAForwarder
delegates events unknown verifiedCompiles
// 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<int, int> = dblILEmitterTests_Delegates__MethodGroup_ToExternalNamedDelegate_Bridges
delegates events runnable verifiedRuns `test` → true
// 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<int> = is_even
return p(4)
}Runs `test` → 42
// 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<int, int> = dbl
return f(21)
}Compiles
// 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
}Compiles
// 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<int>
pub func wire(h: Action<int>) {
self.OnChanged += h
}
pub func unwire(h: Action<int>) {
self.OnChanged -= h
}
pub func add(n: int) {
self.total = self.total + n
raise OnChanged(self.total)
}
}ILEmitterTests_Events__Event_Interface_EmitsAbstractAccessorsAndEventDef
delegates events unknown verifiedCompiles
// 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
}Compiles
// 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<int>
pub event OnB: Action<int>
pub func fireA(v: int) { raise OnA(v) }
pub func fireB(v: int) { raise OnB(v) }
}Compiles
// 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<int>
pub func add(n: int) {
self.total = self.total + n
raise OnChanged(self.total)
}
}Compiles
// 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
delegates events unknown verifiedCompiles
// 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<int>
}Compiles
// 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<int>
pub func ping(v: int) { raise OnPing(v) }
}Runs `test` → 42
// 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)
}Runs `test` → 42
// 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)Runs `test` → 42
// 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)
}Runs `test` → 25
// 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)
}Runs `test` → 10
// 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)
}Runs `test` → 42
// 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)
}Runs `test` → 42
// 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)Runs `test` → 37
// 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)Compiles
// 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)
}Compiles
// 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
}Compiles
// 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
}