Skip to content

delegates events — examples

← all topics · 33 examples · page 1 of 1 · raw source ↓

delegates_and_pointers

delegates events authored verified

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
}

events

delegates events authored verified

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
}

Runs `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)

Compiles

// 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

Compiles

// 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

Runs `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)
}

Runs `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)
}

Runs `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)

Compiles

// 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> = dbl

Runs `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)
    }
}

Compiles

// 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) }
}

ILEmitterTests_Events__Event_Raise_InvokesSubscribers

delegates events unknown verified

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()
    }
}

Compiles

// 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>
}

ILEmitterTests_Events__Event_Unsubscribe_StopsDelivery

delegates events unknown verified ×2

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) }
}

ILEmitterTests2__Field_With_Function_Pointer_Type_Pin

delegates events runnable verified

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)
}

ILEmitterTests2__Function_Literal_Inline_Argument

delegates events runnable verified

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)

ILEmitterTests2__Function_Literal_Passed_To_Function

delegates events runnable verified

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)
}

ILEmitterTests3__Arrow_Lambda_Single_Param

delegates events runnable verified

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)
}

ILEmitterTests3__Arrow_Lambda_Two_Params

delegates events runnable verified

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)
}

ILEmitterTests3__Data_Field_Function_Pointer_Pin

delegates events runnable verified

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)

ILEmitterTests3__Function_Pointer_Two_Args

delegates events runnable verified

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
}