What's the difference between using "def" to update a var and using "alter-var-root"?
e.g.
(def x 3)
(def x (inc x))
vs
(def x 3)
(alter-var-root #'x inc)
I find alter-var-root very rarely comes up in idiomatic Clojure code; not that there is anything wrong with it, it's just intended for corner cases. If you find yourself using it to build loops and such it's a sign something needs a different approach. I mostly see it in initialization routines for setting access credentials or loggers and such.
alter-var-root uses a function to mechanically change the value of a var while def just sets it to a new value. In your example they are equivalent.
hello.exp> (def foo 4)
#'hello.exp/foo
hello.exp> (alter-var-root #'foo inc)
5
hello.exp> foo
5
alter-var-root is also unwilling to create a new var:
hello.exp> (alter-var-root #'foo1 inc)
CompilerException java.lang.RuntimeException: Unable to resolve var: foo1 in this context, compiling:(NO_SOURCE_PATH:1)
alter-var-root can work on other namespaces as well:
hello.exp> (in-ns 'user)
#<Namespace user>
user> (alter-var-root #'hello.exp/foo inc)
6
user> (def hello.exp/foo 4)
CompilerException java.lang.RuntimeException: Can't create defs outside of current ns, compiling:(NO_SOURCE_PATH:1)
user>
This last use case is the only one I have ever needed in practice. For instance forcing clojure.logging to use the correct slf4j logger as an example from the Pallet project:
(defn force-slf4j
"The repl task brings in commons-logging, which messes up our logging
configuration. This is an attempt to restore sanity."
[]
(binding [*ns* (the-ns 'clojure.tools.logging.slf4j)]
(alter-var-root
#'clojure.tools.logging/*logger-factory*
(constantly (clojure.tools.logging.slf4j/load-factory)))))
Which is just using alter-var-root to reset a var in another namespace regardless of its content on initialization. I suppose it's a bit of a hack ...
alter-var-root provides the added value of being atomic with regards to the function application. Two (possibly concurrent) applications of (alter-var-root #'foo inc) guarantee that foo will increase by 2.
With (def x (inc x)) there is no such guarantee. It might overwrite any changes done by other threads between reading the value of x and writing its updated value.
On the other hand, if you are using alter-var-root for its atomicity then perhaps atoms are better for your use case than vars.
With def:
(def w (vector)) ; create Var named w and bind it to an empty vector
(dotimes [x 9] ; repeat 9 times (keeping iteration number in x):
(future ; execute in other thread:
(def w ; replace root binding of w with
(conj w ; a new vector with all elements from previous (w)
x)))) ; with added an element indicating current iteration (x)
w ; get a value of Var's root binding (identified by symbol w)
; => [0 2 3 6 8 7 4 5] ; 1 is missing !!!
; second thread overlapped with another thread
; during read-conjoin-update and the other thread "won"
With alter-var-root:
(def w (vector)) ; create Var named w and bind it to an empty vector
(dotimes [x 9] ; repeat 9 times (keeping iteration number in x):
(future ; execute in other thread:
(alter-var-root #'w ; atomically alter root binding of w
(fn [old] ; by applying the result of a function,
(conj ; that returns a new vector
old ; containing all elements from previous (w)
x))))) ; with added an element indicating current iteration (x)
w ; get a value of Var's root binding (identified by symbol w)
; => [1 2 4 5 3 0 7 8 6]
Related
I have 3 previous files with a function each and am trying to use comp in ex4.clj to combine all 3 but am currently getting an error about the wrong number of args being passed. I've tried using map, reduce, and filter with it but they all fail and I'm not sure how to tell which one would be desired since all functions use a different one.
ex1.clj
(defn round [input] (Math/round (double input)))
(def testList [4.7 3.3 -17 17 -5.6 -3.3 0])
(def roundedList (map round testList))
ex2.clj
(defn isDivisibleBy [factor]
(fn [number]
(def result (/ number factor))
(def roundedResult (Math/round (double result)))
(and (= result roundedResult))
)
)
(def divisibleBy2 (isDivisibleBy 2))
(def testList [2 3 4 17 3000 -3 -6 0])
(def divisibleSuccess (filter divisibleBy2 testList))
ex3.clj
(defn findMax [accum value]
(if (> accum value) accum value)
)
(def testList [2 3 4 17 3000 -3 0 -3001])
(def maxValue (reduce findMax testList))
ex4.clj (Problem file)
(load-file "ex1.clj")
(load-file "ex2.clj")
(load-file "ex3.clj")
(def testList [4.7 3.3 -17 17 -5.6 -3.3 0])
(def allThree (comp findMax divisibleBy2 round))
(def output ((map/reduce/filter) allThree testList))
(println "Original list: " testList)
(println "Highest rounded number divisible by 2: " output)
Thank you!
Your functions there are used for different jobs: one is a predicate,
you want to filter with. One is a transformation, you want to map
over. And the last one is an aggregate, you want to use as final step
(via reduce).
So you have to compose over the transformations you want to do:
((comp
(partial reduce findMax)
(partial filter divisibleBy2)
(partial map round))
testList)
If you want to do that alot, you should also have a look at
transducers, which allow
doing this without the cost of intermediate sequences.
Random style critique:
Clojure uses kebab-case and not camelCase
Never def outside of the namespace; use let instead
It's common to have a trailing ? on predicates (e.g. divisible-by-2?)
Anything wrong with the code? looks like binding doesn't work with iterate?
(def ^:dynamic *step* 1)
(defn incr [n] (+ n *step*))
(take 3 (binding [*step* 2] (iterate incr 1)))
gives
'(1 2 3)
not
'(1 3 5)
The problem is that iterate returns a lazy sequence. So, the first call to incr function occurs outside of binding scope when you're trying to print the sequence.
Technically, your incr function is not free from side-effects just because it uses ^:dynamic variable.
If you want to use binding with lazy sequences you should force the evaluation of your sequence somewhere inside of a binding scope, e.g.:
(binding [*step* 2]
(doall (take 3 (iterate incr 1))))
; => (1 3 5)
the other day I was trying to come up with an example of closure in Clojure. I came up with and example I had seen before and thought it was appropriate.
Alas, I was told it was not a good one and that I should provide something with let.
Can anyone shed some light?
(defn pow [x n] (apply * (repeat x n)))
(defn sq [y] (pow y 2))
(defn qb [y] (pow y 3))
A closure is a function that has access to some named value/variable outside its own scope, so from a higher scope surrounding the function when it was created (this excludes function arguments and local named values created within the function). Your examples do not qualify, because every function just uses named values from their own scopes.
Example:
(def foo
(let [counter (atom 0)]
(fn [] (do (swap! counter inc) #counter))))
(foo) ;;=> 1
(foo) ;;=> 2
(foo) ;;=> 3, etc
Now foo is a function that returns the value of an atom that is outside its scope. Because the function still holds a reference to that atom, the atom will not be garbage-collected as long as foo is needed.
Function that returns function i.e higher order functions are nice examples of closure.
(defn pow [n]
(fn [x] (apply * (repeat n x))))
(def sq (pow 2))
(def qb (pow 3))
Another example of closure. There are two functions that share the same environment (state).
(defn create-object [init-state]
(let [state (atom init-state)]
{:getter (fn []
#state)
:setter (fn [new-val]
(reset! state new-val))}))
(defn test-it []
(let [{:keys [setter getter]} (create-object :init-value)]
(println (getter))
(setter :new-value)
(println (getter))))
(test-it)
=> :init-value
:new-value
I wanted to have something that setup constant value(s) that are to be used each time.
(def myran
(let [constrand (rand)]
(fn [n] (* n constrand))))
(myran 3)
2.7124521745892096
(myran 1)
0.9041507248630699
(myran 3)
2.7124521745892096
This will only set a value for "constrand" once. This is a very contrived example, but I wanted to be able to do something like:
This is from: JavaScript: The Good Parts
I'd like to know how to create an infinite, impure sequence of unique values in Clojure.
(def generator ...) ; def, not defn
(take 4 generator) ; => (1 2 3 4)
(take 4 generator) ; => (5 6 7 8). note the generator's impurity.
I think that such a design could be more convenient than e.g. wrapping a single integer value into a reference type and increment it from its consumers, as:
The proposed approach reduces the implementation details to a single point of change: the generator. Otherwise all the consumers would have to care about both the reference type (atom), and the concrete function that provides the next value (inc)
Sequences can take advantage many clojure.core functions. 'Manually' building a list of ids out of an atom would be a bit bulky: (take 4 (repeatedly #(swap! _ inc)))
I couldn't come up with a working implementation. Is it possible at all?
You can wrap a lazy sequence around an impure class (like a java.util.concurrent.atomic.AtomicLong) to create an id sequence:
(def id-counter (java.util.concurrent.atomic.AtomicLong.))
(defn id-gen []
(cons
(.getAndIncrement id-counter)
(lazy-seq
(id-gen))))
This works, but only if you don't save the head of the sequence. If you create a var that captures the head:
(def id-seq (id-gen))
Then call it repeatedly, it will return ids from the beginning of the sequence, because you've held onto the head of the sequence:
(take 3 id-seq)
;; => (0 1 2)
(take 3 id-seq)
;; => (0 1 2)
(take 3 id-seq)
;; => (0 1 2)
If you re-create the sequence though, you'll get fresh values because of the impurity:
(take 3 (id-gen))
;; (3 4 5)
(take 3 (id-gen))
;; (6 7 8)
(take 3 (id-gen))
;; (9 10 11)
I only recommend doing the following for educational purposes (not production code), but you can create your own instance of ISeq which implements the impurity more directly:
(def custom-seq
(reify clojure.lang.ISeq
(first [this] (.getAndIncrement id-counter))
(next [this] (.getAndIncrement id-counter))
(cons [this thing]
(cons thing this))
(more [this] (cons
(.getAndIncrement id-counter)
this))
(count [this] (throw (RuntimeException. "count: not supported")))
(empty [this] (throw (RuntimeException. "empty: not supported")))
(equiv [this obj] (throw (RuntimeException. "equiv: not supported")))
(seq [this] this)))
(take 3 custom-seq)
;; (12 13 14)
(take 3 custom-seq)
;; (15 16 17)
I had a fun time discovering something during answering your question. The first thing that occured to me was that perhaps, for whatever ultimate goal you need these IDs for, the gensym function might be helpful.
Then, I thought "well hey, that seems to increment some impure counter to generate new IDs" and "well hey, what's in the source code for that?" Which led me to this:
(. clojure.lang.RT (nextID))
Which seems to do what you need. Cool! If you want to use it the way you suggest, then I would probably make it a function:
(defn generate-id []
(. clojure.lang.RT (nextID)))
Then you can do:
user> (repeatedly 5 generate-id)
=> (372 373 374 375 376)
I haven't yet tested whether this will produce always unique values "globally"--I'm not sure about terminology, but I'm talking about when you might be using this generate-id function from within different threads, but want to still be sure that it's producing unique values.
this is another solution, maybe:
user=> (defn positive-numbers
([] (positive-numbers 1))
([n] (cons n (lazy-seq (positive-numbers (inc n))))))
#'user/positive-numbers
user=> (take 4 (positive-numbers))
(1 2 3 4)
user=> (take 4 (positive-numbers 5))
(5 6 7 8)
A way that would be more idiomatic, thread-safe, and invites no weirdness over head references would be to use a closure over one of clojures built in mutable references. Here is a quick sample I worked up since I was having the same issue. It simply closes over a ref.
(def id-generator (let [counter (ref 0)]
(fn [] (dosync (let [cur-val #counter]
(do (alter counter + 1)
cur-val))))))
Every time you call (id-generator) you will get the next number in the sequence.
Here's another quick way:
user> (defn make-generator [& [ii init]]
(let [a (atom (or ii 0 ))
f #(swap! a inc)]
#(repeatedly f)))
#'user/make-generator
user> (def g (make-generator))
#'user/g
user> (take 3 (g))
(1 2 3)
user> (take 3 (g))
(4 5 6)
user> (take 3 (g))
(7 8 9)
This is hack but it works and it is extremely simple
; there be dragons !
(defn id-gen [n] (repeatedly n (fn [] (hash #()))))
(id-gen 3) ; (2133991908 877609209 1060288067 442239263 274390974)
Basically clojure creates an 'anonymous' function but since clojure itselfs needs a name for that, it uses uniques impure ids to avoid collitions. If you hash a unique name then you should get a unique number.
Hope it helps
Creating identifiers from an arbitrary collection of seed identifiers:
(defonce ^:private counter (volatile! 0))
(defn- next-int []
(vswap! counter inc))
(defn- char-range
[a b]
(mapv char
(range (int a) (int b))))
(defn- unique-id-gen
"Generates a sequence of unique identifiers seeded with ids sequence"
[ids]
;; Laziness ftw:
(apply concat
(iterate (fn [xs]
(for [x xs
y ids]
(str x y)))
(map str ids))))
(def inf-ids-seq (unique-id-gen (concat (char-range \a \z)
(char-range \A \Z)
(char-range \0 \9)
[\_ \-])))
(defn- new-class
"Returns an unused new classname"
[]
(nth inf-ids-seq (next-int)))
(repeatedly 10 new-class)
Demonstration:
(take 16 (unique-id-gen [\a 8 \c]))
;; => ("a" "8" "c" "aa" "a8" "ac" "8a" "88" "8c" "ca" "c8" "cc" "aaa" "aa8" "aac" "a8a")
it seem like clojure's let is sequential and would correspond to a scheme let* .
Does clojure have an unsequential binding mechanism like scheme's let?
I believe binding macro is parallel not sequential.
See: http://clojuredocs.org/clojure_core/clojure.core/binding
letfn is a parallel binding form for functions that exists to allow people to write mutually recursive local functions. It's not quite as general as you seek though it can be used in a pinch.
user> (letfn [(a [] 4)
(b [] c)
(c [] a)]
(a))
4
Binding can be used so long as you are assigning values to things in vars and want dynamic scoping
user> (def ^:dynamic x 4)
#'user/x
user> (defn foo [] x)
#'user/foo
user> (binding [x 8] (+ x (foo)))
16 ; the value of x that gets called by foo is modified by the caller
; yielding 16 instead of 12
user> (binding [x 8 a 7] (+ x (foo)))
; Evaluation aborted.
Unable to resolve var: a in this context
if you try to use parallel bindings the dynamic scoping will give different results than let* would in Scheme
user> (def ^:dynamic a 2)
#'user/a
user> (binding [x 8 a 7] (+ x a))
15
user> (binding [x 8 a (+ x 2)] (+ x a))
14 ; this would be 18 if the binding of x to 8 had been used
; instead the root value of 4 was used.
In general It is most common to bind sequentially or use nested lets if required.
binding doesn't give you the same capability as a parallel let because it depends on the existence of bindings. As mentioned letfn will work as long as you don't mind wrapping your values in functions. Another solution is to write a parallel let using a macro:
(defmacro letp
[bindings & exprs]
(let [bindings (partition 2 bindings)
vars (->> bindings (map first) vec)
values (->> bindings (map second))]
`((fn ~vars ~#exprs)
~#values)))
So the following holds:
(def a 7)
(letp [a 5 b a] b)
;;=> 7