Hacker News new | ask | show | jobs
by lgessler 2985 days ago
Looking at this as someone who's been writing a lot of ClojureScript lately, I'm reminded of how nice it is to be writing in a Lisp: if I felt this was the right syntactic construct for a common-enough problem in my codebase, I'd write a macro for it and get on with my life without having to wait for it to trickle through committees, compilers, and browser implementations.
4 comments

And the next person to maintain your codebase would be grateful for your choice and insight, I'm sure.

Permissiveness is good for small projects but it can feel like getting into a suit tailored specifically for everyone else as projects get bigger.

I don't think this snarky remark is warranted. I think the point was that in Lisp-style languages (such as Clojure/ClojureScript) new features such as pattern matching can easily be added without "changing the language", as libraries. This is how core.async was added to Clojure, to pick a non-trivial example. Or more to the point, how core.match works.

Additions such as those do not have to be one lonely programmer's macros, they can be libraries widely accepted by the community.

I had a similar thought when reading the ECMAscript extension proposal: I'm glad that in the languages I use, features like that can be provided by libraries.

Yes, but I think the other point is well-made, as well: languages that allow this can be very difficult to work in if you have to maintain a large app with multiple contributors over a long period of time.
The same can be said for function calls, with the indirection they create hiding details of broken and side-effecting implementations.

None the less, the opposite is also true. Languages that have macro facilities can aid in writing more legible code. (See `threading` in clojure), or the `loop` macro and regular expression macros in common lisp.

Well said. Rambling Java code with little to no abstraction is its own kind of nightmare.

Some people are just terrified of any new abstractions, I guess, preferring to work with an endless series of tally marks, rather than these obfuscating “multiplication” and “exponent” complications (exaggerating to make a point - abstract != unintelligible).

I think there is probably some middle ground between "no abstraction at all" and "literally anything goes."
I did say if. Macros often aren't the right choice, but there are times when they're appropriate, and on the premise that the new syntax would be good and responsible, it's great to not have the headache of monitoring compatibility tables for 2+ years.

When you get to the scale of enterprise software, though, I'd agree with you that the best thing to do is probably not to allow any macros at all. The inevitable abuse at the hands of inexperienced developers would quickly overtake any gains from more responsible macros without perhaps some clever and/or toilsome code review processes.

Honestly I'm not sure the Javascript story here is much worse - Babel tends to allow you to opt in to proposed specs pretty early, without worrying about browser support because you're not shipping it as is.

The benefit is that your polyfill/conversion to something browsers support today is handled by someone else, and your actual code base can point a reader to the proposal to at least make some sense later on.

Not that I imagine many people would encourage using a stage 0 proposal, but it's probably a bit better than everyone writing their own adhoc implementation.

Clojure's multimethods covers all of the use cases for pattern matching and then some. I've never felt the urge to reach for pattern matching when writing in Clojure.
some-> (threading macro) and the fact that you can put an s-expression _anywhere_, these two language fundamental features alone put lisps way above c-style languages. You can laugh and continue sipping your espresso while reading the JS community bicker about syntax changes and what you are allowed to type.