Often, when following discussions on this list, I wonder if I've
grasped the fundamentals well enough to comment or ask questions.

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.  Wherever we would
see Arith('a), we would know that the Arith(int32) specialisation will
be included in the code, with the provided Arith(int32) instance (and
unless you really know what you are doing, that is sure to be the
instance defined in the prologue).  Of course, the standard set of
specialisations could be controlled on a per-module or
per-compilation-unit level, and could be overridden for specific uses
of the type class or its methods.

I take it that this isn't the problem at all; and that the problem is
how that would interact with the rest of the typeclass instances.

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.

My common sense (which is as heavily tainted by real experiences as
the next person) says that the second choice is the obvious one:
typeclass instances are determined where you say 'treat this thing as
its instance of this typeclass'.  This is obvious to me since, if you
define a parametric collection type with items that are Disposable and
Eq, you shouldn't have to have my item type lexically visible when you
compile your library.  Ie, [0] doesn't actually work, and certainly
not in the presence of separate compilation.

The issue that arises is that when typeclass instances are specialised
at (separate) compile time, the instance resolution algorithm is
necessarily closer to [0].  So, instance resolution is inconsistent.

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.

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

Have I, as usual, completely missed the point?

Your other point (about inheritance) is orthogonal, I guess.  I
figured that the solution could wait for dependent types to
materialise, or we could reify vtables as structs and use those for
dynamic dispatch.

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

Reply via email to