4 ms·
The Weird and Wonderful Characters of Clojure
- moomin 12y agoFun article. Should also add in #anything, and discover the weird and wonderful world of the extensible reader.
- yobriefcase 12y agoIf you can link me to some examples of this I'll be happy to add them. (edit) I have a comment around the fact user defined reader macros are not supported in Clojure (save for a hack). Is this not the case anymore?
- emidln 12y agoI think this is referring to the ability to the tagged literals api (set data-readers[1] and change/extend the various literal notations already provided by clojure (like #uuid and #inst)). The docs seem to believe that unqualified var names are reserved and you should fully-qualify your tags, but this seems to be more of a suggestion than a requirement. [1][2] *data-readers* [2] http://clojure.github.io/clojure/clojure.core-api.html#clojure.core/*data-readers* http://clojure.github.io/clojure/clojure.core-api.html#cloju...
- Totient 12y agoI don't understand the difference between fn and fn* . After some brief experimenting in the REPL, they seem to behave exactly the same, the only difference being that fn* is what comes out of macro expanding the #( macro Is there a reason that the #( macro doesn't expand to plain old fn?
- MBlume 12y agofn is a macro that knows how to apply destructuring rules, fn* is a primitive read by the clojure compiler and cannot apply destructuring rules. https://github.com/clojure/clojure/blob/master/src/clj/clojure/core.clj#L4143 https://github.com/clojure/clojure/blob/master/src/clj/cloju...
- diego 12y agofn itself is a macro, fn* is a symbol defined at the compiler level: static final Symbol FN = Symbol.intern("fn*");
- emidln 12y agoI've been using Clojure for awhile now and it has never previously occurred to me that you could do: #(foo %2) instead of (fn [_ arg2] (foo arg2)) Thanks!
- yobriefcase 12y agoNeither did I until I started writing about #( and decided to see what would happen. The joys of being nosey.
- da02 12y agoNosey? Or maybe "curious"? Explorer? Pioneer? Either way, thanks for writing about it.
- moomin 12y agoObviously, bear in mind that (comp foo second) may be preferable.
- weavejester 12y agoSlightly different use-case, as: (comp foo second) Is equivalent to: (fn [[_ x]] (foo x)) Not: (fn [_ x] (foo x))
- ar7hur 12y ago+1. How about: (comp foo second list)
- programnature 12y agoThe characters are hard to google, but I've found them sufficiently documented here: http://clojure.org/reader http://clojure.org/reader
- eudox 12y agoAnd here's how to use Common Lisp reader macros to implement JSON literals: https://gist.github.com/chaitanyagupta/9324402 https://gist.github.com/chaitanyagupta/9324402
- jcromartie 12y agoDoes the author mean "character" in a literary sense? Because many of these things have better names, and in fact "character" is wholly incorrect for anything like "#_" or "#'" which consist of multiple characters. Also, functions are not methods, and the terms are not interchangeable. All of this is summarized in a much more succinct and correct fashion here: http://clojure.org/reader http://clojure.org/reader
- masklinn 12y ago> and in fact "character" is wholly incorrect for anything like "#_" or "#'" which consist of multiple characters. #_ is a character for the dispatch invocation, and a dispatch character. The way it's used in TFA is perfectly understandable. > All of this is summarized in a much more succinct and correct fashion here: http://clojure.org/reader http://clojure.org/reader Which uses the word "character" to describe them. And gives no examples, so it may be more succinct but is also of very limited use to people who have no idea what this is about. Those who know what it's about are not going to google for macro characters.
- jcromartie 12y agoThe word "character" is used to describe them because they are certainly made of characters. The most generic term for everything but the macro characters themselves is "form". The dispatch macro is a special case that is not a form, but represents reader macros that are applied to forms as they are read. Same goes for quoting. But all of the specific cases of #_ or #{ or #" etc. are more than just characters. And the docs do in fact give plenty of examples. I'm not sure how you can say "no examples" when there are examples for most of the things described on the page. It may be dense, but the writing is clear and you can just read it start to finish. EDIT: I see what you mean about "macro characters". Just to be as clear as possible: # - a macro character which dispatches on the next character #{:foo :bar} - a hash-set literal form #(...) - an anonymous function literal form ' - the quote character 'foo - a quoted symbol form -> - the threading macro (just a normal symbol) (-> x inc str) - a form using the threading macro
- 12y ago
- BostX 12y agoA big Thanx for this!
- kivikakk 12y agoIt seems disingenuous to describe ";" as a "comment macro". It's not a macro, it just causes the reader to ignore characters until EOF, \r, or \n. (https://github.com/clojure/clojure/blob/master/src/jvm/clojure/lang/LispReader.java#L505 https://github.com/clojure/clojure/blob/master/src/jvm/cloju...) The fact that the CommentReader is dispatched from a table called "macros" (https://github.com/clojure/clojure/blob/master/src/jvm/clojure/lang/LispReader.java#L84 https://github.com/clojure/clojure/blob/master/src/jvm/cloju...) means nothing, unless you also call string literals "string macros", s-expressions "s-exp macros", etc., since mostly everything is dispatched from that table.