10 ms·
Clojure's mini languages
- mark_l_watson 17y agoNice. I bought a MEAP of Fogus' Clojure book: I assume that all of his mini-articles will be in the book.
- fogus 17y agoI'm trying not to recycle the blog posts, but in some ways it's impossible. This specific post will not make it in, but all of the topics will be covered where applicable. Thanks for buying the MEAP; I hope you like it so far.
- peregrine 17y agoHis site has a console mode...and its pretty awesome. I've never really heard great things about "The Joy of X" books but if the books are as excellent as his blog posts I may have to chip in.
- thomas_a_berlin 17y agoI feel a bit sorry to ask but : how does one access a site in "console mode" ?
- peregrine 17y agoIn the head of the site look for this "Run This Blog In Mobile Or Console Mode..." click Console mode.
- delluminatus 17y agoHey, pretty cool. I had no idea about the (-> ... ... ) macro. I loved how F# (and Haskell) made that same thing really easy, but it turns out Clojure did too. Heh. Now if only I could get it working on Windows.
- brianobush 17y ago500 error :(
- fogus 17y agoI was playing on the server at the time... should be fine now.
- nearestneighbor 17y agoIt starts with > one of the strengths of Clojure is that it is comprised of many little mini-languages and ends with (in the comments) > I hope you do not judge the whole of Clojure by this blog post So which is it? Is this syntactic soup an achievement to be proud of or a misfeature to ignore and avoid?
- jdp 17y agoI don't see how those two statements are conflicting. He begins by saying that it is one of the (implied) multiple strengths of Clojure. He then admits that perhaps it is not for everyone, that Clojure has other features that may be more appealing to others.
- gruseom 17y agoThe language has many strengths. This is one; it is not the whole.
- nearestneighbor 17y ago"I hope you don't judge me by this strength of mine, I'm actually an OK guy" - how does that parse :-P
- swannodette 17y ago> So which is it? Is this syntactic soup an achievement to be proud of or a misfeature to ignore and avoid? Most of those things listed are neither, rather they are pragmatic and intended to improve readability. * List comprehensions need no justification. * Literal regex support also needs no justification. * Syntax quote needs no justification. * Literal numerics need no justification. Stuff you might not use: * pre/post conditions * gen-class I hardly consider ns a mini-language any more than I consider any language's import syntax a mini-language but that's me. So we're left with #() and ->, ->>. #() is often abused. It's really meant for things like this: (map #(* % 3) (range 100)) ; vs. (map (fn [x] (* x 3)) (range 100)) It's intended to improve readability when used properly. This the purpose of -> and ->> as well. People often complain that Lisp code needs to be read inside out. (+ (* (/ x 2) 3) 5)) ; vs. (-> x (/ 2) (* 3) (+ 5)) Again a readability win, not loss.
- ekiru 17y agoI don't really understand how the Clojure syntax-quote somehow prevents name-capturing any more than that of Common Lisp does(except for the foo# gensym shortcut). The Common Lisp backquote automatically qualifies symbols in the current package. In fact, the Common Lisp reader does that for all symbols used without a qualified namespace. It would be terribly painful to write in any language with a mandatory package system which could not infer the package to which a symbol belongs in this way. What makes Clojure's backquote so much more resilient against variable capture than Common Lisp's?
- apgwoz 17y agoI've often wondered this. Last week rich hickey mentioned this at clojure NYC, and they only things he mentioned were the fully qualifying namespaces (which resolves to the original package it was defined in) and the auto gensyms. I assume this is enough in most cases and the auto gensyms take care of the rest. I don't think I'd trust namespace rewriting by itself though.
- fogus 17y agoRight, and one without the other doesn't do the trick. You need both auto-gensyms and namespace resolution to ensure hygiene in Clojure macros (cleanly at least). On the other hand as lg mentioned you can intentionally capture using the pattern described. So you get the best of both worlds with the stipulation that the case of intentional capture is a bit more cumbersome.
- lg 17y agoCL-USER> (progn (defmacro foo () `(let ((bar 1)) bar)) (foo)) 1 user=> (do (defmacro foo [] `(let [bar 1] bar)) (foo)) java.lang.Exception: Can't let qualified name: clojure.core/bar EDIT: sorry if that was cryptic, see Lisp will let you say (let ((cl-user::bar 1)) cl-user::bar) but clojure won't let you do (let [clojure.core/bar 1] clojure.core/bar) You can't use fully-qualified names that way. So namespace resolution in expansions prevents capture. If you really want capture, you can do ~'bar to protect it from resolution. Well I hope that's still true, lotrepls doesn't seem to like it :(
- projectileboy 17y agoI realize this has nothing to do with the content of your post, but your blog has the best title of all time.