Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

The object-functional impedance mismatch

In OOP it is good practice to talk to interfaces not to implementations. So, e.g., you write something like this (by Seq I mean scala.collection.immutable.Seq :)):

// talk to the interface - good OOP practice
doSomething[A](xs: Seq[A]) = ???

not something like the following:

// talk to the implementation - bad OOP practice
doSomething[A](xs: List[A]) = ???

However, in pure functional programming languages, such as Haskell, you don't have subtype polymorphism and use, instead, ad hoc polymorphism through type classes. So, for example, you have the list data type and a monadic instance for list. You don't need to worry about using an interface/abstract class because you don't have such a concept.

In hybrid languages, such as Scala, you have both type classes (through a pattern, actually, and not first-class citizens as in Haskell, but I digress) and subtype polymorphism. In scalaz, cats and so on you have monadic instances for concrete types, not for the abstract ones, of course.

Finally the question: given this hybridism of Scala do you still respect the OOP rule to talk to interfaces or just talk to concrete types to take advantage of functors, monads and so on directly without having to convert to a concrete type whenever you need to use them? Put differently, is in Scala still good practice to talk to interfaces even if you want to embrace FP instead of OOP? If not, what if you chose to use List and, later on, you realized that a Vector would have been a better choice?

P.S.: In my examples I used a simple method, but the same reasoning applies to user defined types. E.g.:

case class Foo(bars: Seq[Bar], ...)
like image 849
lambdista Avatar asked May 09 '16 12:05

lambdista


People also ask

What happens if there is an impedance mismatch?

In electrical engineering, an impedance mismatch occurs when the input impedance of an electrical load does not match the output impedance of the signal source, resulting in signal reflection or an inefficient power transfer (depending on the type of matching required).

What is impedance mismatch example?

A programming impedance mismatch occurs when data needs to be transformed into a different architectural paradigm. The most prominent example involves object-oriented codebases and relational databases. An impedance mismatch arises when data is fetched from or inserted into a database.

What are the mismatch between the object and relational model?

The object–relational impedance mismatch is a set of conceptual and technical difficulties that are often encountered when a relational database management system (RDBMS) is being served by an application program (or multiple application programs) written in an object-oriented programming language or style, ...

Which of the following are mismatches in the relational and ORM model?

Impedance Mismatch between Object Model and Relational Model. The Object Oriented (Domain) model use classes whereas the relational database use tables. This creates a gap (The Impedance Mismatch).


1 Answers

What I would attack here is your "concrete vs. interface" concept. Look at it this way: every type has an interface, in the general sense of the term "interface." A "concrete" type is just a limiting case.

So let's look at Haskell lists from this angle. What's the interface of a list? Well, lists are an algebraic data type, and all such data types have the same general form of interface and contract:

  1. You can construct instances of the type using its constructors according to their arities and argument types;
  2. You can observe instances of the type by matching against their constructors according to their arities and argument types;
  3. Construction and observation are inverses—when you pattern match against a value, what you get out is exactly what was put into it.

If you look at it in these terms, I think the following rule works pretty well in either paradigm:

  • Choose types whose interfaces and contracts match exactly with your requirements.
    • If their contract is weaker than your requirements, then they won't maintain invariants that you need;
    • If their contracts are stronger than your requirements, you may unintentionally couple yourself to the "extra" details and limit your ability to change the program later on.

So you no longer ask whether a type is "concrete" or "abstract"—just whether it fits your requirements.

like image 166
Luis Casillas Avatar answered Oct 21 '22 04:10

Luis Casillas