Skip to content

Instantly share code, notes, and snippets.

@namandixit
Last active October 8, 2024 03:42
Show Gist options
  • Save namandixit/938ef347a695dc02f5d04eea9e021239 to your computer and use it in GitHub Desktop.
Save namandixit/938ef347a695dc02f5d04eea9e021239 to your computer and use it in GitHub Desktop.
Sample statically-typed prototype-based OOP

Statically typed prototype-based OOP

I did not come up with this. I found this in a Pastebin linked from a Hacker News comment, and I was never able to find either the comment or the paste ever again. Thus, I am unable to credit whoever did come up with it. If someone knows the source, please let me know.

# object "ex nihilo"
var a = object {
    x: 7,
    f: func (unused) -> 99
}

# typeof a: {x as int; f as int -> int}
a.x = 1
a.f = func(y) -> this.x + y

# type is still the same!
a.f(5) # => 6

# constructor, only that the members are given all in one place
func B(s as string) {
    s = s.uppercase()
    return object {
        a: a,
        s: s,
        g: func () -> this.s + string(this.a.x)
    }
}

# typeof B: string -> {a as {x as int, g as int -> int}, z as string, g as () -> string }
B("foo").g() # => "foo1"

# inheritance, objects returned by C have a as prototype and can access its members
func C() {
    return object <: a {
        h: func (z) -> this.f(z) + 1
    }
}

# typeof C: {f as int -> int} -> {f as int -> int, h as int -> int}
# again, replacing a member (even shadowing an inherited one) doesn't need to change the type!
c = C()
c.f = func (unused) -> -1
C(a).h(1) # => 0
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment