Protocol library as alternative to refinements (Russell Leggett)

Benjamin (Inglor) Gruenbaum inglor at gmail.com
Mon Oct 21 13:16:39 PDT 2013


Great, thanks for the clarifications. A few more scenarios:


----- Case 1:

I have an object O of type Foo. A protocol P.

 - O has the structure {x:5,foo:7};
 - The protocol implements `foo` but does not specifically for Foo (via
.defaults).

What happens? Does `P.foo` get invoked, or do we get an error because
`O.foo` is not a function?

---- Case 2:

I have an object O of type Foo, Foo.prototype = new Bar. A protocol P.

 - O has the structure {x:5,foo:7};
 - The protocol implements `foo` for Bar specifically (but not for Foo)

What happens?  (Similar to case above?)

---- Case 3:

I have an object O of type Foo, Foo.prototype = new Bar. A protocol P.

 - O has the structure {x:5,y:7};
 - Bar has a method foo
 - The protocol implements `foo` for Bar specifically (but not for Foo)

What happens? Does it invoke Bar.foo or P.foo?

---- Case 4:

I have an object O of type Foo, Foo.prototype = new Bar. A protocol P.

 - O has the structure {x:5,y:7};
 - Bar has a method foo
 - The protocol implements `foo` for Bar specifically (but not for Foo)

What happens? Does it invoke Bar.foo or P.foo ?

---- Case 5:

I have an object O of type Foo, I import two `Protocol`s that implement a
method `Foo` at the same specificity level - what happens?

Thanks



On Mon, Oct 21, 2013 at 10:35 PM, Russell Leggett <russell.leggett at gmail.com
> wrote:

> On Mon, Oct 21, 2013 at 3:17 PM, Benjamin (Inglor) Gruenbaum <
> inglor at gmail.com> wrote:
>
>> Russell Leggett <russell.leggett at gmail.com> wrote:
>> > https://gist.github.com/genericallyloud/7086380
>>
>> Very interesting.
>>
>> >  // 4. use the default if available
>>
>> what's "the default" in #4? The protocol's default? What's the behavior
>> if no matching method is found?
>>
>
> The default is something I go into in a little bit of detail further down:
>
>     Collections.defaults({
>         each(iterator, context){
>             if (this.length === +this.length) {
>               for (var i = 0, length = this.length; i < length; i++) {
>                 //notice we also get to use :: for a simple call replacement
>                 if (context::iterator(this[i], i, this) === breaker) return;
>               }
>             } else {
>               var keys = this.keys();
>               for (var i = 0, length = keys.length; i < length; i++) {
>                 if (context::iterator(this[keys[i]], this[i], this) === breaker) return;
>               }
>             }
>         },
>
> This is defining a sort of default implementation of the method for the
> protocol, meaning that other types do not have to implement it in their own
> type specific implementation of the protocol.
>
>
>> Also, can anyone explain why this solves the performance problem scoped
>> object extensions have? It still seems like it would have to check the
>> environment for protocols and then check the methods on all available
>> protocols and do type matching to the type of the method.
>>
>> `Collections.extend(Array)` seems awfully similar to an array extensions,
>> how does the `::` operator resolve the need for expensive lookup, can you
>> explain that to me?
>>
>
> Yes, the reason is because no new scopes or environments have been
> created. The protocol and its methods are simply variables - objects like
> anything else. Getting a protocol's method is not really any different from:
>
> import {map} from 'UnderscOOre';
> //basically the same as
> let {map} = Array.prototype;
>
> //this is effectively the same whether you got it from the protocol or the function
> //pulled off of Array.prototype
> arr::map( x => x+2);
>
> The magic is what happens one of these protocol methods. The simplest to
> understand/naive approach to this would basically be that inside of a
> protocol, for each protocol method, you hold all the methods in a map going
> from type to implementation. The actual method used would inspect the
> |this| and follow the algorithm and use the maps to figure out which
> implementation to use. This would have a penalty - but it would be limited
> to the protocol method calls. Scoped extension would apply a penalty to
> *all* function calls everywhere. If protocols were natively supported, or
> at least some kind of hook for single dispatch on type, I'm pretty sure you
> could get function calls that were *at least* as fast as normal prototype
> based methods. Even if you didn't get native support, I have a feeling that
> something more clever than the naive approach could be used to hit the
> sweet spot and get some polymorphic inline caching, but maybe not.
>
> - Russ
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mail.mozilla.org/pipermail/es-discuss/attachments/20131021/d85751e5/attachment.html>


More information about the es-discuss mailing list