Skip to content

pointers — examples

← all topics · 135 examples · page 3 of 3 · raw source ↓

Runs `go` → 100

// E# — a verified example from the E# language corpus (CLR language; .es, not ECMAScript).
// provenance: ILEmitterTests_PointerModel.cs::EscapingAddressOfLocal_TwoAliasesShareCell   topic: pointers   status: verified
// verified behavior: Test.go(...) == 100

namespace Test

data P {
    var x: int
}

ref data Pair {
    a: *P
    b: *P
}

func go() -> int {
    var local = P { x: 1 }
    var pr = Pair()
    pr.a = &local
    pr.b = &local
    local.x = 50
    return pr.a.x + pr.b.x
}

Runs `go` → 22

// E# — a verified example from the E# language corpus (CLR language; .es, not ECMAScript).
// provenance: ILEmitterTests_PointerModel.cs::MixedReceivers_Downgraded_Alias   topic: pointers   status: verified
// verified behavior: Test.go(...) == 22

namespace Test

data Reg {
    var hi: int
    var lo: int
}

func raise(r: *Reg, by: int) {
    r.hi += by
}

func total(r: Reg) -> int {
    return r.hi + r.lo
}

func go() -> int {
    var r = Reg { hi: 10, lo: 5 }
    raise(&r, 7)
    return r.total()
}

Runs `go` → 106

// E# — a verified example from the E# language corpus (CLR language; .es, not ECMAScript).
// provenance: ILEmitterTests_PointerModel.cs::NullCompared_Param_ForcesWrapper   topic: pointers   status: verified
// verified behavior: Test.go(...) == 106

namespace Test

data Box {
    var v: int
}

func valueOr(b: *Box, fallback: int) -> int {
    if b == nil {
        return fallback
    }
    return b.v
}

func go() -> int {
    let present = new Box { v: 7 }
    let a = valueOr(present, 99)
    let nothing: *Box = nil
    let bb = valueOr(nothing, 99)
    return a + bb
}

Runs `go` → true

// E# — a verified example from the E# language corpus (CLR language; .es, not ECMAScript).
// provenance: ILEmitterTests_PointerModel.cs::PrimitivePointer_Field_IsNullableWrapper   topic: pointers   status: verified
// verified behavior: Test.go(...) == true

namespace Test

ref data Slot {
    p: *int
}

func go() -> bool {
    var s = Slot()
    return s.p == nil
}

Runs `go` → 7

// E# — a verified example from the E# language corpus (CLR language; .es, not ECMAScript).
// provenance: ILEmitterTests_PointerModel.cs::ReturnHoist_AddressOfLocal   topic: pointers   status: verified
// verified behavior: Test.go(...) == 7

namespace Test

data Node {
    value: int
    next: *Node
}

func makeNode(v: int) -> *Node {
    var n = Node { value: v, next: nil }
    return &n
}

func go() -> int {
    let p = makeNode(7)
    return p.value
}

Rejected at compile time: ES2003

// E# — a verified example from the E# language corpus (CLR language; .es, not ECMAScript).
// provenance: ILEmitterTests_PointerModel.cs::StarRefData_IsError   topic: pointers   status: verified
// verified behavior: reports diagnostic ES2003

namespace Test

ref data Session {
    id: int
}

func touch(s: *Session) {
    s.id = 1
}

Compiles

// E# — a verified example from the E# language corpus (CLR language; .es, not ECMAScript).
// provenance: ILEmitterTests_PtrListRepro.cs::ListCtor_WithHeapPointerData_Resolves   topic: pointers   status: verified
// compiles cleanly (no auto-run claim was extracted)

namespace Test

data Counter {
    var total: int
}

func bump(c: *Counter, n: int) {
    c.total += n
}

func go() -> int {
    var c: *Counter = new Counter { total: 0 }
    let xs = List<int>()
    xs.Add(5)
    xs.Add(10)
    for x in xs {
        bump(c, x)
    }
    return c.total
}

Compiles

// E# — a verified example from the E# language corpus (CLR language; .es, not ECMAScript).
// provenance: ILEmitterTests_PtrListRepro.cs::ListParamAndCtor_WithHeapPointerAlias_Resolves   topic: pointers   status: verified
// compiles cleanly (no auto-run claim was extracted)

namespace Test

data Counter {
    var total: int
    var steps: int
}

func bump(c: *Counter, amount: int) {
    c.total += amount
    c.steps += 1
}

