3 ms·
The main difference I find is that with Clojure approach you have a common set of data structures that you operate on using common functions from the standard l
by yogthos 8y ago
The main difference I find is that with Clojure approach you have a common set of data structures that you operate on using common functions from the standard library. I find that it's usually easy to tell what type of data you're working with by seeing how these functions are used. When I see functions like map, filter, iterate, and so on, I have context for what the intent of the code is, and this helps me know what type of data I'm working with. At the same time I'm mostly working in a local context thanks to immutability, so I don't have to worry that a piece of data might get changed from under you via a side effect.
I also find that you learn patterns for structuring code that make it easier to track the types. For example, I avoid renaming keys or restructuring data except at the edges of the application. Adding Spec or Schema at component boundaries is also helpful, as you can see what the shape of the data was at the API level and work your way through the helpers from there.
There's also a big benefit of working with data as opposed to objects. Each class is its own ad hoc DSL with custom behaviors. Knowing what one class does tells you nothing about what another does. This approach doesn't scale well for large applications where you have thousands of classes with each with its own behaviors.
- jb1991 8y agoI think I would definitely benefit from blog posts or whole books on Clojure style specifically, rather than the many constant re-introductions to its syntax and data structures (like the one in this article). Your thoughts have come closer to explaining a maintainable approach to the language than most of what is out there. In my experience, despite working for years professionally with Clojure, I've never successfully felt like I wasn't fighting the language because of the constant and unexpected nils and other odd wranglings of data that were not intended and not easy to track down at runtime. The flexibility of the dynamic typing and the many APIs for manipulating data can make it easy to restructure your values in unintended ways, and this to me is a meaningful problem unique to the language. I don't have the problem in a Java app, for example, of a Foo type accidentally becoming a Bar type or even some other "type" that was never defined but now has a unique data shape because I made a typo somewhere or used the wrong library function, etc.