How are these principles applied in the context of streams and lambda expressions? In particular, the applicability with respect to the following three principles: - Single Responsibility Principle (SRP) - Liskov-Substitution Principle (LSP) - Open-closed Principle(OCP)

I feel like Lambdas, in general, have single responsibilities however when we use streams we use many lambda expressions chained,together ( map, iterate etc). So streams violate SRP according to my understanding.

I'm unsure if LSP is even applicable to streams and lambda's because it mostly deals with subtypes.

I would like to gain a clearer perspective on this.

  • 1
    "So streams violate SRP according to my understanding." - your understanding could not be more wrong. That seems to be be the same misunderstanding like "any class which contains more than one method violates the SRP".
    – Doc Brown
    Jun 16, 2020 at 17:22
  • About the SRP, see also my older answer here.
    – Doc Brown
    Jun 16, 2020 at 17:28
  • There is so much confusion surrounding the SOLID principles that I'm starting to wonder if they have any enlightenment value. Jun 16, 2020 at 17:29
  • 1
    I feel like Lambdas, in general, have single responsibilities however when we use streams we use many lambda expressions chained,together (map, iterate etc). So streams violate SRP according to my understanding. But each of these functions (map, iterate, etc) has a single purpose, and they all operate on the same Stream type. You don't see the value and elegance in that? Jun 16, 2020 at 17:32
  • 1
    I do see value in that. But the term "single responsibility" is pretty vague to me .
    – L m
    Jun 17, 2020 at 6:51

2 Answers 2


I think streams+lambdas sometimes violate the single responsibility principle and sometimes don't. Sequencing of other operations is a "single thing" for the purposes of SRP. That's what streams do. If you mix that too much with defining the other operations, which is what lambdas do, you can get into a situation where you are no longer doing a "single thing."

Consider the following function from this question:

const getPctSameXs = (getX, filter = vals => vals) =>
  (objA, objB) =>
    filter(getXs(objB, getX))
        (numSame, x) =>
          getXs(objA, getX).indexOf(x) > -1 ? numSame + 1 : numSame,
      ) / Object.keys(objA).length * 100;

Here the lambdas make it really difficult to determine the sequencing. Consider my response that accomplishes the same task:

function getPctSameXs(obj1, obj2, f) {
  const mapped1 = mapObj(obj1, f);
  const mapped2 = mapObj(obj2, f);
  const same = mapped1.filter(x => mapped2.indexOf(x) != -1);
  const percent = same.length / mapped1.length * 100;
  return percent;

SRP purists would probably want to move some of this into separate functions, but this is roughly at the same level of abstraction, and the sequencing is easy to see.

In other words, a syntactic construct like a stream neither fulfills nor violates a principle on its own. It's about how you use it.


SRP and OCP both sound like wisdom, but are essentially meaningless. There are no clear set of definitions, and there are conflicting interpretations, most of which don't even seem to have any clear design advantages.

Unless you define what you mean (not just link the Clean Code book, or some article without good examples), there is no point discussing this.

Liskov, even though it has its gray areas, is well defined, but as you mentioned is not applicable here.

A much better question though is, do you write lambdas and use streams that violate encapsulation / object-orientation / Law of Demeter? Because a lot of labmda/stream code out there does. Things like:

people.filter(p -> p.getName().startsWith("A"))

Unless you're in the Person class this filtering violates all of the above.

  • 1
    SRP and OCP are often mistaken as general guidelines, but really are context-dependent. One of their main design advantages however lies in writing code which is easily unit-testable, avoids tight coupling between classes, avoids/minimises injected dependencies, minimises/avoids the need for mocking and extensive setup in unit tests, minimises the number of different test cases needed for sufficient unit test coverage. Jun 16, 2020 at 22:07
  • @BenCottrell That's the sales pitch. It's highly debatable whether any of that is true. "Avoids tight coupling" sounds especially untrue, given that SRP primes developers to split stuff. Splitting up objects never results in less coupling, since coupling is a thing between objects. The most you can argue, is that it may result in increased cohesion, but that happens at the expense of coupling. Jun 17, 2020 at 9:10
  • What you're describing there is a result of failure to follow SRP and OCP. It's not entirely uncommon for people to misunderstand or misinterpret - again, that could be down to people viewing them as general purpose guidelines such as assuming it means "an object should only do one thing", or just not really understanding the requirements of a project. Tightly-coupled classes and code which requires a lot more mocking and set-up in unit tests are a very definite violations of SRP. Jun 17, 2020 at 14:21
  • I also disagree with the premise that splitting up objects results in increased coupling. There is no reason for objects to have any dependency on each other at all. Any object can do its job or jobs without being dependent upon other objects provided it has enough information. The task of orchestrating objects and facilitating communication between objects does not require those objects to communicate with each other nor have any dependency on each other -- it doesn't even require them to share any interfaces. Orchestration is often separate. Jun 17, 2020 at 14:30
  • @BenCottrell Ok, the code you split up may actually have no connection to the other code you had in the class. So that would not increase coupling, you're right. However that's the most you can say. It will never decrease coupling. Jun 17, 2020 at 14:42

Not the answer you're looking for? Browse other questions tagged or ask your own question.