func addAll(c: *Counter, xs: List<int>) -> void {
    for x in xs {
        bump(c, x)
    }
}

func go() -> int {
    var tally: *Counter = new Counter { total: 0, steps: 0 }
    let alias = tally
    let xs = List<int>()
    xs.Add(5)
    xs.Add(7)
    xs.Add(3)
    addAll(tally, xs)
    bump(alias, 100)
    return tally.total + tally.steps
}

Runs `test` → 2

// E# — a verified example from the E# language corpus (CLR language; .es, not ECMAScript).
// provenance: ILEmitterTests_Refs.cs::AddressOf_PassedToByRefParam_Works   topic: pointers   status: verified
// verified behavior: Test.test(...) == 2

namespace Test

func increment(x: *int) {
    x += 1
}

func test() -> int {
    var count = 0
    increment(&count)
    increment(&count)
    return count
}

Compiles

// E# — a verified example from the E# language corpus (CLR language; .es, not ECMAScript).
// provenance: ILEmitterTests_Refs.cs::OutParam_HasByRefAndOutAttribute   topic: pointers   status: verified
// compiles cleanly (no auto-run claim was extracted)

namespace Test

func emit(out value: int) {
    value = 7
}

Compiles

// E# — a verified example from the E# language corpus (CLR language; .es, not ECMAScript).
// provenance: ILEmitterTests_Refs.cs::OutParam_Int_WritesThrough   topic: pointers   status: verified
// compiles cleanly (no auto-run claim was extracted)

namespace Test

func try_inc(input: int, out result: int) -> bool {
    result = input + 1
    return true
}

Runs `label` → false

// E# — a verified example from the E# language corpus (CLR language; .es, not ECMAScript).
// provenance: ILEmitterTests_Refs.cs::OutParam_ReferenceType_WritesThrough   topic: pointers   status: verified
// verified behavior: Test.label(...) == false

namespace Test

func label(n: int, out text: string) -> bool {
    if n == 0 {
        text = "zero"
        return true
    }
    text = "other"
    return false
}

Runs `divide` → false

// E# — a verified example from the E# language corpus (CLR language; .es, not ECMAScript).
// provenance: ILEmitterTests_Refs.cs::OutParam_TryPattern_BothBranchesAssign   topic: pointers   status: verified
// verified behavior: Test.divide(...) == false

namespace Test

func divide(a: int, b: int, out q: int) -> bool {
    if b == 0 {
        q = 0
        return false
    }
    q = a / b
    return true
}

Runs `test` → 42

// E# — a verified example from the E# language corpus (CLR language; .es, not ECMAScript).
// provenance: ILEmitterTests_Refs.cs::ReadOnlyByRef_CanReadThrough   topic: pointers   status: verified
// verified behavior: Test.test(...) == 42

namespace Test

func readVal(x: readonly *int) -> int {
    return x
}

func test() -> int {
    var n = 42
    return readVal(&n)
}

Compiles

// E# — a verified example from the E# language corpus (CLR language; .es, not ECMAScript).
// provenance: ILEmitterTests_Refs.cs::ReadOnlyByRef_HasInAttribute   topic: pointers   status: verified
// compiles cleanly (no auto-run claim was extracted)

namespace Test

func readOnly(x: readonly *int) -> int {
    return x
}

Runs `test` → 50.0f

// E# — a verified example from the E# language corpus (CLR language; .es, not ECMAScript).
// provenance: ILEmitterTests_Refs.cs::ReadOnlyByRef_StructFieldAccess_Works   topic: pointers   status: verified
// verified behavior: Test.test(...) == 50.0f

namespace Test

data Rect {
    x: float
    y: float
    w: float
    h: float
}

func area(r: readonly *Rect) -> float {
    return r.w * r.h
}

func test() -> float {
    let r = Rect { x: 0.0, y: 0.0, w: 10.0, h: 5.0 }
    let result = area(&r)
    return result
}

Runs `test` → 3

// E# — a verified example from the E# language corpus (CLR language; .es, not ECMAScript).
// provenance: ILEmitterTests_Refs.cs::RefLocal_MultipleWrites_Accumulate   topic: pointers   status: verified
// verified behavior: Test.test(...) == 3

namespace Test

func test() -> int {
    var count = 0
    var p = &count
    p += 1
    p += 1
    p += 1
    return count
}

Runs `test` → 42

