Here is Rust's solution to the coherence problem:

https://mail.mozilla.org/pipermail/rust-dev/2011-December/001036.html

Based on a quick read, it looks like the second solution I initially
proposed, namely the instance is a "phantom type" of sorts included in
the constructed type, and so trying to use an incompatible instance
results in an type error.

Sandro

On 16/04/2012 12:25 AM, Jonathan S. Shapiro wrote:
> It won't surprise anyone here that I've spent a good bit of background
> cycles thinking about how the instance coherence problem might be
> solved. I want to lay out my thinking as best I can. I have not had a
> chance to read the various papers that have been recommended recently.
> It would not surprise me if this approach is similar to what is being
> done in other languages.
> 
> *Inlining - What is the Issue?*
> *
> *
> Let me start by clarifying an apparent confusion that I have created
> concerning inlining.
> 
> In BitC, Arith('a) is a type class that defines, among other things, the
> type class method +:'a x 'a -> 'a. Where 'a turns out to be int32, we
> rely on inlining to allow the compiler to notice that this is a case of
> hardware-supported addition. This is done as follows:
> 
>   * The specializer renders a + b:int32 as a procedure call;
>     approximately: +_int32_int32__int32(x, y).
>   * The preamble has marked +:int32 x int32 -> int32 as having an
>     external implementation.
>   * There is a header file that supplies this implementation as a/ C
>     macro/, with the effect that the primitive + operator is seen by the
>     C compiler.
> 
> This is obviously a C-specific implementation. The point is that the
> proper mechanism for deriving ground operators is to treat the operators
> as regular procedure calls and then inline the concrete implementations
> so as to expose the hardware operations. With this model, optimizations
> can be implemented entirely within the typed framework.
> 
> The requirement to do this is mainly that we be able to do early binding
> on ground operators at ground types. The main impediment to this in
> practice is the possibility that a late coherence failure may be discovered.
> 
> *JIT - What is the Issue?*
> *
> *
> There is no issue in my mind with JIT. The issue is that any JIT system
> brings in a large and complicated pile of runtime code. I would
> therefore prefer that code generation be possible in controlled AOT
> form. In particular, I'd /really/ like to see us implement the JIT
> system this way!
> 
> 
> *Instance Coherence*
> *
> *
> So on to the real subject of the note. The goal is to replace the
> requirement for instance coherence with a lesser requirement for
> instance selection determinism.
> 
> Objectives:
> 
>  1. Timing of binding should be continuous. It should be clearly
>     specified what constitutes sufficient information to make a durable
>     binding/selection decision for instances. By "durable", I mean
>     binding/selection decisions that will remain correct as more
>     information about the program becomes apparent. This means, in
>     particular, that the compiler must be able to know that early
>     binding/selection decisions are not hazarded by late discovery of
>     incoherent instances.
>  2. As Sandro (and others) have suggested, it should be possible to
>     explicitly specify cases where eager binding/selection (therefore
>     instantiation) should be applied.
>  3. In particular, early binding for ground types and ground operators
>     is imperative. It is clearly intolerable if we are unable to
>     implement int32 addition without an indirect procedure call.
>  4. Explicitly directed instantiation is acceptable.
> 
> Proposal:
> 
> The main problem is to switch from an ambient instance resolution
> process to a lexical instance resolution process. Once resolution is
> specified as lexically resolved in the usual way, the overwhelming
> majority of instance coherence issues simply go away.
> 
> In order for this to work, however, we must distinguish between
> /importing/, which makes the _name_ of an instance visible in the
> importing unit, and /opening/, which brings a named instance into the
> instance resolution contour. As part of this distinction, we will
> require that all instance definitions be named, mainly so that they can
> be opened by name.
> 
> An instance for a type class TC('a, 'b, ... 'z) is resolved in the
> resolution contour in which all of the type variables 'a ... 'z become
> concrete.
> 
> It is permitted to have overlapping, open instances in a single
> resolution contour. It is /not/ permitted to have two precisely matching
> instances in a single resolution contour. Ambiguous instance matches are
> resolved by adopting the /latest/ open instance in the resolution
> contour. Thus:
> 
>    instance TC('a, 'b) { ... }  // fine
>    instance TC('a, int) {...} // okay - /partially/ shadows previous
>    instance TC(char, char) {...} // okay - /partially shadows /previous
>    instance TC(char, char) {...} // error - /fully/ shadows previous
>    instance TC(int, 'a) {...} // okay - ambiguous at TC(int, int), but
> preferred as the later resolution
> 
> Note that because of the opening process, an instance declared in a
> distant module cannot impact the behavior of my module without my
> consent. The notable exception to this is instances declared and opened
> in the preamble, because all preamble imports are performed as opening
> imports.
> 
> Can anybody state a place where this approach fails to deal with
> instance coherence?
> 
> 
> Jonathan
> 
> 
> _______________________________________________
> bitc-dev mailing list
> [email protected]
> http://www.coyotos.org/mailman/listinfo/bitc-dev


_______________________________________________
bitc-dev mailing list
[email protected]
http://www.coyotos.org/mailman/listinfo/bitc-dev

Reply via email to