On 24-Feb-2000, Marcin 'Qrczak' Kowalczyk <[EMAIL PROTECTED]> wrote:
> Thu, 24 Feb 2000 14:17:43 +0300 (MSK), S.D.Mechveliani <[EMAIL PROTECTED]> pisze:
>
> > Seeing `Just x1 == Just x2'
> > the compiler extends *silently* the context for f:
>
> It would mean that the type no longer determines the way a function
> is physically used.
>
> Well, currently compilers already depend on the body (strictness
> analysis, inlining), but it's for optimization only: does not
> change the semantics and is skipped in cases where it's impossible
> (e.g. higher order functions).
>
> Compilers can't be _required_ to make usage of a function depend on
> its definition (not type alone), because it is sometimes impossible.
>
> Surprisingly, separate compilation does not make this impossible.
> An imported module must be compiled before an importing module can
> use it.
Which of course complicates things in the case where you have
mutually recursive modules.
> A compiler puts derived extra information about compiled
> functions in the interface file. Such inter-module optimizations
> are mostly impossible in languages where the programmer writes the
> interface file himself, like in C.
Such inter-module optimizations are also impossible if you want to build
shared libraries with stable interfaces. If I'm trying to build
such a library, then I want to be able to change the implementation
without changing the interface. That won't work if the binary interface
depends not just on the type, but also on properties that the compiler
silently infers from the definition of the function.
I know ghc does those kind of optimizations by default,
so I hope there is some way of turning them off...
> I cannot imagine a sensible implementation
> of the function:
> h :: Eq a => a -> a -> Int
> h x y = if x == y then 0 else 1 + h [x] [y]
> which would make h "1" "2" return 7 if in some other module there is:
> instance Eq [[[[[[[String]]]]]]] where
> x == y = length x == length y
The only sensible way to implement it, I think, would be to
abandon dictionary-passing. Instead, you could just pass a representation
of the type, with the instance declarations for each class being stored
in a global table, and each method call would search the instance declaration
table for that class to find the best matching instance for that type.
Of course, this would make method calls more expensive.
> > For, to my mind, the separate compilation is not a sacred cow.
> > It is only a technical feature, something that is not theoretically
> > principal.
>
> I don't agree.
Having separate compilation of library packages (which may consist
of more than one module and more than one source file) is indeed
important, because it lets you distribute library packages in
precompiled binary form. This has a number of advantages.
Having separate compilation of individual modules or source files within a
single package (i.e. distribution unit) is not important, though; what is
really desired there is efficient incremental recompilation, and separate
compilation of individual modules or source files is just a means to that end.
> Some people could even say that the current system,
> where an imported module must be compiled before an importing one can,
> is a too limited version of separate compilation,
Yes, indeed. See my comments above about building shared libraries
with stable interfaces.
--
Fergus Henderson <[EMAIL PROTECTED]> | "I have always known that the pursuit
WWW: <http://www.cs.mu.oz.au/~fjh> | of excellence is a lethal habit"
PGP: finger [EMAIL PROTECTED] | -- the last words of T. S. Garp.