I know that in Clojure, namespaces map symbols to Vars. So we can map the symbol x to a Var (here in the default namespace) like this:
user=> (def x 5)
#'user/x
user=> #'x
#'user/x
user=> (type #'x)
clojure.lang.Var
user=> x
5
Now if I subsequently say this
user=> (def x 3)
#'user/x
Have I rebound the symbol x to a brand new Var or have I updated the value in the same Var I created above? How would I know?
I'm thinking it's the latter because I read the sentence "Only Java fields, Vars, Refs and Agents are mutable in Clojure." in the Clojure Reference page on Vars but I'm not sure that holds as a proof.
No, def does not always create a new Var. You can confirm this using identical?:
user=> (def x 5)
#'user/x
user=> (def v #'x)
#'user/v
user=> (def x 3)
#'user/x
user=> (identical? v #'x)
true
Elogent's answer is excellent and accepted, but I just found another way to prove that a new var is not created, which might be of use:
user=> (def x 10)
#'user/x
user=> (let [y #'x] (println #y) (def x 7) (println #y))
10
7
nil
If def did create a new var, we would have seen 10 printed twice.
Related
Quoting from the (1975) Maclisp Reference Manual: "Each atomic symbol has associated with it a property-list, which can be retrieved with the plist function."
A Maclisp property-list was a list of 'indicator/value' pairs. In Maclisp,
(get x y)
gets x's y-property.
(putprop x 'banana y)
sets x's y-property to banana.
I am tasked with converting a lot of old Maclisp code into Clojure. I am new to Clojure but won't be for long as this project unfolds. Before I run off and write something myself, I'm wondering if Clojure already has a "property list" feature? Or something close?
And if not, what would the assembled Clojure gods have me do to implement such a feature? Remember, every atomic symbol in Maclisp can but does not have to have a property-list. Thank you.
clojure has metadata maps associated with variables / data values:
user> (def x [1 2 3])
#'user/x
user> (reset-meta! #'x {:my-data 1})
;;=> {:my-data 1}
notice that this metadata is associated with variable, not with variable bound data
user> (-> x var meta)
{:my-data 1}
user> (-> #'x meta) ;; short form
{:my-data 1}
user> (-> x meta)
nil
otherwise you can attach it to the value itself:
user> (def x ^{:some-data 101} [1 2 3])
#'user/x
user> (meta x)
{:some-data 101}
depending on how do you want to use it.
What is the difference between def and defonce in Clojure?
When to use def over defonce or vice versa?
defonce is skipped when variable is already defined.
user> (def a 1) ;;=> #'user/a
user> a ;;=> 1
user> (def a 2) ;;=> #'user/a
user> a ;;=> 2
user> (defonce b 1) ;;=> #'user/b
user> b ;;=> 1
user> (defonce b 2) ;;=> nil
user> b ;;=> 1
Defonce only binds the name to the root value if the name has no root value.
For example, like Jay Fields blogs about, it can be used in conjunction when you want to reload namespaces but you might not need to reload all.
(defonce ignored-namespaces (atom #{}))
(defn reload-all []
(doseq [n (remove (comp #ignored-namespaces ns-name) (all-ns))]
(require (ns-name n) :reload )))
As for when to use defonce, if you're using system with hot reloading (CLJS with mount and re-frame for example), defonce is useful to keep the state between reloads.
Similar situation when you re-evaluate source file yourself (e.g. in REPL) but want to keep the value of the var bound to the symbol.
I have a question regarding how to define functions/macros which call other macros or special forms but where one of the symbols passed in needs to be dynamic.
The simplest version of this question is described below:
We can define variables using def
(def x 0)
But what if we wanted the name x to be determined programmatically so that we could do the equivalent of?
(let [a 'b]
(our-def a 3)) => user/b
We could try to define a function
(defn defn2 [sym val]
(def sym val))
However it does not do what we want
(def2 'y 1) => #'user/sym
At first it seems like a macro works (even though it seems like it would be unnecessary)
(defmacro def3 [sym val]
`(def ~sym ~val))
(def3 z 2) => user/z
but it is just superficial, because we're really right back where we started with regular def.
(let [a 'b]
(def3 a 3)) => user/a
I can do it if I use eval, but it doesn't seem like eval should be necessary
(defn def4 [sym val]
(eval `(def ~sym ~val)))
(let [a 'b]
(def4 a 4)) => user/b
If there are other built-in commands that could achieve this particular example, they are not really what I am looking for since def is just to show a particular example. There are macros more complicated than def that I might want to call and not have to worry about how they were internally implemented.
First: The right way to do this is to use macro that starts with def... since this is the way people have been doing defs and is of little surprise to the user.
To answer you question: Use intern:
(def foo 'bar)
(intern *ns* foo :hi)
(pr bar) ;; => :hi
(intern *ns* foo :hi2)
(pr bar) ;; => :hi2
If you want to use macros do this:
(def z 'aa)
(defmacro def3 [sym val]
`(def ~(eval sym) ~val))
(def3 z 2)
(pr aa) ;; => 2
Leonardo Borges has put together a fantastic presentation on Monads in Clojure. In it he describes the reader monad in Clojure using the following code:
;; Reader Monad
(def reader-m
{:return (fn [a]
(fn [_] a))
:bind (fn [m k]
(fn [r]
((k (m r)) r)))})
(defn ask [] identity)
(defn asks [f]
(fn [env]
(f env)))
(defn connect-to-db []
(do-m reader-m
[db-uri (asks :db-uri)]
(prn (format "Connected to db at %s" db-uri))))
(defn connect-to-api []
(do-m reader-m
[api-key (asks :api-key)
env (ask)]
(prn (format "Connected to api with key %s" api-key))))
(defn run-app []
(do-m reader-m
[_ (connect-to-db)
_ (connect-to-api)]
(prn "Done.")))
((run-app) {:db-uri "user:passwd#host/dbname" :api-key "AF167"})
;; "Connected to db at user:passwd#host/dbname"
;; "Connected to api with key AF167"
;; "Done."
The benefit of this is that you're reading values from the environment in a purely functional way.
But this approach looks very similar to the partial function in Clojure. Consider the following code:
user=> (def hundred-times (partial * 100))
#'user/hundred-times
user=> (hundred-times 5)
500
user=> (hundred-times 4 5 6)
12000
My question is: What is the difference between the reader monad and a partial function in Clojure?
The reader monad is a set of rules we can apply to cleanly compose readers. You could use partial to make a reader, but it doesn't really give us a way to put them together.
For example, say you wanted a reader that doubled the value it read. You might use partial to define it:
(def doubler
(partial * 2))
You might also want a reader that added one to whatever value it read:
(def plus-oner
(partial + 1))
Now, suppose you wanted to combine these guys in a single reader that adds their results. You'll probably end up with something like this:
(defn super-reader
[env]
(let [x (doubler env)
y (plus-oner env)]
(+ x y)))
Notice that you have to explicitly forward the environment to those readers. Total bummer, right? Using the rules provided by the reader monad, we can get much cleaner composition:
(def super-reader
(do-m reader-m
[x doubler
y plus-oner]
(+ x y)))
You can use partial to "do" the reader monad. Turn let into a do-reader by doing syntactic transformation on let with partial application of the environment on the right-hand side.
(defmacro do-reader
[bindings & body]
(let [env (gensym 'env_)
partial-env (fn [f] (list `(partial ~f ~env)))
bindings* (mapv #(%1 %2) (cycle [identity partial-env]) bindings)]
`(fn [~env] (let ~bindings* ~#body))))
Then do-reader is to the reader monad as let is to the identity monad (relationship discussed here).
Indeed, since only the "do notation" application of the reader monad was used in Beyamor's answer to your reader monad in Clojure question, the same examples will work as is with m/domonad Reader replaced with do-reader as above.
But, for the sake of variety I'll modify the first example to be just a bit more Clojurish with the environment map and take advantage of the fact that keywords can act as functions.
(def sample-bindings {:count 3, :one 1, :b 2})
(def ask identity)
(def calc-is-count-correct?
(do-reader [binding-count :count
bindings ask]
(= binding-count (count bindings))))
(calc-is-count-correct? sample-bindings)
;=> true
Second example
(defn local [modify reader] (comp reader modify))
(def calc-content-len
(do-reader [content ask]
(count content)))
(def calc-modified-content-len
(local #(str "Prefix " %) calc-content-len))
(calc-content-len "12345")
;=> 5
(calc-modified-content-len "12345")
;=> 12
Note since we built on let, we still have destructing at our disposal. Silly example:
(def example1
(do-reader [a :foo
b :bar]
(+ a b)))
(example1 {:foo 2 :bar 40 :baz 800})
;=> 42
(def example2
(do-reader [[a b] (juxt :foo :bar)]
(+ a b)))
(example2 {:foo 2 :bar 40 :baz 800})
;=> 42
So, in Clojure, you can indeed get the functionality of the do notation of reader monad without introducing monads proper. Analagous to doing a ReaderT transform on the identity monad, we can do a syntactic transformation on let. As you surmised, one way to do so is with partial application of the environment.
Perhaps more Clojurish would be to define a reader-> and reader->> to syntactically insert the environment as the second and last argument respectively. I'll leave those as an exercise for the reader for now.
One take-away from this is that while types and type-classes in Haskell have a lot of benefits and the monad structure is a useful idea, not having the constraints of the type system in Clojure allows us to treat data and programs in the same way and do arbitrary transformations to our programs to implement syntax and control as we see fit.
Basically...
=> (atom? 5)
CompilerException java.lang.RuntimeException: Unable to resolve symbol: atom? in this context, compiling:(NO_SOURCE_PATH:1)
=> (atom? /a)
RuntimeException Invalid token: /a clojure.lang.Util.runtimeException (Util.java:156)
RuntimeException Unmatched delimiter: ) clojure.lang.Util.runtimeException (Util.java:156)
=> (atom? "hello world")
CompilerException java.lang.RuntimeException: Unable to resolve symbol: atom? in this context, compiling:(NO_SOURCE_PATH:1)
So does anyone know what's happening??
I am using Eclipse Juno 4.2, the CounterClockwise plugin.
What's called an atom in Clojure is something completely different than what's called an atom in other Lisps. In classic Lisp an atom is a single value, defined as being not null or not a cons cell (pair):
(define (atom? x)
(not (or (pair? x)
(null? x ))))
In Clojure an atom is a concurrency reference type. Atoms in Clojure can be either single-valued or collections/sequences, where updating (mutable state change) is guaranteed to happen atomically.
In Clojure there's far more reference types than the cons list in Lisp, and there's all the Java interop collection types to be reckoned with. That makes it hard to define a check on single-values.
If you do want to, the simplest check is to see if something can be counted. Looking at (source counted), it references clojure.lang.RT/count and countFrom. There, several classes / interfaces are specified, which I included in the following function:
=> (defn single-valued?
[x]
(not (or (nil? x)
(.. x getClass isArray)
(some #(instance? % x) [clojure.lang.Counted
clojure.lang.IPersistentCollection
java.util.Collection
java.util.Map]))))
=> (map single-valued? [1 "foo" \a 'x true not nil])
(true true true true true true false)
=> (map single-valued? ['(1 2 3 4)
[1 2 3 4]
{:a 1 :b 2}
#{1 2 3 4}
(seq [1 2 3 4])
(seq {:a 1 :b 2})
(seq "foo")
(int-array [1 2 3 4])
(seq [])])
(false false false false false false false false false)
Since (seq []) evaluates to nil it's not considered single-valued. Of course, java objects with multiple fields, as well as Clojure deftypes / defrecords will register as such, even though they're composite objects.
I suspect you are confusing a clojure atom with an atom in something like scheme.
In scheme an atom is a fundamental unit.
In clojure an atom is one of clojure's reference types (like ref and var) that can be updated atomically.
This fits nicely with clojure's concurrency model.
e.g.
user> (def a (atom '(1 2 3)]); create an atom with value (1 2 3)
user> #a ; look up (deference) the atoms value
(1 2 3)
user> (swap! a (fn [v] (map inc v))) ; add 1 to each element, v is the
; old value of the atom. other threads will
; see the three values in a change atomically
user> #a
(2 3 4)
user> (reset! a '(5 10 15))
user> #a
(5 10 15)
atom? is not a function.
You could use
(def x (atom 5))
(instance? clojure.lang.Atom x)
You can create atom? function like this:
(defn atom? [x]
(not (coll? x))
)
The complement function returns the opposite of any predicate passed to it as argument, so you can make a atom? with it:
(defn atom?
[x]
((complement coll?) x))
(atom? []) ;=> false
(atom? ()) ;=> false
(atom? {}) ;=> false
(atom? 4) ;=> true