On Mon, Apr 16, 2012 at 4:33 AM, William ML Leslie <
[email protected]> wrote:

> If the issue was simply that some set of typeclass instances should
> always be specialised for ahead of time, it would not be prohibitive
> to create that list and create that specialisation.


The issue is that we'd *like* to do this, but combinatoric concerns may
make it prohibitive. With luck, my example concerning expansion of
illustrative_add() will put this in sharp relief. If it does not,
*please* re-raise
the question!


> There has been mention that 'typeclass instances should be determined
> lexically', and it has been considered obvious what this means.  Yet I
> can interpret this two ways:  Either [0] the instance must be lexically
> visible at the use of the typeclass method, or [1] the instance is
> determined when an expression of some type is cast to an instance of
> the typeclass.  If you had chosen the 'instance pointer' style, it
> would be at this cast where the instance pointer is bound.
>

I'm not sure what you mean by "cast" here. Do you perhaps mean
"instantiate"?  In any case, I attempted to specify the point of required
visibility in my note here:

   http://www.bitc-lang.org/pipermail/bitc-dev/2012-April/003405.html

"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."

Which is to say: at the first point where we would know enough to choose
the concrete instance. This generally happens on the *caller* side of the
interface, which is where you want it to happen.


> The algorithm that bitc now goes through to specialise functions with
> parametric arguments becomes slightly more complicated, because we
> aren't just looking for function f specialised for Arith(int32), we are
> looking for function f specialised for the instance of Arith(int32)
> that our parameter has been bound to, which introduces the question of
> identifying instances, and if it is possible to coalesce equivalent
> instance definitions.
>

Yes. That is *exactly* the problem. What it mainly means is that incoherent
instances are still a bad idea. They are nonetheless a *survivable* idea.

To some degree, I have intentionally limited the problem for ground types
by virtue of four rules:

   1. Instances for ground operators over ground types are defined in the
   preamble.
   2. Preamble modules are both imported **and opened** in every
   compilation unit.
   3. An earlier instance may not be shadowed by a later instance that is
   an exact match
   4. The instance selection criteria is "closest match, disambiguated by
   lexical order".

These rules combine to ensure that you can't redefine arithmetic over
int32, even though you can define arithmetic over new types.

An alternative is "well, you can't have that instance, here's one I
> prepared earlier", aka [0] consistently, which still seems like
> ambient authority to me.


I share your discomfort at this, but I don't think it is really an ambient
authority. Ground truth is that the CPU implements some things in hardware,
and that those things have "preferred" implementations. Nothing stops you
from implementing new operators over a different type class and using them.

So what I think we've really done here is to lock down a portion of the
operator namespace for certain types.


> And a linker that can do inlining is basically
> useless for ground operators if it can't (re)do register allocation or
> specialise on region for fairly complex pragmatic reasons.
>

Yes. But the hope is that my sneaky four rules (above) are enough to let us
do those optimizations.


> Have I, as usual, completely missed the point?
>

Aside from the understandable confusion about instance resolution context,
I think you have captured the point very well.



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

Reply via email to