Hacker News new | past | comments | ask | show | jobs | submit login

I seems you interpreted SOLID with a functional mindset and then turned around and found OO lacking.

1. Single-Responsibility Principle: Whether or not an object can change it's own state has nothing to do with how many responsibilities it has. Even a pure function that takes a single argument can have multiple responsibilities. To give a silly example a spell-check-and-update-wordcount function/object would violate SRP.

2. Open-Closed Principle is about modification of the code. It means the function/object should do its thing so well, you never have to touch its code. But if you want to modify the behavior of your program you should have a way to insert your new function/object so the new behavior is added.

3. Liskov Substitution Principle: "the type checker isn't mathematically sound" No type checker is mathematically sound. Obviously correct statement, since even math itself cannot be automatically proven. However what LSP basically warns against is to say: "a square is a special type of rectangle". It's not, because if you take this 'rectangle' and multiply its width by 2 and its height by 3, you either end up with a 'not a square', which is unexpected or you don't end up with 2xwidth by 3xheight, which is also unexpected.

4. Interface Segregation Principle: agreed

5. Dependency Inversion Principle: "modules should just communicate with one another" is exactly what DIP warns against. Your monthly-activity-calculator shouldn't 'just' communicate with the user-database module. It should take a user-collection interface and let another part of the program that is responsible (SRP!) for setting up that system provide it. That way this program-setup can decide based on configuration / the environment to pass it a redis-user-collection instead of an oracle-user-database.




1. Depending on what layer you analyze things at, in OOP, it may not be possible to maintain single responsibility. In OOP SOLID refers to the business layer. However with FP you can take single responsibility all the way down to types. A function returns One TYPE. It interfaces with the universe through a single type and that is one responsibility.

2. Why does the open and closed principle only have to apply to code? What if it could apply to everything. You gain benefits when you apply this concept to code... what is stopping the benefits from transferring over to runtime structures. SOLID for OOP is defined in an abstract hand wavy way, for FP many of those guidelines become concrete laws of the universe.

>No type checker is mathematically sound. 3. A type checker proves type correctness. Languages can go further with automated provers like COQ or agda. They are mathematically sound. Your square example just means that types shouldn't be defined that way. It means that the type checker isn't compatible with that method of defining types.

4. -

5. I highly disagree. There should only be communication between modules NEVER dependency injection. The monthly activity module should not even accept ANY module, or module interface as a parameter. It should only accept the OUTPUT of that module as a parameter. This makes it so that there are ZERO dependencies.

For example don't create a Car object that takes in an engine interface. Have the engine output joules as energy and have the car take in joules to drive. Function Composition over Dependency Injection. (Also think about how much easier it is to unit test Car without a mock engine)

If you get rid of dependency injection, you get rid of the dependency inversion principle. DIP builds upon a very horrible design principle which makes the entire principle itself horrible.




Consider applying for YC's Spring batch! Applications are open till Feb 11.

Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: