Using a var outside let - clojure - clojure

Is there any way in clojure to allow a var defined within a let structure to be used elsewhere in the namespace?
The problem that I am having is that I need two seperate values from the let.
For example if I have the code
(defn example [x y z]
(let [
xy (* x y)
xz (* x z)]
xz))
Is there any way for me to use xy outside the let?
I should also note that xy and xz are just examples in this case, the real data sets are hash-maps and that I have tried using seperate functions to obtain each of sets seperately but because of the nature of the system that I am using this doesn't seem possible.

when you need multiple results from a single function, destructuring is useful
(defn example
[x y z]
(let [xy (* x y)
xz (* x z)]
[xy xz]))
(defn other-example
(let [[xy xz] (example 1 2 3)]
(println 'xy xy 'xz xz)))

No, by definition the variables defined in a let will only be visible inside it. If you need a variable outside maybe you should use a global definition ... but in general that's not a good idea. How about passing around the values as parameters to the other functions that need it?

Related

Why are variables in list cormprehensions not considered is mutable state in clojure?

In Clojure every variable is immutable. But when i use list comprehension like in the case below, the elem variable seems to be mutable, because each time elem is overwritten by 1, then by 2 and then by 3 or it is not?
(for [elem [1 2 3]]
elem)
Is this a point where mutability is allowed or am i missing something?
"Mutation" refers to an existing variable changing its contents. You could observe this if you had a reference to a variable, looked at it once, noting its value as X, and then later looked at the same variable again, noting its value is now Y. That isn't what's happening in a list comprehension.
First, let's talk about one thing that I hope you will agree is not mutation: calling a function multiple times with different values. Suppose we have
(defn triple [x]
(* x 3))
If we write [(triple 1) (triple 2)], do we say that x has mutated? Of course not. There were two different invocations of the function triple, each with a different value for x, but those weren't the same variable: they were different instantiations of x.
A list comprehension is the same thing. The body is a function, which is evaluated once for each of the inputs. It doesn't look like a function, because there's no fn, but it really is one, both technically (it macroexpands into the body of a fn) and philosophically (it handles inputs the same way as our triple function above). (for [x xs] (f x)) is no different from writing (map f xs), which needs no mutation.
Usually when newcomers worry about mutation in Clojure, they are worried about let, which allows you to replace existing bindings:
(let [x 1
_ (prn x)
x 2]
(prn x))
This prints 1 2: doesn't this prove that x has mutated? No, it doesn't: the old x is still there, it's just shadowed so you can't refer to it anymore. You can prove this by using a function to let you refer to the old x:
(let [x 1
f (fn [] x)
x 2]
(prn (f) x))
This still prints 1 2 even though both prints happen after x was bound to 2. This is because f still sees the old x. The new x is an unrelated variable with the same name; you might as well have called it y and renamed all references to it.
The distinction between value and identity, as described here, is important. If an identity appears to change, it is because it becomes associated with different state values over time.
If you have a C/C++ background, it may help to think that elem behaves like a non-const pointer which points at const objects.
If you have a Python/Java background, it might help to think that the values in the collection you are traversing are immutable.
In any case, the immutability question is an assertion about the elements in the collection, not about elem.

How can you destructure in the REPL?

