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
