So thankful to be programming in Clojure the past few years. Thank you, Clojure Team, for all you do!
My favorite things about using Clojure:
1. Runs on the JVM. Battle tested, tons of libraries, and well engineered.
2. Immutable Data Structures. I wouldn't want to live without this safety ever again.
3. LISP syntax - so simple to remember and just basically code functions! I also find reading Clojure code very simple vs other procedural languages.
4. REPL development.
5. Transducers - not unique to Clojure, but just love them so listed it.
When you say immutable data structures, do you mean all lisp data structures are immutable? It’s been awhile since I’ve worked with lisp (and that was implementing a MAL not actually writing lisp.)
About the syntax. I tend to prefer Scheme because (, [ and { mean the same thing, whether in Clojure they are different constructs. How do you feel about this minor point?
Glad to see Clojure continuing to improve. Racket borrows a lot from Clojure^1,2,3 so its success fuels ours as well. With the other post on here about Java 18 including Pattern Matching, I'm glad that good ideas continue to cross pollinate between different languages. Programming is still a young field compared to other professions, and there is still a lot of good things left to discover!
If you have been filtering out clojure due to dislike of JVM, give it a try with GraalVM either directly [1] or via Babashka [2]. GraalVM will in most cases not only run your code much faster than JVM, but cuts startup time from seconds down to msecs [3][4], not to mention compiling to native with c api or LLVM. With Babashka, it packages a subset of GraalVM so you don't have to install that but is more limited. So if you just want to play around with clojure to see if you like it, Babashka is a great way to start.
A nitpick: Your code will not run faster in GraalVM vs the JVM, it will start faster. If its small scripts where the startup time dominates, then of course it goes faster. For anything long-lived (even in the range of tens of seconds), the JVM has better performance.
Juxt had a recent blog post covering the new Clojure (iteration) function in depth, which is useful for abstracting over sequences that require some state management to access, such as a paginated API.
Sweet, variadic maps sound really useful, I am always having to take a moment when mixing functions that take keyword arguments vs. option maps. Also, some of those functions added to core show up in my code as convenience functions - Glad I can now just make use of core.
The parse-*, update-keys, update-vals, and random-uuid functions are great additions to core. I look forward to dropping the custom versions from each of my projects!
Every person I know that has developed in Clojure has high praise for it.
How does it compares to the likes of other statically typed Lisp dialects such as Rackett?
I've always wanted to read "Clojure for the brave and true" but there's just enough lisp books (my favorite being "Structure and Interpretation of Computer Programs") I can read without actually wanting to use the language.
I think a lot of people that come from clojure arrive at consensus that you can instrument some typechecking on edges. Define what is valid(input) data and move it through your program. Inside your program it rarely matters(from validity perspective) if something is a list, tuple, lazylist - it is a collection. Things are either single value, collection or associative the semantics around each in code are pretty obvious in most cases.
Its always contentious topic, there are no answers.
- ease the onboarding. Every few months I try to give clojure another shot, and every few months _some_ part of the setup has changed and / or is broken.
- compile to small binaries that run fast. I get what the langage gets from the JVM, but those 5,10 seconds I get before _anything_ runs, even after I had everything compiled ?
- show me an example of how having 'spec' is going to help me refactor the code that I got wrong the first time, as easily as what a proto-ML-like static type checker does. It's not a question of "types are bad vs types are good thing". It's a question of "this property was called 'name', but now I need it to be 'names', and I really need to know every possible place of my code base that uses it so that I can recursively change all code paths to handle the fact that it's a list, now." I read the spec doc a dozen times, and I don't think it does help in this simplest of simple case.
Also, I make typos all the time, and caml / typescript / rust catch them before I waste a run cycle. Dynamic langages can't know if 'names' and 'name' coexist - Let me tell the compiler what I mean once.
- promote an "obvious" gui lib. It's not obvious what I need to use to do an hello world window (but that's really not specific to clojure, in all fairness...)
Nothing. It is still growing. Slowly, steadily, systematically. Clojure evolves strategically, not tactically. Besides, no matter what happens - Clojure would stay a niche language. There are certain benefits to that. Those who tie business worth and technical advantages to language popularity, often ignore them.
My unit (just like many other Clojure teams) has been building numerous solutions for many years now. Our employer loves us very much. As long as we keep making money; maintain our codebase aiming for expansion rather than [quartely] renovation - investors won't care what we use to achieve the results. If other companies prefer hiring new devs and rebuilding everything every two years - well, that's their money.
I would never use it under any circumstance of my choosing, since it's a dynamically typed language and I don't have any further need for any more of those at the moment; in fact only looking to cut down on my usage of them.
But from my experience working with it on real projects:
- Good tutorials, combined with library and build tooling integration for usage with GraalVM. Startup times make it a horrible fit for anything other than long-lived daemons.
- Speaking of build systems: more ecosystem coalescing around tools.deps, there's a lot of resources around Leiningen, not too many around the blessed native tooling (I know, I know, it's fairly new for Clojure standards, but it is a problem).
- More and better linters for popular libraries. Without good types, you need something to guide you when you're misusing an API; the team where I worked with Clojure lost a lot of time getting Reagent patterns wrong.
My final complaint is something that I don't think can't ever be fixed without undoing what makes Clojure, Clojure:
REPL-driven development combined with dynamic typing, in the same way as its cousin: debugger-driven development, often leads to write-only code that works but good luck using it or modifying it if you don't have good automated tests to tell you how it's supposed to be used and more importantly how it's not.
It doesn't help that tests are de-emphasized by the community precisely because of REPL-driven development. "Just put it on the REPL and see what it does" is not a good way of reasoning about code, and makes it easy and convenient to just pile on more hacks that may or may not break something instead of promoting understanding. "Just write good code and have discipline, you're doomed if you can't do that anyway" does not excuse that other languages have radically different tools and practices that lead to far fewer footguns.
Companies seeing some value in it and pushing it but that won't happen. Most companies today want static typing and don't want to rely on discipline for stuff like maintaining documentation/more tests and having them up to date.
If it's true that engineers leave after one/two years then I can't blame them. Whatever cost static typing brings, it's worth it to them. Just look at how typescript usage has exploded.
I use Clojure every day at work and it's my favorite dynamic functional language. That said, I think in large projects like the one I'm working in, a statically typed language would've been better. I know Clojure has spec and other similar libraries but it's just not a replacement for static typing.
I love Clojure and would use it for small projects if given the chance but I think there are diminishing returns when you scale up, specially if you deal with a complex data structures which get encoded and decoded to JSON (messes up things like keywords).
[+] [-] silver-arrow|4 years ago|reply
My favorite things about using Clojure: 1. Runs on the JVM. Battle tested, tons of libraries, and well engineered. 2. Immutable Data Structures. I wouldn't want to live without this safety ever again. 3. LISP syntax - so simple to remember and just basically code functions! I also find reading Clojure code very simple vs other procedural languages. 4. REPL development. 5. Transducers - not unique to Clojure, but just love them so listed it.
Great language.
[+] [-] edgyquant|4 years ago|reply
[+] [-] haolez|4 years ago|reply
[+] [-] Decabytes|4 years ago|reply
1. https://docs.racket-lang.org/collections/index.html 2. https://docs.racket-lang.org/seq/index.html 3. https://docs.racket-lang.org/threading/index.html
[+] [-] kbuchanan|4 years ago|reply
[+] [-] agumonkey|4 years ago|reply
[+] [-] zitterbewegung|4 years ago|reply
[+] [-] bjoli|4 years ago|reply
[+] [-] fuzzythinker|4 years ago|reply
[1] https://github.com/oracle/graal
[2] https://github.com/babashka/babashka
[3] https://arnoldgalovics.com/java-cold-start-aws-lambda-graalv... (large proj - dynamoDB)
[4] https://dev.to/wololock/groovy-script-startup-time-from-2-1s... (small proj)
[+] [-] orestis|4 years ago|reply
[+] [-] hiepph|4 years ago|reply
For a one-liner scripting I still use Bash but for a larger script I now use Clojure.
[+] [-] timgilbert|4 years ago|reply
https://www.juxt.pro/blog/new-clojure-iteration
[+] [-] pjmlp|4 years ago|reply
Whìch happens to be the favourite alternative JVM language from Brian Goetz,
https://youtu.be/GedrGWu16_I
[+] [-] jakebasile|4 years ago|reply
I'm particularly happy with the new keyword args semantics, which solves a long standing pain point.
[+] [-] brtmr|4 years ago|reply
[+] [-] jdminhbg|4 years ago|reply
[+] [-] d_t_w|4 years ago|reply
[+] [-] epolanski|4 years ago|reply
How does it compares to the likes of other statically typed Lisp dialects such as Rackett?
I've always wanted to read "Clojure for the brave and true" but there's just enough lisp books (my favorite being "Structure and Interpretation of Computer Programs") I can read without actually wanting to use the language.
[+] [-] roguas|4 years ago|reply
Its always contentious topic, there are no answers.
[+] [-] buzzwords|4 years ago|reply
[+] [-] phtrivier|4 years ago|reply
- compile to small binaries that run fast. I get what the langage gets from the JVM, but those 5,10 seconds I get before _anything_ runs, even after I had everything compiled ?
- show me an example of how having 'spec' is going to help me refactor the code that I got wrong the first time, as easily as what a proto-ML-like static type checker does. It's not a question of "types are bad vs types are good thing". It's a question of "this property was called 'name', but now I need it to be 'names', and I really need to know every possible place of my code base that uses it so that I can recursively change all code paths to handle the fact that it's a list, now." I read the spec doc a dozen times, and I don't think it does help in this simplest of simple case.
Also, I make typos all the time, and caml / typescript / rust catch them before I waste a run cycle. Dynamic langages can't know if 'names' and 'name' coexist - Let me tell the compiler what I mean once.
- promote an "obvious" gui lib. It's not obvious what I need to use to do an hello world window (but that's really not specific to clojure, in all fairness...)
[+] [-] iLemming|4 years ago|reply
My unit (just like many other Clojure teams) has been building numerous solutions for many years now. Our employer loves us very much. As long as we keep making money; maintain our codebase aiming for expansion rather than [quartely] renovation - investors won't care what we use to achieve the results. If other companies prefer hiring new devs and rebuilding everything every two years - well, that's their money.
[+] [-] jdminhbg|4 years ago|reply
[+] [-] mixedCase|4 years ago|reply
But from my experience working with it on real projects:
- Good tutorials, combined with library and build tooling integration for usage with GraalVM. Startup times make it a horrible fit for anything other than long-lived daemons.
- Speaking of build systems: more ecosystem coalescing around tools.deps, there's a lot of resources around Leiningen, not too many around the blessed native tooling (I know, I know, it's fairly new for Clojure standards, but it is a problem).
- More and better linters for popular libraries. Without good types, you need something to guide you when you're misusing an API; the team where I worked with Clojure lost a lot of time getting Reagent patterns wrong.
My final complaint is something that I don't think can't ever be fixed without undoing what makes Clojure, Clojure:
REPL-driven development combined with dynamic typing, in the same way as its cousin: debugger-driven development, often leads to write-only code that works but good luck using it or modifying it if you don't have good automated tests to tell you how it's supposed to be used and more importantly how it's not.
It doesn't help that tests are de-emphasized by the community precisely because of REPL-driven development. "Just put it on the REPL and see what it does" is not a good way of reasoning about code, and makes it easy and convenient to just pile on more hacks that may or may not break something instead of promoting understanding. "Just write good code and have discipline, you're doomed if you can't do that anyway" does not excuse that other languages have radically different tools and practices that lead to far fewer footguns.
[+] [-] wildermuthn|4 years ago|reply
[+] [-] joshlemer|4 years ago|reply
[+] [-] unknown|4 years ago|reply
[deleted]
[+] [-] newlisp|4 years ago|reply
If it's true that engineers leave after one/two years then I can't blame them. Whatever cost static typing brings, it's worth it to them. Just look at how typescript usage has exploded.
[+] [-] armitron|4 years ago|reply
[+] [-] masijo|4 years ago|reply
I love Clojure and would use it for small projects if given the chance but I think there are diminishing returns when you scale up, specially if you deal with a complex data structures which get encoded and decoded to JSON (messes up things like keywords).
[+] [-] lbj|4 years ago|reply
[+] [-] fogus|4 years ago|reply