On Fri, Jul 26, 2013 at 12:56 PM, David Jeske <[email protected]> wrote:
> On Fri, Jul 26, 2013 at 12:15 PM, Jonathan S. Shapiro <[email protected]>wrote: > >> > The use case for non-lexically-scoped resolution is the one where we have >> A.Trait, B.Type, and C.TraitInstance developed by non-cooperating >> developers in different organizations. I gave an example of a novel stream >> trait in an earlier email. >> > > I see. I couldn't find the stream example, but I can imagine it. > The example was: Developer A provides NovelStream in crate cA. Unrelated developer provides UsefulType in crate cB. You, poor sod, want to serialize an instance of UsefulType to a NovelStream, so you're stuck providing the trait implementation as an orphan in your own crate. > My personal term for this is "bottom-up code reuse". That is, repurposing > a module by handing it a different set of "bottom level" bindings/operators > to talk to. > I don't think that's what is happening here. The bindings in use in the respective crates cA, cB aren't changing at all. All that is happening is the establishment of bindings in *your *crate cYourCrate. Nothing is being overridden here. > > The alternative to non-lexically-scoped resolution in this situation is to >> require all instances to be bound at module import. That's essentially how >> ML solves this, and Bob Harper has pointed out that it's expressively >> equivalent to type classes. It's just not very attractive. >> > > This sounds the same as lexical scoping and dynamic binding (aka > DLL/SO)... and the way C solves this. Any C function is lexically scoped > in, but at run-time link you can override any particular (non-inlined) > functional binding. The same is true in .NET/JVM, if by no other means than > just supplying an alternative implementation of the bound DLL. > That's a completely different thing - not what's happening here at all. The alternative I'm citing requires first-class modules. If a module has an orphaned instance requirement, that orphaned instance has to be presented as an instantiating argument at the point of module import. Annnnnnd... it just doesn't work, and I'm running out the door, so I'll have to explain why later. What makes [instantiating module import] unattractive? It this a > granularity issue? Convenience? > Mutability. It's a fairly foundational assumption that modules get instantiated only once. If they instantiate multiple times, then parametricity needs to work so that the overlapping globals don't collide. The instant you have a mutable global in that module, you get hit with the monomorphism rule, and multiple instantiation of the module utterly ceases to work. > As far as I can see, the suggestion ( sortR :: Ord R = > OrphanedInstanceForR => R[] -> R[] ), is effectively trying to admit a more > granular per-function module import dependency, as opposed to a per-module > import module dependency. However, different parts of the module with sortR > may depend on it using the same OrdR, which means it's safer to remind the > OrdR import at the module/assembly level --- unless we have a safe way to > identify that cross-dependency. > It's not a module dependency. Your (client side) resolution of Ord R only matters if you actually call sortR. If we escalate this to a module dependency, it would become a precondition for well-typed module import. shap
_______________________________________________ bitc-dev mailing list [email protected] http://www.coyotos.org/mailman/listinfo/bitc-dev
