4 ms·
First rule of macros is: do not write macros. At least in clojure, it's rare that I stumble upon macros in the wild. But when they're needed (someone else wrote
by monsieurbanana 6y ago
First rule of macros is: do not write macros. At least in clojure, it's rare that I stumble upon macros in the wild. But when they're needed (someone else wrote about core.async in this thread) they are very useful.
After one year of clojure, it's annoying for me to read classic C-like languages. There's also people who prefer reading code without syntax color, so clearly this is a subjective matter.
I find clojure tooling really good, and it's hard to go back to a non-repl oriented workflow (this is not at all the same as something like python or javascript repl). But this is admittedly a gray area, there's areas where it's immature compared to other languages, and others where it shines because of it's repl-oriented nature.
The lack of typing is certainly a sound argument, although my personal opinion is that for many use cases it isn't required. This is going to be a contentious opinion, I'm sure.
Note that clojure has an advantage on this over other dynamic languages: idiomatic clojure code means that pretty much everything is pure data, in basic structures: maps and vectors. So the functions that you use to operate on your data are always the same. Over time you'll learn them, and they won't change between domains nearly as much as, say, if you were coding in OOP oriented python.
- mythz 6y agoI've also spent a bit of time with LISPs, when learning Clojure I ported the Clojure 101 LINQ Examples [1] and did appreciate a lot of niceties that Clojure brings with it where the additional syntax actually added to its readability, e.g. the usage of vector syntax for function params provided a welcomed visual separator from its implementation body. Basically all its additional syntax improves readability over a LISP's typical clumped sea of parens where you can more quickly discern different constructs from a glance which would otherwise take me a lot more time & effort trying to determine the boundaries of each expression whilst evaluating them in my head, effectively conveying that the minimal s-expression syntax that's optimal for the compiler isn't optimal for humans. So when it came time to implementing a .NET LISP [2], I adopted much of Clojure's additional syntax for improved readability & interop with .NET APIs [3]. But you can only improve LISP's syntax so far, e.g. its Template libraries for HTML generation [4] make for horrible HTML DSL's which looks nothing like the HTML it's supposed to generate. The solution to overcome this was basically to not to use LISP for templates, instead create a multi-language scripting language [5] that embeds lisp into it allowing it to Combine strength's of all languages [6], e.g. use LISP for algorithms and Handlebars / JS Expressions for templating. The REPL is definitely one of its super powers which is one areas where it shines & basically the primary use-case where I still use it. I've created a live "watch" mode & deep integration with .NET libs that I use for discovery, e.g. run DB queries, call HTTP APIs, execute shell scripts, etc. [7]. It especially shines for being able to open a REPL session with a remote production .NET instance letting me inspect its live running state & invoke system functionality like querying its configured RDBMS, executing redis commands, send tweets, emails, etc [8], I've even got it to Live Script Unity objects in-game :) [9], which speaks to the power & elegance of LISP that's able to achieve so much with so little code. At the same time I don't think REPL-based programming is all that useful during normal development, you can execute encapsulated code fragments fine, but most of the time I'll need my whole environment constructed before being able to inspect it as I would when debugging, so I find it useful for opening a REPL session into a live running instance, but not using the REPL to construct the live instance. So for my dev workflow, static analysis & typing, great IDE, tooling + debugging is a lot more useful. [1] https://github.com/mythz/clojure-linq-examples https://github.com/mythz/clojure-linq-examples [2] https://sharpscript.net/lisp/ https://sharpscript.net/lisp/ [3] https://sharpscript.net/lisp/#net-interop https://sharpscript.net/lisp/#net-interop [4] https://www.cliki.net/HTML%20template https://www.cliki.net/HTML%20template [5] https://sharpscript.net/docs/syntax#language-block-modifiers https://sharpscript.net/docs/syntax#language-block-modifiers [6] https://sharpscript.net/docs/syntax#combine-strengths-of-all-languages https://sharpscript.net/docs/syntax#combine-strengths-of-all... [7] https://sharpscript.net/lisp/#run-and-watch-lisp-scripts https://sharpscript.net/lisp/#run-and-watch-lisp-scripts [8] https://sharpscript.net/lisp/#techstacks-tcp-lisp-repl-demo https://sharpscript.net/lisp/#techstacks-tcp-lisp-repl-demo [9] https://sharpscript.net/lisp/unity https://sharpscript.net/lisp/unity