Brendan Eich (2014-01-13T05:21:24.000Z)
We're not abusing guard :: syntax, are you trying to get my goat? :-P

Andrea Giammarchi wrote:
> recap ...
>
> in class point3d
> ```javascript
>    function + (a :: point2d, b :: point3d) {
>         return point3d(a.x + b.x, a.y + b.y, b.z);
>     }
> ```
>
> in class point2d
> ```javascript
>    function + (a :: point2d, b :: point3d) {
>         return point2d(a.x + b.x, a.y + b.y); // ignore b.z
>         // or do something else with z
>     }
> ```
>
> which one would be the result and why? what if both defines a and b 
> arguments differently too ?

Those are distinct multimethods. One returns a point3d, one a point2d. 
Declaring both as you show (with the bogo-syntax changed to avoid 
guard-::) results in ambiguous method calls on instances: we get the 
left+ symbol's set from point2d.prototype, and the right+ symbol's set 
from point3d.prototype, for an expression of the form

   var presult = p2 + p3.

We interset the sets. The result is not a singleton, but a set with two 
functions. Since there's no return-type dispatch, or indeed any clue 
what type is wanted for presult, the call is ambiguous and an error is 
thrown.

This points out another benefit of putting multimethod pattern-based 
definitions in value class declarations: we can raise an early error 
when the second value class is processed.

/be
domenic at domenicdenicola.com (2014-01-17T23:46:09.890Z)
We're not abusing guard :: syntax, are you trying to get my goat? :-P

Andrea Giammarchi wrote:
> recap ...
>
> in class point3d
> ```javascript
>    function + (a :: point2d, b :: point3d) {
>         return point3d(a.x + b.x, a.y + b.y, b.z);
>     }
> ```
>
> in class point2d
> ```javascript
>    function + (a :: point2d, b :: point3d) {
>         return point2d(a.x + b.x, a.y + b.y); // ignore b.z
>         // or do something else with z
>     }
> ```
>
> which one would be the result and why? what if both defines a and b 
> arguments differently too ?

Those are distinct multimethods. One returns a point3d, one a point2d. 
Declaring both as you show (with the bogo-syntax changed to avoid 
guard-::) results in ambiguous method calls on instances: we get the 
left+ symbol's set from point2d.prototype, and the right+ symbol's set 
from point3d.prototype, for an expression of the form

    var presult = p2 + p3.

We interset the sets. The result is not a singleton, but a set with two 
functions. Since there's no return-type dispatch, or indeed any clue 
what type is wanted for presult, the call is ambiguous and an error is 
thrown.

This points out another benefit of putting multimethod pattern-based 
definitions in value class declarations: we can raise an early error 
when the second value class is processed.