mlhaufe/brevity

Multimethods

Opened this issue · 6 comments

References:

Pattern could be leveraged, but how would this work with the trait declaration?

Perhaps the camelCase naming convention would work?

This feature does raise an interesting question: Is Brevity becoming a Relational DSL?

Instead of complected = data + traits, it would be data + multimethods. Starting to rhyme with Julia?

What of encapsulation and open-recursion? Slate may be more useful here, but Slate relies on mutable prototypes...

Note that Haskell can't do this.

Gilad is not a fan (because of runtime cost?):
https://gbracha.blogspot.com/2009/09/systemic-overload.html

Interesting comments on LtU:

Multiple Dispatch in Practice

There is some agreement with my thoughts that Pattern could be leveraged here. If this could be made modular (tied to an Algebra), then maybe that's the trick. Use the Dylan algorithm and merge with my pattern matching form

Is there such a thing as a super call in multimethods? Whose super?

Open-Recursion support seems to make this feature explode in possible callers when spread across a code-base.

Do Multimethods in general violate the Open-Closed Principle?

Is there such a thing as a super call in multimethods? Whose super?

With multimethods associated with the family, super would be the family parent

Here's my thoughts on the new form:

const Shape = family((Shape) => ({
    Circle: { r: Number },
    Square: { side: Number },

    collides: [
        { s1: Shape, s2: Shape, $(o) { },
        { s1: Shape, s2: Shape.Circle, $({ s1, s2 }) { } },
        { s1: Shape.Circle, s2: Shape.Square, $({ s1: c, s2: s }) { } }
    ]
}))

const Peano = family((Peano) => ({
    Zero: {},
    Succ: { pred: Peano },

    isZero: [
        { pred: Peano.Zero, $() { return true } },
        { pred: Peano.Succ, $() { return false } }
    ]
}))

const List = family((List, T) => ({
    Nil: {},
    Cons: {head: T, tail: List(T) },

    length: [
        {xs: List.Nil, $(){ return 0 } },
        {xs: List.Cons, $({tail}){ return 1 + this.length(tail)} }
    ]
}))
const Shape = family((Shape) => ({
    Circle: { r: Number },
    Square: { side: Number },

    collides: [
        $({ s1: Shape, s2: Shape })(() => { throw new TypeError('Unhandled shapes') }),
        $({ s1: Shape.Circle, s2: Shape.Circle })(() => { }),
        $({ s1: Shape.Circle, s2: Shape.Square })(() => { }),
        $({ s1: Shape.Sqaure, s2: Shape.Circle })(() => { }),
        $({ s1: Shape.Square, s2: Shape.Square })(() => { }),
    ]
}))

I don't know how the multimethods would work with mult-sorted algebras:

// Multi-Sorted
const Stmt = family(IntBoolExp, (Self) => ({
    Var: {name: String}, // E
    Assign: {name: String, e /* E */}, // E

    Expr: {e /* E */}, // S
    Seq: {first /* S */, second /* S */} // S
}))