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)
Related
I want to write a macro to accept a vector params
(defmacro eval-verify [body]
`(cond
~#body
:default nil))
it work in this case
(eval-verify [true 1 false 2])
it return 1,and i run
(macroexpand-1 '(eval-verify [true 1 false 2]))
it return
(clojure.core/cond true 1 false 2 :default nil)
it seems ok,but when i def a vector
(def a [true 1 false 2])
and run
(eval-verify a)
it is error
IllegalArgumentException Don't know how to create ISeq from: clojure.lang.Symbol
how to write a macro can accept argument which is symbol,or write functoin can do the same things.
Macro arguments are passed as unevaluated symbols. Therefore when you invoke (eval-verify a) the symbol a is the value of the body argument passed to eval-verify and not [true 1 false 2]. Since unquote-splice (~#) expects a Seq and it finds a symbol (a), you receive the IllegalArgumentException.
You would either need to invoke eval-verify using the form (eval-verify [true 1 false 2]) or you would need to use a plain function.
You can use the following function instead of a macro:
(defn eval-verify [coll]
(loop [[f v :as c] coll]
(cond
(and (ifn? f) (f)) v
(and (not (ifn? f)) f) v
:else (if (seq c) (recur (drop 2 c)) nil))))
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))
)
)
)
Sometimes I want to pass argument-value pairs to a higher-order function, where the value I should pass is determined by the argument I pass. I want to be able to pass the argument without explicitly specifying the accompanying value. In particular, I'm interested in the case where the argument is itself a function.
Generic Example:
Here's a very generic example, where my-foo and my-bar are functions that I'm passing to higher-foo:
(higher-foo my-foo :option4 args) ;good
(higher-foo my-bar :option13 args) ;good
(higher-foo my-foo :option13 args) ;how stupid are you?! my-foo requires :option4!
Question: Is there a "standard" method for making :option4 or :option13 to be inferable by higher-foo so that I can just write (higher-foo my-foo) and (higher-foo my-bar)?
More Specific Example:
Bear in mind that there are better alternatives to the following code, but I'm just trying to put forward a concrete example of what I'm talking about:
(defn seq-has? [f n someseq]
(every? (partial apply f)
(partition n 1 someseq)))
(defn monotonicity [a b]
(<= a b))
(defn generalized-fib [a b c]
(= c (+ a b)))
(seq-has? monotonicity 2 someseq) should return true if the sequence is monotonic, false otherwise. (seq-has? generalized-fib 3 someseq) should return true if the sequence follows the generalized Fibonacci form, false otherwise.
But the "2" and "3" bother me. I could have an arbitrary number of properties to test for, and I don't want to have to remember the appropriate "magic numbers" for such calls.
Note: I know of two ways to do this, and for my own personal use, I suppose they both work. But I'm interested in what is idiomatic or considered best practice in the community. I'll post my answers, but I'm hoping there are more solutions.
Just make the predicate function itself take variadic arguments, and have it do the partitioning / recurring. Your monotonic? for instance already exists in core, and is called <=
(<= 1 2 4 5)
=> true
(<= 1 2 1 5)
=> false
Here's the source for the 1, 2 and variadic arg versions:
(source <=)
(defn <=
"Returns non-nil if nums are in monotonically non-decreasing order,
otherwise false."
{:inline (fn [x y] `(. clojure.lang.Numbers (lte ~x ~y)))
:inline-arities #{2}
:added "1.0"}
([x] true)
([x y] (. clojure.lang.Numbers (lte x y)))
([x y & more]
(if (<= x y)
(if (next more)
(recur y (first more) (next more))
(<= y (first more)))
false)))
You can make a fib? work the same way, have it take variadic arguments and recur over triples:
(defn fib?
[a b & [c & r]]
(if (= c (+ a b))
(if r
(recur b c r)
true)
false))
(fib? 0 1 1)
=> true
(fib? 2 3 5 8 13)
=> true
Since you are asking for a standard way how a function determines a not passed argument from one argument:
(defn f
([arg0] (case a :foo (f a :bar)
:baz (f a :quux)))
([arg0 arg1] ...))
Depending on your use case a different dispatch construct than case may be a better fit.
For your generic example this implies that higher-foo should determine the correct :option in the desired overload like demonstrated above.
In your specific example, you can't determine the n from the passed function. You need a more specific datastructure:
(defn seq-has? [{:keys [f n]} s]
(every? (partial apply f)
(partition n 1 s)))
(def monotonicity
{:f <=
:n 2})
(def generalized-fib
{:f #(= (+ %1 %2) %3)
:n 3})
(seq-has? monotonicity [1 2 3])
;; => true
This solution seems like a hack to me. Is it considered common/idiomatic? Use meta-data on the functions that define the property you are looking for:
(defn higher-foo [foo & args]
(apply foo (:option (meta foo))
args))
(def my-foo
(with-meta
(fn [a b] (println "I'm doing something cool"))
{:option :option4}))
;using it:
user=> (higher-foo my-foo arg)
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)
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.