6 ms·
Excellent tips. I'd advise most inexperienced programmers (say under 10 years of lisp) to stick to tip #1. You very rarely need a macro in Clojure.
by jwr 11y ago
Excellent tips. I'd advise most inexperienced programmers (say under 10 years of lisp) to stick to tip #1. You very rarely need a macro in Clojure.
- cageface 11y agoIf it's true that you rarely need macros then isn't the awkwardness of s-expr syntax a very high price to pay just to have access to them?
- aaron-santos 11y agoSure. The syntax is distracting at first, but in my experience after a few weeks I saw past it. It's a non-issue for me at this point and I dearly miss it when writing Scala on another project.
- nilliams 11y agoWhat aspect do you dearly miss? (Honest question, I've never understood the S-expr trade-off, especially if macros are off the table).
- pka 11y agoProbably paredit. It's really so much better than non-structured editing. That said, there are structured editing plugins/modes/editors for other languages too. However, looking back at Lisp/Clojure now I really don't like the syntax anymore. I don't care about the brackets, it's absolutely true that you learn to look past them in a matter of days, but the homogeneity and the "denselesness" really impact my ability to quickly parse an expression. Infix syntaxes make reading code much easier, imo.
- roboguy12 11y agoI thought that at first too about infixes being better (I've only been using Clojure for a few months), but I'm beginning to find the opposite. The only times when I miss an infix syntax is when doing math 1 + (2 * 10) - (12 / 3) is so much easier for me to read to read than (- (+ 1 (* 2 10) (/ 12 3))) But when working with functions, I much prefer the standard Clojure syntax.
- malloryerik 11y agoI believe the parens are off by one in the Clojure example and that it should be: (- (+ 1 (* 2 10)) (/ 12 3)) ;=> 17 I've found the threading operator can help in these cases. (-> (+ 1) (+ (* 2 10) (- (/ 12 3)))) Or, line breaks can clarify: (- (+ 1 (* 2 10)) (/ 12 3)) or at the risk of overdoing it: (- (+ 1 (* 2 10)) (/ 12 3)) Now I know at first glance that I'm subtracting the results of those two lines from each other. Indeed the last two might be almost as clear as the infix, and are without any order of operations rules. Also some don't like colored parens but I find them very clarifying.
- pka 11y agoI have to disagree. f x . g reads just so much easier than (comp (partial f x) g)
- d_t_w 11y agoStructural editing, paredit, 100%. I say that not being particularly accomplished with it. 15 years of programming Java, now 3 in Clojure, would dearly miss slurp and barf, the lesser appreciated virtues of homoiconicity.
- aaron-santos 11y agoI took some time to think about this because it started off as a feeling and not a list of reasons. For me it's mostly centered around control structures - if, for, switch, case (scala's pattern matching). Clojure's control structures are syntactically composed of ()'s and []'s. Scala's aren't. They are a coded into the language's grammar[1][2]. Clojure's ns forms parallel Scala's package and import statements, but are again Clojure's are syntactically composed of ()'s and []'s. I know it's a relatively small point, but control structures make up a significant portion of programs. As a side note, I took a look at a Clojure grammar also specified for antlr[3]. My initial thought would be that Clojure's grammar would be appreciably smaller. It is, but not by as much as I was expecting. There are a lot of very little additions to the reader that add up [4][5][6]. [1] - Scala's syntax http://www.scala-lang.org/files/archive/spec/2.11/13-syntax-summary.html http://www.scala-lang.org/files/archive/spec/2.11/13-syntax-... [2] - Examples https://github.com/lrlucena/grammars-v4/blob/master/scala/scala.g4#L96 https://github.com/lrlucena/grammars-v4/blob/master/scala/sc... [3] - https://github.com/laurentpetit/ccw/blob/3738a4fd768bcb0399630b7f6a6427a3066bdaa9/clojure-antlr-grammar/src/Clojure.g https://github.com/laurentpetit/ccw/blob/3738a4fd768bcb03996... [4] - http://clojure.org/reference/reader#macrochars http://clojure.org/reference/reader#macrochars [5] - https://yobriefca.se/blog/2014/05/19/the-weird-and-wonderful-characters-of-clojure/ https://yobriefca.se/blog/2014/05/19/the-weird-and-wonderful... [6] - See "Special Characters" http://clojure.org/api/cheatsheet http://clojure.org/api/cheatsheet
- jdminhbg 11y agoI'd say it's more true that you rarely need to write a macro than it is that you rarely need to use them. Lots of very useful things across the language, from builtins like the threading macros (->, ->>) to libaries like Compojure, are built on macros.
- bkirkbri 11y agoI've found s-expressions to be one of my favorite things about Clojure. I understand that many people dislike them, and that many people get used to them, but I loved the syntax from the get go.
- reitzensteinm 11y agoI have a pet theory that someone will put a Python skin on Clojure and have significant success with it.
- SapphireSun 11y agoYou can't. The reason you can use macros so easily in LISP is because of homoiconicity: https://en.wikipedia.org/wiki/Homoiconicity https://en.wikipedia.org/wiki/Homoiconicity Your macros will break all over the place in languages that don't have this property.
- e12e 11y agoSRFI-110 says you can^1: "Sweet-expressions are general and homoiconic, and thus can be easily used with other constructs such as quasiquoting and macros. In short, if a capability can be accessed using s-expressions, then they can be accessed using sweet-expressions. Unlike Python, the notation is exactly the same in a REPL and a file, so people can switch between a REPL and files without issues. Fundamentally, sweet-expressions define a few additional abbreviations for s-expressions, in much the same way that 'x is an abbreviation for (quote x)." http://srfi.schemers.org/srfi-110/srfi-110.html#wisp http://srfi.schemers.org/srfi-110/srfi-110.html#wisp ^1 [ed: well, not "just python syntax", but if you wanted that, you would be better off using python. But python-like syntax/skin is absolutely doable. ]
- SapphireSun 11y agoThanks, I learned something today. :)
- pjmlp 11y agoDylan also has macros.
- groovy2shoes 11y agoAs does Rust.
- andrewingram 11y agoThis is interesting, but also a little discouraging. Coming from a background of Python and JavaScript, and using a little bit of Elixir (which also supports macros) lately, the power of macros for defining DSLs is the main draw for me. As an example, I've been using GraphQL quite heavily for the last 8 months, primarily with JavaScript and i've found it to be a fairly tedious experience. I tried out an Elixir GraphQL library that's heavily based on macros and was almost immediately more productive - despite not even knowing the language. Similarly, coming up with a nice API for working with forms seems to be pretty much impossible with JavaScript. I've evaluated dozens, and not one comes close to the simplicity of Django's forms (which is only possible thanks to Python's metaclass magic). Having sampled the power of languages with macros, I'm naturally drawn to Clojure, simply because it has a very decent JavaScript implementation. I'm sure there are other very good reasons for using the language, but right now macros are the motivation. I'd like to understand why one would need 10 years of lisp experience before starting to author their own macros, it feels like a philosophy that's just going to stop people trying out lisp.
- asimuvPR 11y agoIt's OK to be discouraging to a certain degree. It helps stop people from cooking up "clever" solutions.
- andrewingram 11y agoWell I try to use the right tool for the job, and it's important that code can be understood easily when it's read by other developers. But I think the 10 years with Lisp argument needs to be better justified. :)
- asimuvPR 11y agoOh, I was not making a personal comment about you. It was a comment in your first point. That being discouraged by others is a sign that one should thread lightly. I was not discouraged by anyone when macros appeared on my horizon. And boy did I write some bad code. :)
- jcadam 11y agoI've recently (about two weeks ago) picked up Clojure for use on a side project after getting frustrated with trying to use Haskell for something non-trivial -- not smart enough for Haskell, apparently :D Haven't messed with a LISP language since college but clojure has grown on me considerably. I already like it more than Scala... though I did almost immediately find myself reaching for a monad library (cats seems good so far) :) Haven't felt the need to write my own macros yet, but certainly many of the libraries I'm using (compojure) make heavy use of them. Too bad my day job is all Java, all the time :( My continual requests to use Scala have been shot down over the last couple of years -- "We want something maintainable, where am I going to find Scala devs when you leave?" So obviously Clojure isn't going to fly :)
- spion 11y agoThat seems off by about 1 order of magnitude...
- AimHere 11y agoLisp is getting on a bit, but even the greyest of Lisp hackers haven't quite racked up a hundred years of Lisp...