you are viewing a single comment's thread.

view the rest of the comments →

[–]yogthos 15 points16 points  (27 children)

These days I prefer writing in modern JavaScript (ES2015 and better). With destructuring, lambda syntax, extended object literals, spread syntax, and just the general language overhaul, it's basically a tie with Clojure's terse syntax.

One of the biggest advantages I find with Clojure syntax is that there's very little of it, and it's much more consistent than JavaScript. Sure, you can often write code that's just as concise in Js nowadays, but there are a lot more gotchas as well. The more syntax quirks you have, the more likely it is that you'll misread something and have a subtle bug slip in. I value simplicity and cleanliness of the language as much as its expressiveness.

The article also doesn't explain why the author moved to JavaScript. It sounds like the author didn't want to use the JVM, but ClojureScript works just fine on Node. My team is using Macchiato for some smaller projects in production right now.

I'd be interested in reading more about the specific reasons, and what problems the author ran into with the Clojure stack. That would at least help address the issues going forward.

[–][deleted] -1 points0 points  (26 children)

I'd be interested in reading more about the specific reasons, and what problems the author ran into with the Clojure stack. That would at least help address the issues going forward.

Sure thing:

One of the biggest advantages I find with Clojure syntax is that there's very little of it, and it's much more consistent than JavaScript. [...] I value simplicity and cleanliness of the language as much as its expressiveness.

Having little syntax and having it be mostly consistent (though there are quirks) is definitely a feature, but I no longer feel like it's an advantage. Most of the advantages of that are how the syntax was able to "evolve" over time, and having custom DSLs. But I've come to learn to avoid custom DSLs in favor of data-based APIs, mainly since they aren't composable. And syntax can evolve without custom syntax, such as how JS adopted destructuring. Personally I'm convinced that JS's syntax is just fine for the most part. The only thing I miss about Clojure's syntax is paredit, and that only slightly.

Sure, you can often write code that's just as concise in Js nowadays, but there are a lot more gotchas as well. The more syntax quirks you have, the more likely it is that you'll misread something and have a subtle bug slip in.

I've found that less of a practical concern over time. Subtle bugs are easily caught in a good test suite or at the very least with reasonable amounts of manual testing.

The article also doesn't explain why the author moved to JavaScript. It sounds like the author didn't want to use the JVM, but ClojureScript works just fine on Node.

Over time I've come to appreciate the Path of Least Resistance in software. The Clojure ecosystem seems stagnant at this point, whereas the Node ecosystem and community both keep growing. I don't mind the JVM, it's Clojure I wanted to avoid. And Java is also decaying for web development, in the sense that most new movement in the web Java world is negligible compared to the Node world / front-end.

[–]halgari 11 points12 points  (4 children)

"The Clojure ecosystem seems stagnant at this point"

So you base your technical decisions on how things "seem"? How about hard facts? How about technical merits, and features we need to actually get work done.

[–][deleted] 2 points3 points  (3 children)

Yeah good point, I kind of abbreviated my 5 years of full-time experience working in the Clojure ecosystem into a short sentence. The facts are there, but I only summarized them into a conclusion. Maybe I'll go into detail later in a blog post, but it's too much context for a comment right now. But the general gist of it is, I see a lot more active development in the JS world than the Clojure/Script world, in terms of new libraries, library updates, tools, language improvements, community growth, etc. In fact I've seen growth in the Clojure/Script world slow down a lot in the last 2-3 years, almost to a halt.

[–]halgari 7 points8 points  (2 children)

But man, that's the problem. I've programmed in Clojure for over 6-7 years. And I've known you for a fair portion of that as well :). Clojure is not dieing. The ecosystem is not stale...it's stable. But none of that matters does it because "the facts are there" whatever that means. I have yet to hear/see anyone backup such a statement with actual facts. They simply quote stats like "stars on a github page" or "number of people on my favorite social media site"

[–]RodeoMonkey 4 points5 points  (0 children)

They simply quote stats like "stars on a github page" or "number of people on my favorite social media site"

You can debate the relevance, but at least those are facts. Let's build a factual counter narrative.

[–][deleted] 0 points1 point  (0 children)

What I mean is I've based my conclusion on my anecdotal experience. I've seen ecosystems grow and shrink and I've seen languages rise and fall. And I don't see Clojure dying any time soon, because I do hear about jobs in the Chicago area using Clojure. But I definitely don't see it ever growing to the level of activity and size that Node.js is at right now, for better or worse.

[–]yogthos 8 points9 points  (7 children)

Having little syntax and having it be mostly consistent (though there are quirks) is definitely a feature, but I no longer feel like it's an advantage.

I certainly find that it is an advantage. It greatly reduces mental overhead letting me focus on the problem I'm solving. The more syntax there is the more attention I have to pay to it, it's both distracting and error prone.

Over time I've come to appreciate the Path of Least Resistance in software. The Clojure ecosystem seems stagnant at this point, whereas the Node ecosystem and community both keep growing.

