It is said by some that if you take SOLID principles to their extremes, you end up at functional programming. I agree with this article but I think that some semantics are lost in the transition from interface/object to function/closure, and I want to know how Functional Programming can mitigate the loss.
From the article:
Furthermore, if you rigorously apply the Interface Segregation Principle (ISP), you'll understand that you should favour Role Interfaces over Header Interfaces.
If you keep driving your design towards smaller and smaller interfaces, you'll eventually arrive at the ultimate Role Interface: an interface with a single method. This happens to me a lot. Here's an example:
public interface IMessageQuery
{
string Read(int id);
}
If I take a dependency on an IMessageQuery
, part of the implicit contract is that calling Read(id)
will search for and return a message with the given ID.
Compare this to taking a dependency on its equivalent functional signature, int -> string
. Without any additional cues, this function could be a simple ToString()
. If you implemented IMessageQuery.Read(int id)
with a ToString()
I may accuse you of being deliberately subversive!
So, what can functional programmers do to preserve the semantics of a well-named interface? Is it conventional to, for example, create a record type with a single member?
type MessageQuery = {
Read: int -> string
}
Without any additional clues
... maybe it is why the documentation is part of the contract?