4 ms·
Couldn't have said it better. Classes are useful, but only occasionally so. About the only time I find myself using classes is when there's several functions th
by rectangletangle 12y ago
Couldn't have said it better. Classes are useful, but only occasionally so. About the only time I find myself using classes is when there's several functions that have a very strong relationship to a particular portion of state (like when using an ORM). The rest of the time it's referentially transparent functions.
- mercurial 12y agoMy beef with plain functions is that you can't mock them properly. But apart from this, yes. Referential transparency as much as possible.
- Arkadir 12y agoWhat situation would require to mock a function ?
- mercurial 12y agoMaybe I'm not interested in testing what the function does? But yes, for pure functions, it's kind of a weak argument. More generally, you can't really swap a different implementation in place.
- JackMorgan 12y agoI answered this in my other answer to you: https://news.ycombinator.com/item?id=7709395 https://news.ycombinator.com/item?id=7709395 It's a common misconception that interfaces are the only way to do polymorphism, because that's usually the only way in Java.
- koide 12y agowhen you require unit tests to finish quickly for functions doing io or otherwise time consuming processes. this being a good idea or not I'll leave to the threads about dhh's tdd article
- Arkadir 12y agoI would argue that functions have no business performing global side-effects in the first place --- these things are better expressed as state encapsulators (such as objects) anyway.
- JackMorgan 12y agoThis is highly dependent on your language. A language where functions can be passed as values allows functions to be injected as parameters (for polymorphic behavior). In Clojure, you can even replace a function definition just for unit tests without dependency injection at all. For example, with-redefs. This allows you to replace a given function anywhere in the whole codebase with any lambda. This rebinding only lasts inside the scope of the s-expression. When I realized that, I realized everything I knew about DI and interfaces were just hacks of incredible complexity to get around a poor language that wasn't built to allow unit testing. I now think it's impossible to have both unit testing and a good design in Java/C#. Neither were made to be easy to unit test, it wasn't even a concept when Java was made. In C#'s defense, there is a way to mock a static function by replacing it using the Mocks library. To MS's shame, that library requires the 13k edition of Visual Studio. When I realized that, I realized I want to leave C# for good. I'm not interested anymore in a language that resists testing so much I have to choose between an easy to understand design and unit tests.
- mercurial 12y agoHm, that may be true for Clojure (or Python, as long as you don't redefine anything important), but I wouldn't how to do that with Haskell, for instance.
- dllthomas 12y agoIt's true that you can't replace arbitrary pieces with no source changes in Haskell. On the other hand, there are a few approaches to making this easier - implicit parameters seems made for this kind of thing, "foo = fooBy whatever" as a pattern leaves it easy to swap in an alternative; and of course keeping functions pure it becomes less necessary to swap out internal bits because they don't matter.