curry-frontend-1.0.4: Compile the functional logic language Curry to several intermediate formats

Copyright(c) 2000 - 2007 Wolfgang Lux
2015 Jan Tikovsky
2016 Finn Teegen
Safe HaskellNone



Interface files include declarations of all entities that are exported by the module, but defined in another module. Since these declarations can become inconsistent if client modules are not recompiled properly, the compiler checks that all imported declarations in an interface agree with their original definitions.

One may ask why we include imported declarations at all, if the compiler always has to compare those declarations with the original definitions. The main reason for this is that it helps to avoid unnecessary recompilations of client modules. As an example, consider the three modules:

module A where { data T = C } module B(T(..)) where { import A } module C where { import B; f = C }

where module B could be considered as a public interface of module A, which restricts access to type A.T and its constructor C. The client module C imports this type via the public interface B. If now module A is changed by adding a definition of a new global function

module A where { data T = C; f = C }

module B must be recompiled because A's interface is changed. On the other hand, module C need not be recompiled because the change in A does not affect B's interface. By including the declaration of type A.T in B's interface, the compiler can trivially check that B's interface remains unchanged and therefore the client module C is not recompiled.

Another reason for including imported declarations in interfaces is that the compiler in principle could avoid loading interfaces of modules that are imported only indirectly, which would save processing time and allow distributing binary packages of a library with a public interface module only. However, this has not been implemented yet.