Clojure Built in Function to access the entire record - clojure

(defrecord Sample (x y))
(def check (Sample. 1 2))
(:x check) ;returns 1
If I receive (:x check) as an argument to a function, is there a way to access check? Or, in other words, return
#:user.Sample{:x 1, :y 2}

No, if a function is passed (:x check) as parameter then the value was already evaluated before entering the function, you'll just receive a 1 as value, and you can't retrieve the record it came from.
If you need the record inside the function, why don't you pass check as parameter?

As Óscar described, (:x check) won't work because its result is 1, and '(:x check) won't work because its result is a list containing the keyword :x and the symbol check.
However, instead of using quote you could use the list function:
(defn receiver [arg]
(map class arg))
;; With a quoted list it receives the symbol `check` rather
;; than the Sample record
(receiver '(:x check))
;=> (clojure.lang.Keyword clojure.lang.Symbol)
;; But this way it does receive the Sample
(receiver (list :x check))
;=> (clojure.lang.Keyword user.Sample)
And (list :x check) can be evaluated:
(eval (list :x check))
;=> 1
(defn receiver [arg]
(str "received " arg "; eval'd to: " (eval arg)))
(receiver (list :x check))
;=> "received (:x #user.Sample{:x 1, :y 2}); eval'd to: 1"
The reason that quote and list behave so differently is that quote doesn't evaluate it's argument. And, when a list is quoted, that effect is recursive: none of the items in the list are evaluated either.
There's another type of quote, called syntax-quote or backquote (and described on the Clojure.org page about the reader) which allows you to selectively un-quote (i.e. evaluate) items.
(require '[clojure.pprint])
(let [n 1
x :x
c check]
(clojure.pprint/pprint
(vector `(n x c)
`(~n x c)
`(~n ~x c)
`(~n ~x ~c))))
Prints:
[(user/n user/x user/c)
(1 user/x user/c)
(1 :x user/c)
(1 :x {:x 1, :y 2})]
And, actually, I lied a little bit. You could in fact use '(:x check) in this particular case. resolve will return the Var associated with a symbol, and deref (or its # reader macro) will get you the Var's value.
(resolve 'check)
;=> #'user/check
(deref (resolve 'check))
;=> #user.Sample{:x 1, :y 2}
(defn resolve-and-deref-symbols [form]
(map (fn [x] (if (symbol? x)
#(resolve x)
x))
form))
(defn receiver [arg]
(str "received " arg "; eval'd to: " (eval (resolve-and-deref-symbols arg))))
(receiver '(:x check))
;=> "received (:x check); eval'd to: 1"
I didn't mention it straight-away because, while it works easily enough in this example, it's not at all appropriate for the general case. (For instance, it won't work with locals, and handling namespaces and nested data structure would be painful).

Related

How to end dotimes clojure

I am trying to make a guess the number game in clojure but I keep getting an error saying I can only recur from tail position
(def n (rand-int 100))
(prn n)
(println "You have 10 guesses :D")
(println "HINT: My number is between 1 and 100")
(dotimes [i 10]
(def guess (read-line))
(if (= guess str(n))
(recur (println "Correct!") (println "Incorrect"))))
(I am new to clojure)
dotimes is used to execute the body for sideeffects that exact amount given; there is no means to break - except throwing
loop (or functions) are recur targets. Next you would have to count down the attempts so you can stop, if the user did not guess it:
(loop [attempts 10]
; ...
(recur (dec attempts)))
There are also other problematic things:
Don't def inside other forms. Use let instead.
str(n) will throw, as it will try to call n (ClassCastException java.lang.Long cannot be cast to clojure.lang.IFn)
recuring with println looks fishy, since println returns always nil
How do you end dotimes? You don't. Try using loop instead. There are a lot of issues with your code but that's a start.
though this is discouraged and counterclojurish to even think of short circuiting the execution this way, it is still totally possible with macros (purely for education and fun)
(defmacro return [& x]
`(list '~'return (do ~#x)))
(defmacro dotimes+ [[i n] & body]
`(loop [~i 0 res# nil]
(cond (and (list? res#) (= '~'return (first res#))) (second res#)
(< ~i ~n) (recur (inc ~i) (do ~#body))
:else res#)))
can be used like this:
user> (dotimes+ [i 10]
(println i)
(if (== i 5) (return :short-circuited)))
;; 0
;; 1
;; 2
;; 3
;; 4
;; 5
:short-circuited
user> (dotimes+ [i 10]
(println i)
(if (== i 5) (return)))
;; 0
;; 1
;; 2
;; 3
;; 4
;; 5
nil
user> (dotimes+ [i 10]
(println i))
;; 0
;; 1
;; 2
;; 3
;; 4
;; 5
;; 6
;; 7
;; 8
;; 9
nil
notice, that it still expects the return macro to be called in tail position (similar to recur in loop macro)
(dotimes+ [x 4]
(println "attempt" (inc x))
(let [answer (read-line)]
(println "answer is:" answer)
(if (= answer "yes")
(return "YEAH!!!")
(println "WRONG!"))))

Clojure idioms: sanely pass function-value pairs

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)

clojure.algo.monad strange m-plus behaviour with parser-m - why is second m-plus evaluated?

I'm getting unexpected behaviour in some monads I'm writing.
I've created a parser-m monad with
(def parser-m (state-t maybe-m))
which is pretty much the example given everywhere (here, here and here)
I'm using m-plus to act as a kind of fall-through query mechanism, in my case, it first reads values from a cache (database), if that returns nil, the next method is to read from "live" (a REST call).
However, the second value in the m-plus list is always called, even though its value is disgarded (if the cache hit was good) and the final return is that of the first monadic function.
Here's a cutdown version of the issue i'm seeing, and some solutions I found, but I don't know why.
My questions are:
Is this expected behaviour or a bug in m-plus? i.e. will the 2nd method in a m-plus list always be evaluated even if the first item returns a value?
Minor in comparison to the above, but if i remove the call
_ (fetch-state) from checker, when i evaluate that method, it
prints out the messages for the functions the m-plus is calling
(when i don't think it should). Is this also a bug?
Here's a cut-down version of the code in question highlighting the problem. It simply checks key/value pairs passed in are same as the initial state values, and updates the state to mark what it actually ran.
(ns monads.monad-test
(:require [clojure.algo.monads :refer :all]))
(def parser-m (state-t maybe-m))
(defn check-k-v [k v]
(println "calling with k,v:" k v)
(domonad parser-m
[kv (fetch-val k)
_ (do (println "k v kv (= kv v)" k v kv (= kv v)) (m-result 0))
:when (= kv v)
_ (do (println "passed") (m-result 0))
_ (update-val :ran #(conj % (str "[" k " = " v "]")))
]
[k v]))
(defn filler []
(println "filler called")
(domonad parser-m
[_ (fetch-state)
_ (do (println "filling") (m-result 0))
:when nil]
nil))
(def checker
(domonad parser-m
[_ (fetch-state)
result (m-plus
;; (filler) ;; intitially commented out deliberately
(check-k-v :a 1)
(check-k-v :b 2)
(check-k-v :c 3))]
result))
(checker {:a 1 :b 2 :c 3 :ran []})
When I run this as is, the output is:
> (checker {:a 1 :b 2 :c 3 :ran []})
calling with k,v: :a 1
calling with k,v: :b 2
calling with k,v: :c 3
k v kv (= kv v) :a 1 1 true
passed
k v kv (= kv v) :b 2 2 true
passed
[[:a 1] {:a 1, :b 2, :c 3, :ran ["[:a = 1]"]}]
I don't expect the line k v kv (= kv v) :b 2 2 true to show at all. The final result is the value returned from the first function to m-plus, as I expect, but I don't expect the second function to even be called.
Now, I've found if I pass a filler into m-plus that does nothing (i.e. uncomment the (filler) line) then the output is correct, the :b value isn't evaluated.
If I don't have the filler method, and make the first method test fail (i.e. change it to (check-k-v :a 2) then again everything is good, I don't get a call to check :c, only a and b are tested.
From my understanding of what the state-t maybe-m transformation is giving me, then the m-plus function should look like:
(defn m-plus
[left right]
(fn [state]
(if-let [result (left state)]
result
(right state))))
which would mean that right isn't called unless left returns nil/false.
Edit:
After looking at state-t and maybe-m source, the m-plus looks more like:
(fn [& statements]
(fn [state]
(apply (fn [& xs]
(first (drop-while nil? xs)))
(map #(% state) statements))))
But the principle is the same, (first (drop-while nil? ...) should only execute over the items that return a valid value.
I'd be interested to know if my understanding is correct or not, and why I have to put the filler method in to stop the extra evaluation (whose effects I don't want to happen).
Edit:
If I switch over to using Jim Duey's hand written implementation of parser-m (from his excellent blogs), there is no evaluation of the second function in m-plus, which seems to imply the transformation monad is breaking m-plus. However, even in this implementation, if I remove the initial (fetch-state) call in the checker function, the domonad definition causes the output of the creation of the m-plus functions, suggesting something going on in domonad's implementation I'm not expecting.
Apologies for the long winded post!

Get Clojure argument list

I want something that gives me the sequence of actual values passed to a function, similar to the arguments value in a javascript function.
I am aware that I can grab the entire function argument list using
(defn fx [& args]
args)
<= (fx {:a 1} 2)
=> ({:a 1} 2)
But this removes the arity on my function. I want to have something like
(defn fx [{:keys [a]} b]
(MAGIC_FUNCTION_THAT_RETURNS_THE_ARGS_VALUES))
<= (fx {:a 1} 2)
=> ({:a 1} 2)
Is it possible to get a raw sequence of the values passed to a function?
By the time the function body is executed, the parameters have already been destructured. You could define your own defn macro and expose those values. I know Lighttable does this in their Instarepl to show the argument values.
Using argument destruction can help. The following works fine for me (as far as I know, it also works for old versions of clojure).
(defn example [ & [a b :as args]] [a b args])
(example 1 2)
=> [1 2 (1 2)]
The key point is that you can destruct the argument after &. The drawback is that it is possible to call the function with more arguments than expected (for example (example 1 2 3) is a valid invocation. Special care should be taken if this might be a problem.
Note: I came across this question while I was searching for similar feature. I kept digging and using an idea from here and :as as it was suggested in this answer, I found a solution for my problem.
I don't know of a way to do this as you describe, but depending on what you're wanting to do there are some options.
If you're wanting to ensure the function is only called with two arguments, consider a precondition:
(defn fx [& args]
{:pre [(= 2 (count args))]}
args)
user=> (fx 1 2)
(1 2)
user=> (fx 1 2 3)
AssertionError Assert failed: (= 2 (count args)) user/fx (NO_SOURCE_FILE:1)
If you're wanting to keep track of your intended arity of a function, but still have access to a vector of all args, you could add your own metadata:
(defn
^{:my.ns/arglists '([{:keys [a]} b])}
fx [& args]
args)
user=> (fx 1 2)
(1 2)
user=> (-> #'fx meta :my.ns/arglists first)
[{:keys [a]} b]
If you're just wanting access to the destructured values you described and access to an args value, you could use let:
(defn fx [{:keys [a]} b]
(let [args [{:a a} b]]
[a b args]))
user=> (fx {:a 1 :c 3} 2)
[1 2 [{:a 1} 2]]
user=> (fx {:a 1 :c 3} 2 4)
ArityException Wrong number of args (3) passed to: user$fx clojure.lang.AFn.throwArity (AFn.java:437)
You could also do a combination of these.
Not very nice as it requires to pass params as a vector, but seems apt
user.main=> (defn fx [[{:keys [a] :as e} b :as o]] [a b e o])
#'user.main/fx
user.main=> (fx [{:a 1} 2])
[1 2 {:a 1} [{:a 1} 2]]
user.main=>
You can use a macro to bind the arguments to symbol, _args in this example.
(defmacro defn-args [name args & body]
`(defn ~name ~args
(let [~'_args ~args]
~#body)))
You can then use _args in the body of the function to refer to the arguments:
user> (defn-args foo [{:keys [a b]} y z] _args)
user> (foo {:a 1 :b 10} 2 3)
[{:a 1, :b 10} 2 3]
This is the best I could cook up.
(def ^:dynamic *arguments* nil)
(defn unstructure [form]
(cond
(or (vector? form) (map? form)) (gensym)
(= form '&) '&
:else form))
(defmacro bind-args-defn [name args & body]
(let [simple-args (vec (map unstructure args))
i (.lastIndexOf simple-args '&)
[h r] (split-at (if (neg? i) (count simple-args) i) simple-args)
r (drop 1 r)]
`(defn ~name
~simple-args
(binding [*arguments* (lazy-cat ~#(map vector h) ~#r)]
(let [~args *arguments*]
~#body)))))
(bind-args-defn ;;my special val binding defn
silly ;;the name
[{:keys [a]} [b & c] & d] ;;the arg vector
{:vals *arguments* :a a :b b :c c :d d}) ;;the body
Obviously, this does not accept the full set of defn options (metadata, docstring, pre and post, arities, etc) that can be passed to defn, but I think it illustrates the idea.
It works by capturing the args vector, and then creating a simple-args vector of the same length as the original args but with no destructuring; using that as the defn argument vector. It then massages this simple-args vector into a sort of flat vector without &, which it assigns to *arguments*. *arguments* is then destructured using the original args vector. Kind of convoluted, but it does what I want at the moment.
> (silly {:a 1} [2 3 4] 5 6)
{:vals ({:a 1} [2 3 4] 5 6), :a 1, :b 2, :c (3 4), :d (5 6)}

Better way to nest if-let in clojure

Say I have a map of this form:
(def m {:a "A" :b "B"})
and I want to do something if :a and :b are both not nil, I can do:
(if-let [a (:a m)]
(if-let [b (:b m)]
... etc ))
or
(if (and (:a m) (:b m))
(let [{a :a b :b} m]
... etc ))
or even
(if (every? m [:a :b])
(let [{a :a b :b} m]
... etc ))
Is there a neater (ie one-line) way to achieve this?
I think a macro may be necessary here to create the behavior you want. I have never written one (yet) but the following representation suggests to me that this might be fairly straightforward:
(let [{:keys [a b]} m]
(when (every? identity [a b])
(println (str "Processing " a " and " b))))
Using the :keys form of destructuring binding and every? enables a single specification of a vector of keys to destructure and check, and the bound locals are available in a following code block.
This could be used to make a macro such as (when-every? [keys coll] code-with-bindings)
I may update this answer with the macro code if I can take the time to work out how to do it.
You could use map destructuring -- a useful feature of Clojure. This also exploits the facts that and is short-circuiting, and any key in the first map not found in the second map gets nil, a falsy value:
(let [{a :a b :b} {:a 1 :b "blah"}]
(and a b (op a b)))
Okay, so it's two lines instead of one .... also this doesn't distinguish between nil and other falsy values.
not-any? is a nice shortcut for this:
user> (not-any? nil? [(m :a) (m :b)])
true
user> (not-any? nil? [(m :a) (m :b) (m :d)])
false
user>
I am not quite sure what you want to do if the keys have non-nil values or whether you want non-nil keys or values returned. So, I just solved it for non-nil keys being returned.
You'd use the following as an intermediate step as part of a final solution.
I'm showing all the steps I used, not to be pedantic, but to provide a complete answer. The namespace is repl-test. It has a main associated with it.
repl-test.core=> (def m {:a "A" :b "B" :c nil})
#'repl-test.core/m
repl-test.core=> (keys m)
(:a :c :b)
and then finally:
; Check key's value to determine what is filtered through.
repl-test.core=> (filter #(if-not (nil? (%1 m)) (%1 m)) (keys m) )
(:a :b)
By the way I found an ugly one-liner, which works because and returns the last thing in its argument list if they're all true:
(if-let [[a b] (and (:a m) (:b m) [(:a m)(:b m)])]
(println "neither " a " nor " b " is falsey")
(println "at least one of " a " or " b " is falsey"))