archives

Type safety in libraries

I wonder if this subject was already studied, as I think I need to look into it for my language. How do you ensure type safety across compilation boundaries?

For example, I am thinking of the situation where a type is shared between an application and a dynamic library. There is no control over the memory layout of the type if both are compiled separately. You could decide that the type belongs to the other codebase, and only perform safe operations on it (call methods, etc.) this way differences in version and even in implementation do not break your code.

But what if both have the type compiled in and this cannot change? The library could interface with some other code which requires the type to be implemented in the library, and the application may need to perform operations which require the memory layout of the type to be used.

In Java, there is bytecode verification - I do not want to depend on using bytecode. Ideally dodo should compile to machine instructions.

In C++, the memory layout is explicitly defined in header files which are shared between different pieces of code - this is brittle and poor encapsulation.

In Lisp, all structures are reducible to cons operations. This is more seductive but I don't think I could live with the performance penalty.

In all these cases, the internal state of an object is accessible by foreign code -although in the case of Java the JVM can put restrictions on code other than its own- which I want to avoid.

In some cases I could rebuild the object at the other end based on my (known) implementation of the type and the public properties of the object, but this does not always contain enough info to do anything useful.

Could I determine in a trusted way if separately compiled pieces of code use the same implementation of a type?