// E# — a verified example from the E# language corpus (CLR language; .es, not ECMAScript). // provenance: interfaces_and_static.es topic: static-func status: verified // hand-authored, idiomatic E# — verified through the E# compiler namespace Demo // ═════════════════════════════════════════════════════════════════════════════ // E#'s object side: interfaces, the two kinds of type that satisfy them, methods that // live inside a `ref data` body, and a `static func` static class. // // An `interface` is nominal: a type satisfies it only by NAMING it after `:` — there is // no structural auto-matching. Both kinds of user type can conform: // // • a value `data` conforms by PROMOTION — a free `func` whose first parameter is the // data type becomes the interface method. (Storing a value type behind an interface // boxes it; the compiler warns. Use `ref data` when you'll pass it as the interface a // lot.) // • a `ref data` conforms with methods written INSIDE its body (they get an implicit // `self`), and constructs via an `init` block. // // A `static func Name { ... }` is a static class: a bag of constants and stateless // functions, called `Name.member(...)`. // ═════════════════════════════════════════════════════════════════════════════ // The contract. By .NET convention interface names start with `I`. interface IArea { func area() -> int } // A value `data` conforming via promotion. `func area(r: Rect)` has `Rect` as its first // parameter, so it IS `Rect.area()` — and that satisfies `IArea`. (Passing a `Rect` where // an `IArea` is expected boxes the struct; fine here, the compiler just notes it.) data Rect : IArea { w: int h: int } func area(r: Rect) -> int { return r.w * r.h } // A `ref data` conforming with an in-body method. It has identity, an `init` constructor, // and `self` inside its methods. ref data Disk : IArea { radius: int init(r: int) { self.radius = r } // Methods inside a `ref data` body read/write fields through `self`. This one // satisfies `IArea.area()`. (Rough integer area, π ≈ 3.) func area() -> int { return 3 * self.radius * self.radius } } // Dispatch through the interface: `describe` neither knows nor cares whether it holds a // `Rect` or a `Disk` — it calls `area()` virtually. This is the one place E# reaches for // the object world on purpose. func describe(s: IArea) -> int { return s.area() } // A `static func` static class: constants + stateless helpers, reached as `Geo.member`. static func Geo { const UNIT = 1 func unitSquare() -> Rect { return Rect { w: UNIT, h: UNIT } } func biggest(a: int, b: int) -> int { return a > b ? a : b } } func main() -> int { let r = Rect { w: 3, h: 4 } // value type let d = Disk(5) // ref data via init let viaInterface = describe(r) + describe(d) // 12 + 75 = 87 (both as IArea) let unit = Geo.unitSquare().area() // 1 (static class → promoted method) let pick = Geo.biggest(viaInterface, 100) // 100 return viaInterface + unit + pick // 87 + 1 + 100 = 188 }