I am having some troubles figuring how to use the "let" form. In the example below, I would like to locally bind the value "cols" in order to work on it later in the function. What I am noticing, however, is that if I use "let" the function sel-opt-tmp will return a nil value instead than a list.
(defn sel-opt-tmp []
(let [cols "test"]))
(prn (sel-opt-tmp))
*The above code returns a nil value.
I understand that "let" only binds a value in the scope of a function, what I do not know is if there is a way to pass the value out of the let scope. Maybe there is something like "return" that I am not aware of? Or this is simply bad design and I should not use the binding at all in this case (this tends to create long chains of functions that are difficult to read although)?
It returns nil because the contents of the let statement is empty (or nil). Try:
(let [cols "test"] cols)
Which will return the value of cols. As seh says, a let statement evaluates to the value of its last sub-expression.
There is no such problem with passing values outside the scope as you mention. The binding cols is in force only within the scope, but the lifetime of the value of (:ks cols) is not similarly restricted. (That's why you have garbage collection: you can return values that point to data, and the data stays live as long as there are references to it.)
If you get nil from the function, that likely means that cols does not have a :ks key... or indeed might not be a map. Since cols is the result from filter, it is a sequence, and when the :ks keyword is used as a function, it returns nil for non-collections. To guard against that kind of bugs it may be a useful convention to always write (cols :ks) instead of (:ks cols) so that you get an error when what you think is a map is something else.
Related
I'm confused with when atoms are dereferenced in Clojure. In the follow, I have a server-request function that receives data and updates the request-result-data which is just a map indexed by the request ID. The function blocks until the server has finished sending the data, and returns the request ID. The first snippet below works as expected. The second doesn't, because (it seems) #request-result-data is de-referenced before the function returns.
;works
(let [req-id (server-request "parameters")]
(pprint (#request-result-data req-id)))
;returns nil
(pprint (#request-result-data (server-request "parameters"))))
Is this normal behaviour? Is there a better way to code this? As intuitively it doesn't seem I need a let here.
Thank you,
If the server-request function is modifying the request-result-data atom, then it's definitely true that you need to use the first form to make sure things happen in the right order. If you have a function call (E1 E2), you shouldn't be relying on E1 or E2 being evaluated in any particular order.
Without any other context, I'd wonder why you can't have server-request return the information instead of putting it in an atom, but that goes beyond your original question.
In Clojure, the fnil function can be used to wrap another function: if the argument of the wrapped function would be nil, the wrapper will change it to something else.
E.g. ((fnil * 0) nil) ; returns 0 However (* nil 0) would throw an NPE.
What I'm asking is if there is a similar, built-in function that modifies the output, in case the input is nil. (In other words, it does not even call the wrapped function, it just returns the default value instead.)
In other words, is there a built-in function equivalent to the following?
(defn ifnil [fun default]
(fn [& args]
(if (some nil? args) default (apply fun args))))
; ((ifnil * nil) 1 2 3) ; returns 6
; ((ifnil * nil) 1 nil 3) ; returns nil
N.B.: As always, "no, there is no such function" is also a valid answer (which I suspect, btw.)
There is no such a function, as far as I know. Your implementation looks well, so why not to use it in your code.
What may be improved here is a better name of the function: ifnil might be a bit confusing for your teammates or those who will support your code.
Also, you said in case the input is nil. But in your code, you check for at least one argument is nil. That differs slightly.
And one more thing, personally I'm not a fan of failing to defaults silently. Maybe, you'd better to validate the input data either manually or using schema/spec and write logs. Because fnil mostly used for non-existing keys with update/update-in. But you function tends to be rather a validator.
I'm a new student of Clojure and don't get why "nil" is returned in REPL when I call functions that do not return values.
Above an example:
(println "Hello Nil")
nil
What type of evaluation process are made to reach "nil"?
It is a convention of functional languages like Clojure that every function needs to return exactly one value. For functions like println that are intended to perform side effects (like printing to the screen), it is not always clear what the return value could or should be.
In these cases, nil is a placeholder value that means "nothing" or "not applicable".
I'm new in Clojure and i read that it is a functional language. It says that Clojure doesn't have variables, still when i find (def n 5), what's the difference between it and a variable?
I can change the value of the var after, so is it really that different from a variable? I don't understand the difference.
Assuming that by variable you mean a refer to a mutable storage location, I guess the main difference(depending against which language you compare) is that if you dynamically rebind the var in Clojure is on a per-thread basis.
But the long answer is that you don't usually use a var in Clojure unless you really need a reference to a mutable storage location.
Clojure favors immutability and programming using values instead of references.
You can watch Rich Hickey's talk about values.
A summary would be, when you're programming in Clojure what you have are values , not references to locations that may change (maybe even changed by another thread).
So.
(let [a 1
_ (println a) => prints 1
a 2
_ (println a) => prints 2
])
Even if you get the illusion of "changing a" in that code, you're not changing the "old" a you just have a new value. (if someone would have looked at the first definition it would still be seeing the value 1).
Actually you can see that sequence of assignments as a composed function calls where a is being replaced in scope, but not the same "variable" at all.
((fn [a]
(println a) => prints 1
((fn [a]
(println a) => prints 2
) 2) 1)
None the less, if you need to have a mutable storage with potentially many threads accessing that storage, Clojure gives you vars, atoms, refs, etc.
It is not true that Clojure does not have variables, i. e. changeable references. They are however not used to store and look up during computations that can be modeled as pure mathematical functions.
The concept of immutability is that of dealing with concrete values instead of references that one or others can change. Just like 1 is a value that you can't change, in Clojure the vector [3 2] is value that you also can't change. E. g. if your algorithm is required to append 1 to that vector, it needs to create a new vector, leaving the old one intact, while in imperative languages you could just "change" the vector, breaking everything potentially relying on it. The takeaway of immutability is that you don't have to worry about that anymore and your code becomes less error prone.
Clojure implements immutable datastructures in a way that such newly created values efficiently reuse most memory of the values they are based on. They provide near the same performance characteristics as their mutable counterparts both for reading and writing (i. e. creating new versions). You may want to read more about that here and Rich Hickey does some excellent explaining in this conversation with Brian Beckmann.
Think about def as defining constant. It can be change by calling def again but you should not do it.
The closes thing to variables are agents which are thread safe.
(def counter (agent 0))
(send counter inc)
#counter
;;=> 1
You can also access the variable in Java class.
New class
(def object (ClassName.))
Se value
(.fieldName object)
Set value
(set! (.fieldName object) 5)
The "whole" point of of not having variables is to make program automatically thread safe. It is because thread error will "always" fail on that thread 1 wil tell the variable a is 1 and thread b tells that a is 2 and after that something fail. This is also reason to use pure functions - no variables "no" thread problem.
See also this question:Clojure differences between Ref, Var, Agent, Atom, with examples and this one Clojure: vars, atoms, and refs (oh my).
Treat "" as in 80% or more - not 100%.
I have a bit of computation that is somewhat expensive (starting a database), and I only want to create the database if I actually am going to use it. I am looking for a reference variable (or just a plain variable, if that is possible) that would only evaluate its value in the event that it is used (or dereferenced). Something conceptually like the following.
(def v (lazy-var (fn [] (do (println "REALLY EXPENSIVE FUNCTION") true))))
and in the future, when I either just use var v, or call #v, I then get it to print out "REALLY EXPENSIVE FUNCTION", and from thereon v has a value of true. The important thing here is that the fn was not evaluated until the variable was (de)referenced. When needed, the function is evaluated once and only once to calculate the value of the variable. Is this possible in clojure?
delay would be perfect for this application:
delay- (delay & body)
Takes a body of expressions and yields a Delay object that will invoke the body only the first time it is forced (with force or deref/#), and will cache the result and return it on all subsequent force calls.
Place the code to construct the database handle within the body of a delay invocation, stored as a Var. Then dereference this Var whenever you need to use the DB handle — on the first dereference the body will be run, and on subsequent dereferences the cached handle will be returned.
(def db (delay (println "DB stuff") x))
(select #db ...) ; "DB stuff" printed, x returned
(insert #db ...) ; x returned (cached)
Clojure 1.3 introduced memoize function for this purpose:
(memoize f)
Returns a memoized version of a referentially transparent function.
The memoized version of the function keeps a cache of the mapping from
arguments to results and, when calls with the same arguments are
repeated often, has higher performance at the expense of higher memory
use.
In your example replace non-existing lazy-var with memoize:
(def v (memoize (fn [] (do (println "REALLY EXPENSIVE FUNCTION") true))))
(v)
=>REALLY EXPENSIVE FUNCTION
=>true
(v)
=>true
(delay expr) also does the job as another answer explains. An extra comment on dereferencing the delay - the difference between force and deref/# is that force does not throw exception if used on non-delay variable while deref/# may throw ClassCastException "cannot be cast to clojure.lang.IDeref".