Suppose I've got a function (remove-bad-nodes g) that returns a sequence like this:
[updated-g bad-nodes]
where updated-g is a graph with its bad nodes removed, and bad-nodes is a collection containing the removed nodes.
As an argument to a function or inside a let, I could destructure it like this:
(let [[g bads] (remove-bad-nodes g)]
...)
but that only defines local variables. How could I do that in the REPL, so that in future commands I can refer to the updated graph as g and the removed nodes as bads? The first thing that comes to mind is this:
(def [g bads] (remove-bad-nodes g)
but that doesn't work, because def needs its first argument to be a Symbol.
Note that I'm not asking why def doesn't have syntax like let; there's already a question about that. I'm wondering what is a convenient, practical way to work in the REPL with functions that return "multiple values". If there's some reason why in normal Clojure practice there's no need to destructure in the REPL, because you do something else instead, explaining that might make a useful answer. I've been running into this a lot lately, which is why I'm asking. Usually, but not always, these functions return an updated version of something along with some other information. In side-effecting code, the function would modify the object and return only one value (the removed nodes, in the example), but obviously that's not the Clojurely way to do it.
I think the way to work with such functions in the repl is just to not def your intermediate results unless they are particularly interesting; for interesting-enough intermediate results it's not a big hassle to either def them to a single name, or to write multiple defs inside a destructuring form.
For example, instead of
(def [x y] (foo))
(def [a b] (bar x y))
you could write
(let [[x y] (foo),
[x' y'] (bar x y)])
(def a x') ; or maybe leave this out if `a` isn't that interesting
(def b y'))
A nice side effect of this is that the code you write while playing around in the repl will look much more similar to the code you will one day add to your source file, where you will surely not be defing things over and over, but rather destructuring them, passing them to functions, and so on. It will be easier to adapt the information you learned at the repl into a real program.
There's nothing unique about destructuring w/r/t the REPL. The answer to your question is essentially the same as this question. I think your options are:
let:
(let [[light burnt just-right] (classify-toasts (make-lots-of-toast))]
(prn light burnt just-right))
def the individual values:
(def result (classify-toasts (make-lots-of-toast)))
(def light (nth result 0))
(def burnt (nth result 1))
(def just-right (nth result 2))
Or write a macro to do that def work for you.
You could also consider a different representation if your function is always returning a 3-tuple/vector e.g. you could alternatively return a map from classify-toasts:
{:light 1, :burnt 2, :just-right 3}
And then when you need one of those values, destructure the map using the keywords wherever you need:
(:light the-map) => 1
Observe:
user=> (def results [1 2 3])
#'user/results
user=> (let [[light burnt just-right] results] (def light light) (def burnt burnt) (def just-right just-right))
#'user/just-right
user=> light
1
user=> burnt
2
user=> just-right
3

previous function input parameter correct storing

I started to learn clojure so pardon for noob question
I try to implement following function
pseudo code:
function(x y) {
if (x != oldX)
dosomething(y);
oldX = x;
}
oldX is global variable
How can i properly do this the clojure way?
I wrote something this but is this correct way or not?
(defn rec [x y]
(if (not= x oldX)
(println "y"))
(def oldX x))
defs should only be top level. (def oldX (atom nil)) and (reset! oldX x) is more correct.
Clojure is a functional programming language. This is a different paradigm than it is used in other popular programming languages like Python. It appears that you are not thinking functional ;-)
The Clojure-way would be not to use a variable for this case. Just solve it with functions or, if it is really necessary, use atoms or refs, depending on what you need.
An atom or a ref can be modified within a function to store the old result - this may be the solution you are looking for.
But for most cases there exists a simpler solution without the need for a variable like oldX - and this is were the benefits of a functional language come into place.
Your Code
(defn rec [x y]
(if (not= x oldX)
(println "y"))
(def oldX x))
As #cgrand already said, def should only be used on the first level.
You use if, but you define only the true case. If you check only, if a certain statement is true, then you can use when.
The last line defines a new oldX in the scope of the function rec. This is a new variable, not the old one with a new value, in the active namespace (thanks to #user1571406).
I think what you're looking for is something like this. I've tried to keep your var names as your originals, so it's easier to see the difference.
Use an atom to store oldX
Use a compare-and-set! to determine whether you've changed the atom
If you've changed the atom, call your (dosomething y)
Note: This is kind of like a swap!, except swap! returns the value swapped in, not whether or not your call to swap! changed the value, so it's less useful here.
Something like this:
(defn dosomething [y]
;; does something, presumably with y...
)
(defonce x-atom (atom nil))
(defn swap-x
"swaps x-atom for new x, calls (dosomething ...) with y if successful"
[x y]
(let [oldX #x-atom] ; get the cur value of x
(when (not= oldX x)
(when (compare-and-set! x-atom oldX x)
(dosomething y))
If the compare-and-set! fails, then it means some other thread has modified the atom since you got its value. If you need to handle that case, the answer is a little different. You could either use a swap! or a loop+recur. If you're unfamiliar, a swap! is sort of like a compare-and-set! that recurs on failure.

Scheme task decomposition - global variable issues

So here is my problem (generalized to an abstract situation). It is generally an interpreter.
I have got a program that needs to parse an input list and according to its elements sequentially call some functions that need to modify variables. Functions are defined separately and chosen by (cond . Those 3 variables that I need to update contain information about current situation (exactly - robot position, maze and robot orientation). The result of previous function is used in the next function (i.e. the updated variables are used).
(define func-a ... )
(define func-b ... )
(define (main-func <maze> <orientation> <coordinates> <list with commands>)
;; here I parse the list and choose which function to call
;; output must contain (list <new-maze> <new-orientation> <new-coordinates>))
)
What scheme tools can I use to update those variables? I have considered several options:
use (define and then call set! (this is bad style cause it is not pure functional programming);
call functions from back to beginning (this won't work: I also have to check if movement is valid);
don't make those variables constant at all, try passing them as arguments to each function;
Is there any other proper way to do it?
You have to keep some state (as well as read a file), so there will not be a pure functional programming, and you have to accept some deviations.
The general approach is to keep the shared object as a local in some meta-function, say parse, and update it by calling those your function, say parse-one, parse-two, and so on.
Now you need a way to update them.
You can make them visible for parse-one and parse-two by defining them inside the scope:
(let ((state (make-state)))
(let ((parse-one (lambda () ...))
(parse-two (lambda () ...)))
....))
Or you use the return value:
(let ((state (make-state)))
...
(set! state (parse-one state))
...)
There is a third approach, called OOP. Define all of them in a single closure, so they can share some data:
(define (make-parser)
(let ((state (make-state))
(let (((parse-one (lambda () ...))
((parse-two (lambda () ...))
((get-state (lambda () state)))
(list parse-one parse-two get-state))))
(destructuring-bind (parse-one parse-two get-state) (make-parser)
...
(parse-one)
...
(get-state))
(destructuring-bind is just an easy way to destruct a list, see it's scheme implementation) But it seems to be a complicated version of the first.
Just because Scheme is considered a 'functional language' doesn't forbid you from using 'set!' - after all it exists in the language to be used. Thus there is nothing wrong with:
(define-record-type position (fields x y z))
(define robot-position (make-position 0.0 0.0 0.0))
(define update-robot-position (new-x new-y new-z)
(set! robot-position (make-position new-x new-y new-x)))
[I've chosen to define positions as invariant.]
You can chose another approach if you want but fundamentally the position of the robot changed and that change will be in your code is some fashion. Why not use the simplest, most straight-forward approach?

Which Vars affect a Clojure function?

How do I programmatically figure out which Vars may affect the results of a function defined in Clojure?
Consider this definition of a Clojure function:
(def ^:dynamic *increment* 3)
(defn f [x]
(+ x *increment*))
This is a function of x, but also of *increment* (and also of clojure.core/+(1); but I'm less concerned with that). When writing tests for this function, I want to make sure that I control all relevant inputs, so I do something like this:
(assert (= (binding [*increment* 3] (f 1)) 4))
(assert (= (binding [*increment* -1] (f 1)) 0))
(Imagine that *increment* is a configuration value that someone might reasonably change; I don't want this function's tests to need changing when this happens.)
My question is: how do I write an assertion that the value of (f 1) can depend on *increment* but not on any other Var? Because I expect that one day someone will refactor some code and cause the function to be
(defn f [x]
(+ x *increment* *additional-increment*))
and neglect to update the test, and I would like to have the test fail even if *additional-increment* is zero.
This is of course a simplified example – in a large system, there can be lots of dynamic Vars, and they can get referenced through a long chain of function calls. The solution needs to work even if f calls g which calls h which references a Var. It would be great if it didn't claim that (with-out-str (prn "foo")) depends on *out*, but this is less important. If the code being analyzed calls eval or uses Java interop, of course all bets are off.
I can think of three categories of solutions:
Get the information from the compiler
I imagine the compiler does scan function definitions for the necessary information, because if I try to refer to a nonexistent Var, it throws:
user=> (defn g [x] (if true x (+ *foobar* x)))
CompilerException java.lang.RuntimeException: Unable to resolve symbol: *foobar* in this context, compiling:(NO_SOURCE_PATH:24)
Note that this happens at compile time, and regardless of whether the offending code will ever be executed. Thus the compiler should know what Vars are potentially referenced by the function, and I would like to have access to that information.
Parse the source code and walk the syntax tree, and record when a Var is referenced
Because code is data and all that. I suppose this means calling macroexpand and handling each Clojure primitive and every kind of syntax they take. This looks so much like a compilation phase that it would be great to be able to call parts of the compiler, or somehow add my own hooks to the compiler.
Instrument the Var mechanism, execute the test and see which Vars get accessed
Not as complete as the other methods (what if a Var is used in a branch of the code that my test fails to exercise?) but this would suffice. I imagine I would need to redefine def to produce something that acts like a Var but records its accesses somehow.
(1) Actually that particular function doesn't change if you rebind +; but in Clojure 1.2 you can bypass that optimization by making it (defn f [x] (+ x 0 *increment*)) and then you can have fun with (binding [+ -] (f 3)). In Clojure 1.3 attempting to rebind + throws an error.
Regarding your first point you could consider using the analyze library. With it you can quite easily figure out which dynamic vars are used in an expression:
user> (def ^:dynamic *increment* 3)
user> (def src '(defn f [x]
(+ x *increment*)))
user> (def env {:ns {:name 'user} :context :eval})
user> (->> (analyze-one env src)
expr-seq
(filter (op= :var))
(map :var)
(filter (comp :dynamic meta))
set)
#{#'user/*increment*}
I know that this doesn't answer your question, but wouldn't it be a lot less work to just provide two versions of a function where one version has no free variables, and the other version calls the first one with the appropriate top-level defines?
For example:
(def ^:dynamic *increment* 3)
(defn f
([x]
(f x *increment*))
([x y]
(+ x y)))
This way you can write all your tests against (f x y), which doesn't rely on any global state.