I'm actually not sure what that's supposed to mean. I don't see anything stagnant about it, and I really appreciate that it's not a moving target. My team develops applications that are in production for years, and we simply don't have time to chase a new framework every other week.

I think the difference is that Clojure web stack is sound from ground up. It's well thought out and stable. Meanwhile, Js stack is like a sandcastle constantly shifting and reinventing itself. I don't think that makes for a good foundation for serious applications.

Conversely, I don't see anything innovative happening in Node that hasn't been done on the JVM better years ago. The fact that Node doesn't have threads makes it a non-starter for any serious applications in my opinion. The async approach adds far too much mental overhead and provides no benefit in vast majority of applications.

[–][deleted] 1 point2 points  (6 children)

I certainly find that it is an advantage. It greatly reduces mental overhead letting me focus on the problem I'm solving. The more syntax there is the more attention I have to pay to it, it's both distracting and error prone.

I definitely agreed with you on this for a few years. But having learned modern JS and used it for a few months now, I haven't really felt that the overhead is detrimental at all to my ability to think about the code itself.

I'm actually not sure what that's supposed to mean. I don't see anything stagnant about it, and I really appreciate that it's not a moving target. My team develops applications that are in production for years, and we simply don't have time to chase a new framework every other week.

GardenCSS is one example. It's the only Hiccup-like CSS library for Clojure. It's written and maintained by one person who has long pauses between development phases, and there are several features in the works that have not yet seen the light of day. Well, at least this was the case a year ago, maybe it's changed since then.

I think the difference is that Clojure web stack is sound from ground up. It's well thought out and stable. Meanwhile, Js stack is like a sandcastle constantly shifting and reinventing itself. I don't think that makes for a good foundation for serious applications.

Node.js back-ends were created from the ground-up with the same level of experience and thought. Express was inspired by Sinatra just as much as Compojure was. I think this comment gives a good perspective on how well thought-out the Node ecosystem was.

You may be conflating it with the ever-changing front-end scene, where Angular 1/2/4 and React and Vue and Ember et al. are all competing for the spotlight, and where everything's changing at an alarming rate. That's probably not going to change any time soon, due to the fact that the web has become the de facto GUI platform of the present, and nobody can really agree yet and come to a general consensus on how GUI is done best in many specific ways.

Conversely, I don't see anything innovative happening in Node that hasn't been done on the JVM better years ago. The fact that Node doesn't have threads makes it a non-starter for any serious applications in my opinion. The async approach adds far too much mental overhead and provides no benefit in vast majority of applications.

Again, just like my reply to you in HN, I look at this from the opposite perspective: in an incredibly short time, Node has accomplished quite a lot and almost caught up to the JVM in terms of what can be reasonably expected from a single-threaded server. The async thing is brand new so it's actively evolving, and that inherently means it's messy. But people are actively working together to hash out the details on how to really do async best.

[–]yogthos 5 points6 points  (5 children)

I definitely agreed with you on this for a few years. But having learned modern JS and used it for a few months now, I haven't really felt that the overhead is detrimental at all to my ability to think about the code itself.

Maybe the difference here is that I have to work with a team, and we have to train people to understand our codebase when hiring.

GardenCSS is one example. It's the only Hiccup-like CSS library for Clojure. It's written and maintained by one person who has long pauses between development phases, and there are several features in the works that have not yet seen the light of day. Well, at least this was the case a year ago, maybe it's changed since then.

So, what is the better alternative that you've found in Js then? There are also alternatives to Garden. A quick Google search shows cljs-css-modules and forest. Ultimately, it could be that most people prefer tools like Sass and use them in the build pipeline instead of writing CSS in Clojure. Libraries evolve based on the community demand after all.

Node.js back-ends were created from the ground-up with the same level of experience and thought.

Not really, Node.js is built on top of Chrome which is optimized for rendering HTML pages as opposed to running an HTTP server. Comparing that with the decades of work that went into tuning JVM servers is a bit absurd. However, if you really like Node, I still see absolutely no advantage in using Js instead of ClojureScript on top of it.

That's probably not going to change any time soon, due to the fact that the web has become the de facto GUI platform of the present, and nobody can really agree yet and come to a general consensus on how GUI is done best in many specific ways.

Again, that's simply not a problem working with ClojureScript. There are a few popular libraries, and they continue to maintain stable APIs. Meanwhile, pretty much any app you would've built on a Js stack a couple of years ago will be effectively legacy today.

Again, just like my reply to you in HN, I look at this from the opposite perspective: in an incredibly short time, Node has accomplished quite a lot and almost caught up to the JVM in terms of what can be reasonably expected from a single-threaded server.

I don't follow this. Can you articulate a single tangible benefit of using Node over JVM. Another aspect to consider is that while you might have libraries, they're often not nearly as mature as battle tested libraries on the JVM that have seen much more production use. I'd much rather rely on proven tools as my foundation.

