Components are parts of applications that can be combined in larger applications. They should be reusable, and therefore it needs an interface, both describing the provided and the required services. This is how it differs from an API.
A component should refer to others via members of parameters (so not statics) This is surprisingly hard to achieve.
In principle Functors work really well for this, but in practice this is often like this:
This is why we need component abstraction. Two priciple forms are:
- parameterization (FP)
- abstract members (OO)
What about contracts in Scala?
Scala does not have contracts, but can they be added after the fact?
First let’s have a look at how other language implement this. Some languages have contracts as part of the language, most notable is of course Eiffel. JML puts them in the comments in a funny syntax. But this is disconnected from the language ans has to do its own parsing and type checking. Now, Java has annotations, but this is not that different from comments. A different way is to put the contract in code. This is a good re-use of language features and parsing and type-checking come for free. However, it is quite verbose.
Scala has contracts as code with four constructs: assert, assume, require, ensuring. Assert and require are implemented with simple predef objects. Ensuring is technically a method call, that is made possible by an implicit conversion. Classes that use an invariant have to extend the invariant trait, which adds its call-by-name parameter as a closure.
This implementation is extremely lightweight, because of the reuse of language features. Downsides are that some things can’t be expressed, like precondition weakening.
Martin concludes: Scala feels very different for producers (sophisticated toolset with which you can push boundaries of what’s possible) and consumer (easy, intuitive, so user can concentrate on the domain).
Want to learn more about Scala? I enjoyed Scalabound.