Protocol library as alternative to refinements (Russell Leggett)

Dean Landolt dean at deanlandolt.com
Tue Oct 22 07:35:31 PDT 2013


First off, this whole concept is brilliant. Thanks for sharing, Russell.
Just a few comments inline...


On Tue, Oct 22, 2013 at 2:13 AM, Russell Leggett
<russell.leggett at gmail.com>wrote:

>
>> > I can see most of your examples involve the interaction between the
>> protocol method and a method supplied on the object itself... They
>> definitely complicate things... I guess I would say that I would have this
>> throw an error. ... Skipping foo on the object because its not a function
>> seems too magical.
>>
>> Skipping `foo` on the object because it is not a function is too magical
>> in my opinion too. Working out how instance methods work in this scenario
>> seems like quite the task to me. The step of putting the protocol _between_
>> the object and the prototype sounds pretty hard to get right in particular.
>> I don't like thinking of reading from the prototype (as in the case of
>> fetching a method) any differently from reading from the own object. After
>> all sharing functionality is at the very core of prototypical inheritance.
>>
>
> Yeah, I'm not exactly married to it, but I liked the idea of being able to
> override at the instance level, therefore giving own properties highest
> priority.
>


I think the idea of overriding at the instance level is appealing too, but
doesn't dispatching on a string key open the door to the kinds of naming
conflicts the concept so elegantly solves otherwise? One possible solution
might be for the protocol to also expose a symbol for each method that
could be used to override at the instance level.

I'd go further and suggest that it should walk the prototype too, since
adding a specific symbol from a protocol would be a very intentional
action. This might be a bit of a perf burden in naive implementations but
it seems like the right thing -- there's something a little off about
intervening between instance and prototype lookup. The whole point of the
prototype is that it's a default logic -- attempting to short circuit this
just smells wrong.


>> >> ---- Case 3:
>> > Ah, yes, I had thought about this a bit, but it had never made it into
>> my gist at all. Let me revise my algorithm:
>> > 4. true - use Bar.foo
>>
>> This makes some sense. About scope resolution more generally I just want
>> to make a note that in C# extension methods, the extension method is always
>> the _last_ candidate. It would check anywhere in the inheritance chain
>> _before_ attempting to evaluate the extension method. For example:
>>
>>    ```
>>     public class Bar
>>     {
>>         public int GetFive() { return 5;}
>>     }
>>     public class Foo : Bar{}
>>
>>     public static class FooExt
>>     {
>>         static int GetFive(this Foo bar)
>>         {
>>             return 5555;
>>         }
>>         static string ToString(this Foo bar)
>>         {
>>             return "Hi";
>>         }
>>     }
>>      static void Main(string[] args)
>>         {
>>             Console.WriteLine((new Foo()).GetFive()); // this prints 5
>>             Console.WriteLine(new Foo())); // Uses the implementation of
>> Object.ToString .
>>         }
>>     ```
>>
>> This is a major difference between this proposal and C# extension
>> methods. However, I'm not sure it's bad. Would you mind making an argumnt
>> for prioritizing the protocol method over an object method?
>>
>
> Well I would start by pointing out that the two really are different
> mechanisms with different strengths and weaknesses. Protocols are more than
> a means of extension - they are also polymorphic and can really take
> advantage of the equivalent of interfaces across data types in addition to
> their extension. In a way, they are more similar to Haskell typeclasses
> than extension methods. There is also the obvious difference that protocols
> can be efficiently implemented in a dynamic language where extension
> methods cannot :)
>
> So anyway, the reason why prioritizing protocols is because there is
> potential value in the protocol itself. The protocol *is* an interface - a
> contract which can be polymorphic over different types. The same way that
> two protocols can have methods with the same name but different semantics,
> it would make sense that a protocol could be defined, and need to be
> applied to a type that already has the method. There is value for the
> protocol version to override the type's built in version. Because there is
> no ambiguity in the intent of using the protocol instead of the prototype,
> I think protocol should win. C# uses uniform syntax so the intent cannot be
> known if the extension method was intended vs the type's method. Even
> interfaces in the Java/C# worlds can't handle that type of clashing. If two
> interfaces have methods with the same name and signature, you can only have
> a single implementation. In those languages it is rarely a problem because
> of the ability for overloading, but with JavaScript its just one name, one
> method.
>
> I'm not opposed to simplifying the algorithm, and perhaps protocol methods
> should always take a backseat similar to C#, but that just doesn't seem
> right to me. If I create a protocol with a map method and I define it for
> Array, I would expect that to take priority, no? You're directly calling
> arr::map not arr.map - maybe its a ParallelCollection protocol and you want
> to override map to be parallel with web workers or something.
>


I agree that arr.map is questionable for protocol walking, but it's just as
questionable on the instance because of possible name conflicts!

If override used symbols, on the other hand, something like
`arr[myProtocol.symbols.map]` makes it clear the intent was to override
`arr::map` (assuming `map` is derived from `myProtocol` in this scope,
obviously). This also seems to beg for a prototype walk for
`myProtocol.symbols.map`, finally falling back on the default
implementation given for the protocol.

This bridges the FP and OOP worlds beautifully -- it's a clean and pleasant
syntax for intensional semantics.
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mail.mozilla.org/pipermail/es-discuss/attachments/20131022/9d38fa97/attachment-0001.html>


More information about the es-discuss mailing list