// E# — a verified example from the E# language corpus (CLR language; .es, not ECMAScript).
// provenance: ILEmitterTests_Refs.cs::RefLocal_ReadThroughPointer_Works   topic: pointers   status: verified
// verified behavior: Test.test(...) == 42

namespace Test

func test() -> int {
    var x = 42
    var p = &x
    return p
}

Runs `test` → 15

// E# — a verified example from the E# language corpus (CLR language; .es, not ECMAScript).
// provenance: ILEmitterTests_Refs.cs::RefLocal_WriteThroughPointer_MutatesOriginal   topic: pointers   status: verified
// verified behavior: Test.test(...) == 15

namespace Test

func test() -> int {
    var x = 10
    var p = &x
    p += 5
    return x
}

Runs `test` → 3

// E# — a verified example from the E# language corpus (CLR language; .es, not ECMAScript).
// provenance: ILEmitterTests2.cs::LinkedList_Length_Via_HeapPointer_Pin   topic: pointers   status: verified
// verified behavior: Test.test(...) == 3

namespace Test

data Node {
    value: int,
    next: *Node
}

func length(n: *Node) -> int {
    var count = 0
    var cursor = n
    while cursor != nil {
        count = count + 1
        cursor = cursor.next
    }
    return count
}

func test() -> int {
    let c = new Node { value: 3, next: nil }
    let b = new Node { value: 2, next: c }
    let a = new Node { value: 1, next: b }
    return length(a)
}

Runs `test` → true

// E# — a verified example from the E# language corpus (CLR language; .es, not ECMAScript).
// provenance: ILEmitterTests3.cs::HeapPointer_Nil_Comparison_True   topic: pointers   status: verified
// verified behavior: Test.test(...) == true

namespace Test

data Atom { n: int }

func test() -> bool {
    let a: *Atom = nil
    return a == nil
}

Runs `test` → false

// E# — a verified example from the E# language corpus (CLR language; .es, not ECMAScript).
// provenance: ILEmitterTests3.cs::HeapPointer_NonNil_Comparison_False   topic: pointers   status: verified
// verified behavior: Test.test(...) == false

namespace Test

data Atom { n: int }

func test() -> bool {
    let a: *Atom = new Atom { n: 1 }
    return a == nil
}

Runs `test` → 14

// E# — a verified example from the E# language corpus (CLR language; .es, not ECMAScript).
// provenance: ILEmitterTests3.cs::HeapPointer_To_Data_Carries_Value   topic: pointers   status: verified
// verified behavior: Test.test(...) == 14

namespace Test

data Atom { n: int }

func test() -> int {
    let a: *Atom = new Atom { n: 7 }
    return a.n + a.n
}

ILEmitterTests3__LinkedList_Sum_Pin

pointers runnable verified

Runs `test` → 6

// E# — a verified example from the E# language corpus (CLR language; .es, not ECMAScript).
// provenance: ILEmitterTests3.cs::LinkedList_Sum_Pin   topic: pointers   status: verified
// verified behavior: Test.test(...) == 6

namespace Test

data Node {
    value: int,
    next: *Node
}

func sum_list(head: *Node) -> int {
    var total = 0
    var cursor = head
    while cursor != nil {
        total = total + cursor.value
        cursor = cursor.next
    }
    return total
}

func test() -> int {
    let c = new Node { value: 3, next: nil }
    let b = new Node { value: 2, next: c }
    let a = new Node { value: 1, next: b }
    return sum_list(a)
}

Runs `test` → 11

// E# — a verified example from the E# language corpus (CLR language; .es, not ECMAScript).
// provenance: ILEmitterTests3.cs::Tree_Structure_Compiles_Pin   topic: pointers   status: verified
// verified behavior: Test.test(...) == 11

namespace Test

data Tree {
    value: int,
    left: *Tree,
    right: *Tree
}

func test() -> int {
    let leaf = new Tree { value: 1, left: nil, right: nil }
    let root = new Tree { value: 10, left: leaf, right: nil }
    return root.value + root.left.value
}

linked_list_and_tail

pointers authored verified

Showcase example

// E# — a verified example from the E# language corpus (CLR language; .es, not ECMAScript).
// provenance: linked_list_and_tail.es   topic: pointers   status: verified
// hand-authored, idiomatic E# — verified through the E# compiler

namespace Demo

