I've been trying to figure out how to execute expressions that are stored as elements in a sequence. For example, here are two expressions in a sequence:
user=> (def z '((println 'x) 'y))
#'user/z
user=> z
((println (quote x)) (quote y))
Trying to use do or doall on them doesn’t seem to do anything
user=> (do z)
((println (quote x)) (quote y))
user=> (doall z)
((println (quote x)) (quote y))
The output I am trying to get is if I were to execute them not as a sequence but as a list of arguments
user=> (do (println (quote x)) (quote y))
x
y
I tried mapping eval but that gives me an extra nil and returns a list
user=> (map eval z)
(x
nil y)
Any help would be greatly appreciated!
Do is a macro that evaluates its args, and returns the last one. let, fn, for among others contain implicit do bodies.
In your map example, the "extra nil" is the return value of the println, and it is actually the x that is extra (it is the printed output interleaved with the sequence that map returns).
Your definition of z does not create executable objects, but lists. Lists just evaluate to themselves when used.
Do you need to evaluate expressions stored as literals?
It is easy to wrap each each one as a thunk (a function of no arguments).
user> (def z [#(println 'x) #(do 'y)])
#'user/z
We can use reduce to execute them all, and only return the last one.
user> (reduce (fn [_ e] (e)) nil z)
x
y
here x is printed, and y is returned.
If you really need to use a list with eval, you can substitute it as apropriate above ((e) becomes (eval e) and z gets your original definition).
(def z '((println 'x) 'y))
Your z definition has a quote saying DON'T EVALUATE ME. So z is defined as an unevaluated expression. You want to evaluate unevaluated code so naturally you'll want to use eval; however (eval z) won't work because (println x) will print x but return the value nil. (nil y) will not work and isn't what you want.
What you do want is do; do only returns the value of the last expression so used here nil does not get in the way and you execute all your expressions. You want your end result to be:
(do (println 'x)
'y))
Let's transform z to look like that.
(cons 'do z)
=> (do (println (quote x)) (quote y))
Looking familiar? eval it!
(eval (cons 'do z))
=> x
y
You're looking to eval code here.
user=> (def z '(do (println "hey!" 'x) 'y))
#'user/z
user=> (eval z)
hey! x
y
Note that I added the do so that both expressions would be evaluated. The code in the question contained an error.
((println 'x) 'y)
First thing that would occur would be to print 'x and println returns nil, so the expression would then look like this.
(nil 'y)
nil is not a function, but it's being evaluated at the head of the list, so that's an error. Or a null pointer exception in this case.
user=> (def z '((println 'x) 'y))
#'user/z
user=> (eval z)
x
NullPointerException user/eval674 (NO_SOURCE_FILE:1)
Related
(defn my-loop [x]
(cond (> x 1)
((println x)
(my-loop (- x 1)))
)
)
;; => #'user/my-loop
user> (my-loop 10)
Why do i get a null pointer exception, when executing this function?
Is this not a normal recursion?
You are invoking the return of (println x) with the additional layer of parentheses. println returns nil so invoking it will lead to the NullPointerException.
To evaluate more than one form where only one is expected use the do special form, which evaluates any number of forms and returns the value of the last one:
(defn my-loop [x]
(cond (> x 1) (do
(println x)
(my-loop (- x 1)))))
In this case, when can replace a one armed cond and do
(defn my-loop [x]
(when (> x 1)
(println x)
(my-loop (- x 1))))
The code should typically look something like so:
(defn my-loop
"Some docstring"
[x]
(cond
(> x 1) (println x)
:else (my-loop (- x 1))))
Keeping to good formatting helps to see problems early.
You may also be interested in this list of documentation sources, especially the Clojure CheatSheet & the book "Getting Clojure".
I have a substitute function that will take in an expression such as (or false x y) and a binding map such as '{x false, y true} and will return the list with the appropriate substitutions. The result is in l and displayed. How might I pass l into another function to do some other processing? The definition for the function I'm passing to looks like this:
(defn f [expression]
)
I have tried passing l as a parameter when calling f, but I get the following error:
IllegalArgumentException Don't know how to create ISeq from: clojure.lang.Symbol clojure.lang.RT.seqFrom (RT.java:550)
Here is my substitute function:
(defn deep-substitute [m l]
(map (fn [i]
(if (seq? i)
(deep-substitute m i)
(m i i)))
l
(f 'l)))
My new function fully works the way I expect it to when calling it with an unevaluated list, but not when I pass it an unevaluated list.
The job of deep-substitute is to fill in a template form and return it. The problem gets harder if you try to make deep-substitute also responsible for doing the next step in the transformations as well. Perhaps let it return the value, then pass that value on to another transform function after it's returned.
Here's an annotated working example:
user> (defn deep-substitute [m l]
(map (fn [i]
(if (seq? i) ;; if this is a sequence,
(deep-substitute m i) ;; finish the sequence and include the result here
(get m i i))) ;; otherwise get the new value from the map, if found
l)) ;; if it's not found, us the value unchanged.
#'user/deep-substitute
then test it on your example:
user> (deep-substitute '{x false, y true} '(or false x y))
(or false false true)
and a more nested example:
user> (deep-substitute '{x false, y true} '(or false (and x (or y x)) y))
(or false (and false (or true false)) true)
a common next step is to wrap that in a macro so it can modify forms before they are evaluated, then evaluate that newly created from to find out what value it becomes:
user> (defmacro dsub [m l]
(deep-substitute m l))
#'user/dsub
and test it
user> (dsub {x false, y true} (or false (and x (or y x)) y))
true
user> (dsub {x false, y true} (or false x))
false
or pass the resulting form (unevaluated) into another function by nesting it:
user> (defn f [expression]
(reverse expression))
#'user/f
user> (f (deep-substitute '{x false, y true} '(or false (and x (or y x)) y)))
(true (and false (or true false)) false or)
A common pattern is to use the threading macros -> ->> etc. to pass the result from transform to transform until the final result is made by composing many simple operations:
user> (->> '(or false (and x (or y x)) y)
(deep-substitute '{x false, y true})
f
(deep-substitute '{false, 41 true 42}))
(42 (and 41 (or 42 41)) 41 or)
first try with the basic approach of the passing list as an argument to the function. You can refer below example
(defn passlist [a]
(println a))
(passlist '(1 2 3))
Output will:
#'user/passlist
(1 2 3)
I'm having problems eval-ing a LazySeq returned by Deriva:
(use 'clojure.core.matrix)
(use 'com.lambder.deriva.core)
(def f1 '(cos (* x y)))
(def f2 '(sin (* x y)))
(def f [f1 f2])
(def u ['x 'y])
(def x 4)
(def y 3)
(defn jacobian [f u]
(map #(partial-derivative f %) u)
)
Returns a LazySeq
((vector (* (* -1 (sin (* x y))) y) (* (cos (* x y)) y)) (vector (* (* -1 (sin (* x y))) x) (* (cos (* x y)) x)))
Which can be successfully eval-ed using the REPL:
(eval (into [] (jacobian f u)))
Results in the correct matrix
[[1.609718754001305 2.5315618761974763] [2.1462916720017398 3.3754158349299686]]
If I put the eval inside the clj file and lein run
(defn -main
[]
(eval (into [] (jacobian f u)))
)
I get Exception in thread "main" java.lang.RuntimeException: Unable to resolve symbol: sin in this context, compiling:(/tmp/form-init2786363415298022761.clj:1:113) since eval works in a different namespace.
Is there any way to include the clojure.math functions in the temporary namespace generated by eval? Or is there a better way to evaluate the expression?
Maybe you need to use java.lang.Math/sin function of java.
Consider using syntax-quote (`) instead quote (') to obtain fully qualified symbols that you can later eval:
's
=> s
`s
=> user/s
See more about quoting here:
https://blog.8thlight.com/colin-jones/2012/05/22/quoting-without-confusion.html
I'm extremely new to Clojure and very new to functional programming. I'm expecting this to return True or False but it's just infinitely recursing and it doesn't seem to be hitting true at all.
My test data set is this:
(def y (list 1 2 3 4)) ; and I'm passing in 2 for X.
(defn occursIn [x y]
(if (= y nil)
"False"
(if (= x first y )
"True"
(occursIn x (rest y))
)
)
)
Try this, and please pay attention to the recommended way to format your code - don't leave lonely parentheses on a line by themselves, they're not like {} in other programming languages:
(defn occursIn [x y]
(if (empty? y)
"False"
(if (= x (first y))
"True"
(occursIn x (rest y)))))
You forgot to call first on the y list, like this:
(first y)
Also, notice that the base case isn't working as you expected. Use this test instead:
(empty? y)
For completeness' sake, here's a more idiomatic way to write the same procedure - but beware of the edge case pointed by #omiel in the comments, this won't work if x is false or nil:
(defn occursIn [x y]
(if (some #(= x %) y)
"True"
"False"))
An even better solution, free from the edge case - as suggested by #mange in the comments:
(defn occursIn [x y]
(if (every? #(not= x %) y)
"False"
"True"))
Oscar's answer is correct and helpful, but I just thought I'd provide an alternate answer which demonstrates how to make a function which is closer to your original function, while still being relatively idiomatic clojure:
(defn occurs-in [needle haystack]
(if-let [[head & tail] (seq haystack)]
(if (= needle head)
"True"
(recur needle tail))
"False"))
In this case I've:
used destructuring to extract head/tail instead of using first/rest on a sequence.
used if-let to bind those names only if haystack is non-empty (that is, if (seq haystack) is truthy).
used recur instead of occurs-in to ensure that this function will be compiled to use tail call elimination, so it calls itself again without using an additional stack frame.
This may not be an issue for small inputs, but it's essential to make it work for calls like (occurs-in 1000000 (range))
In terms of idiomatic naming, see that I've used occurs-in instead of occursIn: generally lisps use hyphens (lisp-case) instead of camel case (camelCase) for names.
Before we do anything else, let's replace "True" with boolean true and "False" with boolean false. The reason for doing this will become apparent.
The fundamental problem is that rest never returns nil. It returns the empty list () instead. And (rest ()) is (). So you get an endless sequence of recursive calls that ultimately blow the top off the stack.
next does return nil where rest returns (). So use next instead of rest and at least we get an answer:
(def aList (list 1 2 3 4))
(defn occursIn [x y]
(if (= y nil)
false
(if (= x first y)
true
(occursIn x (next y))
)
)
)
(occursIn 2 aList)
; false
... but the wrong answer. Why? As #OscarLopez says, you are missing parentheses around first y to call first upon the argument y. As it stands,
(= x first y)
tests whether x, first, and y are all equal. There is only one way this can happen:
(occursIn first first)
; true
... not what we want. So, let's call first instead of comparing it:
(defn occursIn [x y]
(if (= y nil)
false
(if (= x (first y))
true
(occursIn x (next y))
)
)
)
(occursIn 2 aList)
; true
It works.
Actually, the base case does work:
(occursIn 2 ())
; false
... but only because the next call turns () into nil: queasy.
And it does misfire searching for nil:
(occursIn nil ())
; true
... because (first ()) returns nil and nil pretends to be () when asked to be a sequence (this is called nil punning), so (first nil) is nil.
So, again following Oscar, we had better test whether y is empty, not whether it is nil:
(defn occursIn [x y]
(if (empty? y)
false
(if (= x (first y))
true
(occursIn x (next y))
)
)
)
(occursIn nil ())
; false
The logic is now correct. Let's make it clearer by using and and or instead of ifs with explicit true and false results (a code smell, in my view):
(defn occursIn [x y]
(and (not (empty? y))
(or (= x (first y))
(occursIn x (next y))
)
)
)
The code reads easily now. It is to do this that we used the proper boolean values.
Only two more changes:
If you look up empty?, you'll find that (empty? y) means (not
(seq y)), so (not (empty? y)) means (not (not (seq y))), which is
equivalent to (seq y).
The recursive call to occursIn is the last thing that happens: it
is said to be in tail position. We can therefore replace it by
recur. This consumes no stack, so puts no limit on the length of
the sequence that can be searched.
So we end up with ...
(defn occursIn [x y]
(and (seq y)
(or (= x (first y))
(recur x (next y))
)
)
)
At the home site of Clojure, there is the following statement:
Strings, numbers, characters, true,
false, nil and keywords evaluate to
themselves.
Is there a single combined predicate that tests for any of these, combining string?, number?, char?, true?, false?, nil?, and keyword?. Should I just use (complement symbol?)?
Maybe I'm missing something, but you could use the following to test for any of those conditions and return true if one is true:
(defn self-eval?
[x]
(or (string? x)
(number? x)
(char? x)
(keyword? x)
(true? x)
(false? x)
(nil? x)))
It's easy enough to write a macro that asks "does the given expression evaluate to itself". In fact this is a good example of tasks that can only be done with a macro because they need to see the argument both evaluated and unevaluated.
(defmacro selfp [a] `(= ~a (quote ~a)))
#'user/selfp
user> (selfp 1)
true
user> (selfp +)
false
user> (selfp [1 2])
true
user> (selfp '(+ 1 2 3))
false
While strings, numbers, characters, keywords, and the booleans are all self-evaluating, other things such as [1 2] are as well,so this may not be a useful test in general.
Another option is to create a function that uses a map:
(defn myclassifier? [x]
(let [types-I-care-about #{java.lang.Sring ...}]
(if (types-I-care-about (type x))
true
false)))
Another option which may have better performance is to use java's dynamism:
(extend-type Object
IMyClassifier
(myclassifier? [x]
(let [c (.getClass x)]
(if (types-I-care-about (type c))
(do
(extend-type (.getClass x)
IMyClassifier
(myclassifier? [x] true))
true)
false))))
where types-I-care-about is a set of types you care about.