4 ms·
When I started using Clojure, the first two weeks were mess. I was trying to fit everything in procedural way of thinking and boy was it a mess. I felt really m
by timewarrior 10y ago
When I started using Clojure, the first two weeks were mess. I was trying to fit everything in procedural way of thinking and boy was it a mess. I felt really miserable and maybe that is how it felt when I first started to walk. And then suddenly everything clicked and the world was beautiful.
Clojure has a steep learning curve when you start. After about a year and a half there is another much steeper curve and if you cross it, I have heard it feels like you have super powers. I am probably 4/10 on Clojure and 9.5/10 on Java. However I take around 10% of time to get better results with Clojure vs Java.
I can try taking a shot at listing why I love Clojure however for me it is as difficult as explaining why I love someone:
1. Computers are functional. You give them a massive subroutine and they execute it. All procedural languages have built semantics to make it supposedly easy for humans to write code but end up with a lot of hacks. Only you start writing functional you feel finally connected to the computer.
2. Immutable structures: With most languages it's difficult to have assumptions about how your code will work. You pass your data to a function, can they change the data due to a bug or bad design. Do you create a copy before sending it to them? All those issues go away. It's better to understand expectations and stupid errors go out of the way.
3. Reusable code: because it's functional and without side effects it's much more easier to create reusable code as a part of standard library. You have functions like butLast (give me all elements of an array except last), even?, rest (return all elements of array except first). Imagine how much less boiler plate would it be. Check out some of the functions here: http://clojure.org/api/cheatsheet http://clojure.org/api/cheatsheet
4. Encourages you to write smaller chunks of functions, not 2000 line long functions. Improves code reusability and testing.
5. Doesn't allow bad design practices - circular dependency.
6. Because the language is built on a very few core constructs, you or anyone else can enhance the language. I have seen situations where someone had a proposal to extend the language, they just releases it as a library. If people like it and use it, it would get included as a part of core framework.
7. The quality of available talent - Because there is a steep learning curve almost everyone Clojure programmer that you meet is likely to be very smart.
8. Has inbuilt support for magical stuff like macros, STM. You can Google it to find out more.
9. Imagine all the java libraries that were very complicated to use and with their confusing java docs. Clojure community has built a lot of super easy to use wrappers on top of it and you could easily write one too.
10. In other languages if I see a library on github which hasn't been updated for years, it feels like it has been abandoned and I would not consider using it. With Clojure, because of functional and no side effects - a code which works now is likely to keep on working with it's current contract. It is not uncommon to see libraries which were built by some of the rockstars in the community within a day and not updated for years but still they work great.
11. Because of being functional and no side effects, code hot replace actually works. Many other languages have attempted it, but it always comes with a bit of caveats. With Clojure it just works. My developer code flow was that I would use an IDE and which I am writing code, it would hot replace the code in VM, find the tests which depends on the changed code and run just them. So I can see the code I am breaking while I am writing code. This is unbelievable. When we had an issue, I used this to connect to a REPL (a commandline for VM) - hot swapped a code to add logging, figured out the issue, fixed the code locally, copied the function to replace the code on running server, fixed the code and pushed it again (I wouldn't recommend people do this, but explains the power at your fingertips).
This list could go on and on. In my current job, I am building a big team where any set of people could come together and build a startup. Like Google's Area 120, but started more than an year before that. Unfortunately I am not encouraging people to use Clojure here, because it would set them back by months. I really love my current job, however I keep getting impulses of quitting everything and just code Clojure full time.
I hope people can see that I am smitten. Give it a try and I promise you wouldn't regret.
edited: for readability
- icebraining 10y agoYou have functions like butLast (give me all elements of an array except last), even?, rest (return all elements of array except first). Imagine how much less boiler plate would it be. As a Python programmer, those sound like a poor tradeoff for slicing syntax. And why do (drop) and (nthrest), which seem to do essentially the same but for lazy/non-lazy, take the arguments in the inverse order?
- madmax96 10y ago> As a Python programmer, those sound like a poor > tradeoff for slicing syntax. Because Python has a static syntactic system. To Lispers, it makes no difference whether or not it's slicing syntax or a function call. Clojure also has a `subvec` function that behaves the way you're getting at. > And why do (drop) and (nthrest), which seem to do > essentially the same but for lazy/non-lazy, take the > arguments in the inverse order? The partial function application for `drop` allows you to create a "dropping" function like `(partial drop 10)` that you can pass about (such a function has a particular use-case w/ transducers), and partially applying `nthrest` lets you create a "to drop" function like `(partial nthrest [1 2 3])` that you can pass about.
- icebraining 10y agoBecause Python has a static syntactic system. To Lispers, it makes no difference whether or not it's slicing syntax or a function call. Conversely, as a programmer, I don't care if the syntactic system is static or not :) what I care about is ergonomics. subvec doesn't seem to support negative indices, so while it sounds superficially similar, it can't replace all those tiny functions (like butLast), while slicing can.
- madmax96 10y ago> subvec doesn't seem to support negative indices You don't need negative indices to define a function like `butlast` (or any function for that matter): (defn my-butlast [vec] (if (empty? vec) nil (subvec vec 0 (dec (count vec))))) If you really care about negative indices support (although you shouldn't because it is wrong) then you can easily add this. IMO, negative indices hide bugs and obfuscate code. Complaining that a Lisp doesn't support syntax Y is kind of silly because of the extendable syntax of the language -- if a language implements Y, then Lisp can implement it as well. Since we have macros, we don't even need to touch the core language, and this is a huge advantage when it comes to language durability. As the Clojure community is very healthy, we have appropriated all sorts of ideas from other languages (most notably, a very "inspired" implementation of Channels from another language and a new spec system that bares a striking resemblance to Racket's contracts...) :) If Python comes out with an earth-shattering language construct, we'll gladly appropriate it and continue along our merry way.