// ═════════════════════════════════════════════════════════════════════════════
// Two flavors of recursion, and a thing E# does that C# can't.
//
//   1. Structural recursion over a heap-linked list. A value `data` can't contain itself
//      by value (that would be infinitely large — a hard error), so the `next` link is a
//      pointer, `*Node`. `new Node { ... }` allocates a node on the heap and yields a
//      `*Node`; `nil` ends the list.
//
//   2. Tail recursion. When a recursive call is the LAST thing a function does
//      (`return f(...)`), E# emits the CLR `tail.` prefix — the frame is REUSED, not
//      stacked — and GUARANTEES it, so an accumulator loop written as recursion runs in
//      constant stack however deep. (Roslyn emits `tail.` only opportunistically and gives
//      C# no language-level control or guarantee, so you can't rely on TCO there; E#, like
//      F#, makes it a guarantee.)
// ═════════════════════════════════════════════════════════════════════════════

// The self-reference is a pointer — `next: Node` would be ES2002 (infinite-size value).
data Node {
    value: int
    next: *Node
}

// Structural recursion: this node's value plus the sum of the rest. NOT a tail call (the
// addition happens after the recursive call returns) — and that's fine for a short list.
func sumList(n: *Node) -> int {
    if n == nil {
        return 0
    }
    return n.value + sumList(n.next)
}

// Tail recursion: the recursive call is in tail position, so it compiles to a guaranteed
// CLR tail call. At large `n` a non-TCO'd version risks a StackOverflow; here it's flat.
func sumTo(n: int, acc: int) -> int {
    if n <= 0 {
        return acc
    }
    return sumTo(n - 1, acc + n)
}

func main() -> int {
    // Build 1 -> 2 -> 3 on the heap, tail first so each node can point at the next.
    let third  = new Node { value: 3, next: nil }
    let second = new Node { value: 2, next: third }
    let first  = new Node { value: 1, next: second }

    return sumList(first) + sumTo(100, 0)   // 6 + 5050 = 5056
}

pointers_and_sharing

pointers authored verified

Showcase example

// E# — a verified example from the E# language corpus (CLR language; .es, not ECMAScript).
// provenance: pointers_and_sharing.es   topic: pointers   status: verified
// hand-authored, idiomatic E# — verified through the E# compiler

namespace Demo

// ═════════════════════════════════════════════════════════════════════════════
// Value vs. shared — the heart of E#'s memory model, and what `new` is for.
//
// A `data` type is a VALUE, like an int. Assigning it COPIES; two variables holding a
// `data` never affect each other. That is the default, and it is usually what you
// want — no spooky action at a distance.
//
// Sometimes you need the opposite: several places that read and write ONE shared
// piece of state (a counter threaded through a computation, a node in a linked
// structure). For that you put the `data` on the heap with `new`, which yields a
// POINTER, written `*T`. Everyone holding the `*T` sees the same mutations.
//
//   `new Counter { ... }`   →   allocate on the heap, hand back a `*Counter`
//   `c: *Counter`           →   a pointer; `c.total` reads/writes the shared cell
//   `let alias = c`         →   copies the POINTER, not the counter — same object
//
// `new` is exactly "put this value on the heap and give me a pointer to it". It is
// the one allocation expression in the language and the only way to mint a fresh `*T`.
// ═════════════════════════════════════════════════════════════════════════════

// A plain value `data`: a running tally. No `init` block — value types are built with
// a composite literal that names each field (`Counter { total: 0, steps: 0 }`).
data Counter {
    var total: int
    var steps: int
}

// `bump` takes a POINTER (`*Counter`), so it mutates the caller's counter in place.
// A pointer parameter stays a free function (only a direct-value receiver like
// `func f(c: Counter)` would become the method `c.f()`).
func bump(c: *Counter, amount: int) {
    c.total += amount
    c.steps += 1
}

// Had this taken a value `Counter` instead of `*Counter`, `add` would receive its own
// COPY and the caller would never see the change. The pointer is what makes the
// sharing real.
// Optional: You can annotate return type as void if you prefer visibility.
func addAll(c: *Counter, xs: List<int>) -> void {
    for x in xs {
        bump(c, x)
    }
}

