Last active
March 21, 2016 23:10
-
-
Save rwilson/b04a57784ddbe060a227 to your computer and use it in GitHub Desktop.
Clojure: when to use the var macro?
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
;;; I went looking for details on when it is appropriate to use the var macro (#’). | |
;; Here are a couple functions to set the context: | |
(defn something [fn x] (fn x)) | |
(defn cube [x] (* x x x)) | |
;; Now, a repl stack to demonstrate: | |
foo.core=> (something cube 4) | |
64 | |
foo.core=> (something #'cube 4) | |
64 | |
;;; Assuming that rarely are there "redundant" behaviors without purpose, I got wondering when | |
;;; it was appropriate to use one form vs the other. So, here’s some info: | |
;;; | |
;;; #’ is the var macro, same as (var x), and “When used it will attempt to return the referenced var. | |
;;; This is useful when you want to talk about the reference/declaration instead of the value it represents.” | |
;;; Quote from this great article: http://yobriefca.se/blog/2014/05/19/the-weird-and-wonderful-characters-of-clojure/ | |
;; It can be seen with: | |
foo.core=> cube | |
#<core$cube foo.core$cube@1fa547d1> | |
foo.core=> #'cube | |
#'foo.core/cube | |
foo.core=> @#'cube | |
#<core$cube foo.core$cube@1fa547d1> | |
;;; The first form resolves the value from the var directly | |
;;; The second form, resolves the symbol “cube” to the Var #'foo.core/cube | |
;;; The third form, while being obviously redundant, explicitly resolves the symbol “cube” | |
;;; to the Var #'foo.core/cube, and then dereferences it to get the value | |
;;; | |
;;; This is interesting because of its implications when passing functions as arguments to other functions. | |
;;; If passed as (some-fn some-arg-fn), then the value of some-arg-fn, as resolved at the time some-fn is called, | |
;;; is passed to some-fn. | |
;;; | |
;;; That’s interesting, because by the time some-fn does anything with that argument it receives, it’s possible that | |
;;; the actual value of some-arg-fn elsewhere could be different. Because the Var some-arg-fn wasn’t passed. The dereferenced | |
;;; value of the Var some-arg-fn was passed. | |
;;; On the other hand, if called as (some-fn #'some-arg-fn), then the Var is actually passed, meaning that the value arrived at | |
;;; by dereferencing some-arg-fn won’t be determined until some-fn actually does the dereferencing. | |
;;; A more detailed explanation is in this Stack Overflow answer: http://stackoverflow.com/a/9115958/302092 | |
;;; It contains a good explanation about getting from ns -> symbol -> var -> value |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment