On Tue, Jul 30, 2013 at 1:44 PM, David Jeske <[email protected]> wrote:

> I want to recap to be sure I understand the space-of-possibilities
> correctly...
>
> (1) If ordR is lexically/statically scoped in sortR we have no issue (it's
> not polymorphic in ordR).
>

I don't think this is right. First, I'm not sure what you mean by
lexically/statically scoped. The whole problem in this discussion is
orphaned instances, which are neither. Second, ordR may be parametric (e.g.
in the case of overlapping instances).

I *think* what you are saying is that if ordR is resolved following the
"cTrait or cR or prologue" rule, then we have no problem, because either
(a) both sides of the interface share all relevant assumptions, or (b) both
sides can see at static compile time that a collision occurred, and static
compilation fails.

If that's what you mean, then I agree there is no problem in this case.


> (2) If ordR is an explicit parameter we have no issue
>

We have no issue concerning *meaning* or *typing*. We have a potentially
overwhelming *pragmatics* issue concerning an explosion in the number of
dictionaries that may need to be passed. This is why, in general, I think
that instantiation should occur by partial evaluation, and that instances
have to be consistently treated as scalars. In particular, it's OK to bind
an instance locally for convenience:

   let localName = Ord 'a in
     ...body...

but /localName/ here is an alias for a *scalar, *or alternatively an alias
for a type*.* In particular, it is not assignable. This preserves the
guarantee that partial evaluation can be used.


> (3) If ordR is a dynamic import of the sortR containing module, we have a
> run-time bind collision issue when two consumers of sortR wish to use
> different bindings for ordR.
>

I don't understand how dynamic import is a factor here. If you have a
dynamic import, then you have a module signature for the imported module
and you have a set of version checks in force across the modules. The end
result is that all of the checks can be accomplished at static compile
time. You do *not* have a binding collision at run time, because the choice
of binding in sortR isn't *up* to the caller. It is prescribed by the sortR
signature.

It is *imperative* that all failures deriving from collisions occur
statically. The module signatures ensure that.


> (4) If ordR is bound to the instance, we have either a run-time bind
> collision issue (if we allow binding ordR onto an existing type) or a
> flexibility issue (if we don't allow binding ordR onto an existing type).
>

I'm not sure what this means, but it is *imperative* that all failures
deriving from collisions occur statically.


> (QQ) My first thought appears to be the way Scala handles type-classes (if
> I understand their system correctly from just reading about it). That is,
> the use of a type-class creates an implicit parameter to the function. This
> causes the selection of ordR to be lexically scoped in the *caller*.
>

First, as I've mentioned elsewhere, this simply doesn't work
(pragmatically) when unboxed types are admitted into the language. Second,
this induces a requirement for whole-program compilation in order to inline
the instances.

Dear God, man. Adopting the Scala approach requires that all uses of int32
addition be done by indirect lookup!



> (RR) My second thought was to do the same thing, but by way of an implicit
> *type* parameter instead of an implicit function parameter. A function
> using an type-class ordR would be implicitly declaring itself parametric in
> R-with-ordR-specializtion. The caller would have to provide such a type at
> bind-time, causing a specialization of sortR to be generated based on this
> type.
>

So really, this all goes back to my earlier statement about why eager
binding of instances is vital in order to achieve any sort of efficient
compilation.


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

Reply via email to