func main() -> int {
    // `new` allocates the counter on the heap and returns a *Counter. `tally` and
    // `alias` are then two NAMES for the SAME heap counter.
    var tally: *Counter = new Counter { total: 0, steps: 0 }
    let alias = tally

    let xs = List<int>()
    xs.Add(5)
    xs.Add(7)
    xs.Add(3)

    addAll(tally, xs)      // through the pointer: total = 15, steps = 3
    bump(alias, 100)       // through the OTHER name — same object: total = 115, steps = 4

    // The writes via `alias` are visible through `tally` — both point at one heap cell.
    // Read the shared fields back through the pointer (auto-deref): total = 115, steps = 4.
    return tally.total + tally.steps    // 119
}

Compiles

// E# — a verified example from the E# language corpus (CLR language; .es, not ECMAScript).
// provenance: TranspilerTests.cs::Transpiles_ByRef_Parameters   topic: pointers   status: verified
// compiles cleanly (no auto-run claim was extracted)

namespace Counter

pub data Counter {
    value: int
}

pub func increment(c: *Counter) {
    c.value += 1
}

Compiles

// E# — a verified example from the E# language corpus (CLR language; .es, not ECMAScript).
// provenance: ILEmitterTests_HeapPointer.cs::HeapPointer_AssignT_ToStarT_WithoutAmpersand_Error   topic: pointers   status: unverified
// compiles cleanly (no auto-run claim was extracted)

namespace Test

data Vec2 {
    var x: int
    var y: int
}

ref data Holder {
    pt: *Vec2
}

func test() {
    var h = Holder()
    h.pt = Vec2 { x: 1, y: 2 }
}

Runs `go` → 4

// E# — a verified example from the E# language corpus (CLR language; .es, not ECMAScript).
// provenance: ILEmitterTests_PointerCollections.cs::GenericFirst_OverPointerList   topic: pointers   status: unverified
// verified behavior: Test.go(...) == 4

namespace Test
data Box { n: int }
func first<T>(xs: List<T>) -> T { return xs[0] }
func go() -> int {
    var xs = List<*Box>()
    xs.Add(new Box { n: 4 })
    let b = first<*Box>(xs)
    return b.n
}

Runs `go` → 4

// E# — a verified example from the E# language corpus (CLR language; .es, not ECMAScript).
// provenance: ILEmitterTests_PointerCollections.cs::GenericFirst_PointerInferred   topic: pointers   status: unverified
// verified behavior: Test.go(...) == 4

namespace Test
data Box { n: int }
func first<T>(xs: List<T>) -> T = xs[0]
func go() -> int {
    var xs = List<*Box>()
    xs.Add(new Box { n: 4 })
    let b = first(xs)
    return b.n
}

Runs `go` → 13

// E# — a verified example from the E# language corpus (CLR language; .es, not ECMAScript).
// provenance: ILEmitterTests_PointerCollections.cs::GenericIdentity_OnPointer   topic: pointers   status: unverified
// verified behavior: Test.go(...) == 13

namespace Test
data Box { n: int }
func identity<T>(v: T) -> T { return v }
func go() -> int {
    let b = identity(new Box { n: 13 })
    return b.n
}

Runs `go` → 50

// E# — a verified example from the E# language corpus (CLR language; .es, not ECMAScript).
// provenance: ILEmitterTests_PtrEmbedIface.cs::PointerEmbed_BumpMutatesThroughPointer   topic: pointers   status: unverified
// verified behavior: Test.go(...) == 50

func go() -> int {
  var o: *Outer = new Outer { Inner: new Inner { n: 48 }, label: "x" }
  o.bump()
  o.bump()
  return o.value()
}

Runs `go` → 45

// E# — a verified example from the E# language corpus (CLR language; .es, not ECMAScript).
// provenance: ILEmitterTests_PtrEmbedIface.cs::PointerEmbed_PromotedDirectAccess   topic: pointers   status: unverified
// verified behavior: Test.go(...) == 45

func go() -> int {
  var o: *Outer = new Outer { Inner: new Inner { n: 45 }, label: "x" }
  return o.value()
}

Runs `use_declared` → 100

// E# — a verified example from the E# language corpus (CLR language; .es, not ECMAScript).
// provenance: ILEmitterTests_Refs.cs::OutParam_EsharpCallSite_PassesByRef   topic: pointers   status: unverified
// verified behavior: Test.use_declared(...) == 100

namespace Test

func try_inc(input: int, out result: int) -> bool {
    result = input + 1
    return true
}

func use_existing() -> int {
    var n = 0
    try_inc(41, out n)
    return n
}

func use_declared() -> int {
    if try_inc(99, out var m) {
        return m
    }
    return -1
}