Var quote (#’) demystified
2025-01-03
require '[ring.adapter.jetty :refer [run-jetty]])
(
defn handler [_req] {:status 200 :body "plop"})
(
#'handler {:port 4321 :join? false}) (run-jetty
#'handler
is equivalent to (var handler)
which returns the var bound to the symbol handler
instead
of the value inside that var.
This "var quoting" makes Jetty invoke the last def
ed
value of handler
. It works because a Clojure var can
be invoked, and it will in turn try to invoke the value it currently
holds.
A clojure var is also Callable
and
Runnable
:
import '(java.util.concurrent Executors ExecutorService))
(require '[clojure.test :refer [deftest is]])
(
defn f [] :plop)
(
deftest vars-are-polyvalent
(with-open [exec (Executors/newVirtualThreadPerTaskExecutor)]
(is (= nil (.get (^[Runnable] ExecutorService/.submit exec #'f))))
(is (= :plop (.get (^[Callable] ExecutorService/.submit exec #'f)))))) (
There are functions that expects a var as input, but I have not encountered many of them:
#'vars-are-polyvalent) (clojure.test/run-test-var
To dig deeper into the subject of functions and vars, I have enjoyed this article by Aaron Lahey: 8thlight.com/insights/the-relationship-between-clojure-functions-symbols-vars-and-namespaces.
Bonus: how to make a StackOverflowError with a var
with-local-vars [a :unused-value]
(var-set a a)
( (a))