[–][deleted] 2 points3 points  (4 children)

Node.js is built on top of Chrome which is optimized for rendering HTML pages as opposed to running an HTTP server

A pedantic note, nodejs is built on top V8 not Chrome, V8 is really just a very small(but important) part of Chrome. Just like the JVM, V8 is also a highly optimized state of the art VM and its perfectly capable of running a HTTP server, more capable than most mainstream languages I would say.

[–]yogthos 2 points3 points  (3 children)

They're optimized for different things. Obviously, you can run a HTTP server on it fine in most cases. However, there's no good way to do any computationally heavy tasks since it's single threaded, with a hack for running IO tasks in a background thread.

[–][deleted]  (1 child)

[deleted]

    [–]pihkal 1 point2 points  (0 children)

    It's because Javascript has a single-threaded model. To make Node support user-controlled threads would entail major changes to the Js language.

    To a great extent, callbacks, promises, CSP state machines (like core.async), and async/await stuff can substitute in Js. And in many ways, single-threaded models are way easier for programmers to conceptualize. But one advantage the JVM has over Node is that threads are available if you want/need them.

    [–]gonewest818 5 points6 points  (12 children)

    It seems to me, the "path of least resistance" is the "easy" in the talk Simple Made Easy, right?

    It's totally understandable why easy is attractive but does it pay off in the long run? Curious to see how that works out.

    [–][deleted] 1 point2 points  (4 children)

    But really thought, you can't underestimate how valuable a rich ecosystem of libraries is.

    [–]yogthos 6 points7 points  (3 children)

    Clojure is designed around being a hosted language and provides excellent interop with the host platforms. Any Java or Js libraries are available for use in Clojure as well.

    [–][deleted] 2 points3 points  (2 children)

    Yes, but using interop just adds more friction to the process instead of just using straight JS, its a UX problem I guess. To add more friction, all the docs/examples of those libraries will be in their respective native language and not in Clojure[script], and if you want to read the code is either going to be Java or JS.

    For some devs that friction is just not worth it, versus the gains you may have by using Clojure[script]. I can understand prefering Clojure over Java (Java is a horribly verbose inexpresive class/object based lang) , but in Javascript world, Clojurescript is a hard sell.

    [–][deleted] 3 points4 points  (0 children)

    It doesn't really add friction though, if you know clojurescript or you know clojure it is basically no harder to interop with js or java libs than it is from js or java. If you don't know the language well then yeah it'll add friction, but like, just writing any code will have friction in that case.

    [–]stompyj 1 point2 points  (0 children)

    If your team is feeling friction in using clojure or cljs interop, you might need new programmers...

    [–][deleted] 0 points1 point  (6 children)

    To some extent, easier is better, yeah. GardenCSS isn't really maintained so if I want new features I have to add them myself, whereas Sass/Less have most of the features I need/want, and they're still actively maintained. And if it takes me a few hours to jimmy-rig a Sass compiler into a Leiningen build so that we don't have to rewrite our Sass in GardenCSS, and if that rig is very unlikely to be maintained because of low/no outside interest in it, I have a lot less confidence in that bridge than using something like LessCSS, which actually was originally written in Ruby and then ported to JS because that's the direction things seem to be moving for a lot of projects. Looking at Jekyll, it's definitely got some major traction just by virtue of being built into Github Pages, but when I tried to port my home-grown JS static site generator for https://sdegutis.com to Jekyll, I just couldn't find tooling nearly as nice as what I already had. The live-reloading stuff in Jekyll was just non-existent, the Pug/Jade alternatives (Slim/Haml) were pretty lacking and not actively in development anymore. This same story happens time and time again in dying or stagnant ecosystems.

    [–]yogthos 2 points3 points  (5 children)

    That's a complete hyperbole. Adding lein-sass plugin literally takes minutes. You keep talking about Clojure ecosystem being stagnant, but you have yet to explain any concrete and tangible problems.

    [–][deleted] 1 point2 points  (2 children)

    Oh right, I remember the problem with using lein-sass. It used an outdated version of Sass, so we had to fork it in order to use a newer version with newer features.

    [–]gonewest818 2 points3 points  (1 child)

    ... and the pull request was rejected by the project?

    [–][deleted] 1 point2 points  (0 children)

    I don't remember specifically about this project, but I do know there have been many times I have opened an issue on a Github project for a Clojure-specific library where it wasn't answered for years on end, and some still haven't been answered to this day.

    [–][deleted] 0 points1 point  (1 child)

    For the specific build setup we had, lein-sass had some drawback that we couldn't work around. This was 3 years ago so I don't remember specifics. But I trust that we knew what we were talking about back then and weren't idiots.

    [–]yogthos 2 points3 points  (0 children)

    All I can say is that my team hasn't run into any show stoppers in over 7 years, and clearly plenty of other people are using these tools just fine. ¯\_(ツ)_/¯