(defn recurse
[temp total] ;total is: (and true true(and false))
(map (fn [i]
(cond
(seq? i) (println "");If total is not a single parenthesis (single sequence), recur until it is
(= i 'and) (System/exit 0) ;I want this to be called only when the **second** "and" is called
:else (println "This should never print I think")
))
idealreturn)
)
I want (System/exit 0) to be called only when the second "and" is detected in total and not before. How would I go about doing this?
You are on the right track with mapping a function over the data to transform it. There are a couple of ways to get what you are looking for:
Don't use map, and use reduce instead. Reduce is for building up state over time. So you could reduce it into an expression, and each time you encounter an and, you look to see if there is already an and in the result you are building up, and if that and is already there, call the exit.
Have the function you are mapping over the input do only one thing, convert single items into more meaningful things. Then once it is done, pass that result to a second function that checks if it's time to exit.
Giving each thing one responsibility makes for code that's much easier to write, and composing them afterwords is efficient and easy. It's also much easier on you later when you come back to work on the code later.
Related
I'm writing a re-frame app that models a board game where I have a board structure containing an array of cells, something like:
{... :board-cells [{:name "cell-1" :material #object} {:name "cell-2" :material #object} ...]}
While re-frame supports the getting of "natural" substructures with a nice keyword syntax like (db :board-cells), I'm getting tired of having to write the entire "drill-down" query every time I want to get a material: (get (nth (db :board-cells) index) :material). This also has the downside of tightly coupling the physical layout of my db to my application logic. What if I decide to change my db structure? Then I have to update ten different spots instead of just one.
Is there a re-frame official way to create a "virtual query" so I can get a material with something like (db :get-nth-mat n), where n is the cell number within the board-cells array? I thought that db.cljs and reg-sub was where I could do this, but it doesn't seem to work. Yes, I can create my own getter:
(defn get-material [db index]
(get (nth (db :board-cells) index) :material))
and call it like (println "mat-4=" (cell/get-material db 4)), but this isn't as convenient or nice as (db :get-nth-mat n)
Many thanks.
db is just a map and this "feature" there has nothing to do with
re-frame, but every map is a function and so are keywords. So when you
do (map something) or (:keyword something) you are actually doing
(get map something) and (get something :keyword).
So there really is no "shortcut" other than accessing/iterating your
data differently (e.g. doseq, for, map, ...) - assuming you are
about to render the grid cell by cell; This way you get rid of the
index based access at all.
Otherwise I'd use a dedicated function like yours, but would rather name
it material-by-idx (it's rather uncommon to name function get and
set like accessors in OO (but there are places for it like e.g.
set for state modification)).
Having properly named, ideally pure, functions, that do one thing
properly is an important building block in functional and Lisp
programming. And often the downside of having to type a bit more can be
mitigated by higher level programming paradigms like threading or partial
application or as last resort, macros.
And you can use get-in to unclutter it a bit:
(defn material-by-idx [db idx]
(get-in db [:board-cells idx :material]))
E.g. you could now in your loop use something like this, if you see
value in that:
(let [mat-at (partial material-by-idx db)]
(mat-at 5))
Btw: The version you are wishing for (db :get-nth-mat n) actually
works (but not as you wish for). It turns into (get db :get-nth-mat
n) (3 argument get), which returns you n if there is no key
:get-nth-mat in db.
I have a web service written in Clojure. It has a simple GET method implemented, which returns back a JSON object representing the router's current position and different time counters.
My code has a bunch of atoms to keep track of time. Each atom represents different activities a machine might be doing at a given time. For example: calibrating, idle, stuck, or working:
(def idle-time (atom 0))
(def working-time (atom 0))
(def stuck-time (atom 0))
(def calibration-time (atom 0))
Towards the end I have a loop that updates the position and time counters every 15 seconds:
(defn update-machine-info []
(let [machine-info (parse-data-files)]
(update-time-counters machine-info)
(reset! new-state (merge machine-info
{:idleCounter #idle-time
:workingCounter #working-time
:stuckCounter #stuck-time
:calibrationCounter #calibration-time}))))
(loop []
(future
(Thread/sleep 15000)
(update-machine-info)
(recur)))
Currently this code runs into race condition, meaning the position and time counters are not updating. However, the Web Service still responses back a proper JSON response, albeit with old values.
Web Service is using Cheshire to generate map into JSON, here my GET implementation:
(defroutes app-routes
(GET "/" [] (resource :available-media-types ["application/json"]
:handle-ok (generate-string (get-machine-information))))
(route/not-found "Not Found"))
Should I be using refs instead of atoms? Am I using future correctly? Is (Thread/sleep 15000) causing the issue, because atoms are async?
Please let me know if you see an obvious bug in my code.
I don't think you can reliably recur inside a future to a loop that's outside the future (not completely sure), but why not try something like this instead?
(future
(loop []
(Thread/sleep 15000)
(update-machine-info)
(recur)))
That way loop/recur stays within the same thread.
Other than that, it's possible that if update-machine-counters throws an exception the loop will stop, and you'll never see the exception because the future is never dereferenced. An agent ( http://clojure.org/agents ) might be better suited for this, since you can register an error handler.
I think what is happening is that the process where you call your futures is terminating before your futures actually execute. For what your doing, futures are probably the wrong type of construct. I also don't think your loop future recor sequence is doing what you think.
There is a lot of guesswork here as it isn't clear exactly where you are actually defining and calling your code. I think you probably want to use something like agents, which you need to setup in the root process and then send a message to them in your handler before you return your response.
I have a function that is iterating over a moderately sized list of strings and is looking through some JSON returned from a server for the existence of a value in the data. The code will be run many times, so I want it to be fast. Is there any way I can return as soon as I find the value I'm looking for?
(defn find-type [js-data-set]
(doseq [type all-type-strs]
(when (aget js-data-set type)
(return true)))) ; is there a way to do this?
The built-in some function will find the first value matching a predicate, which fits this case rather nicely. More generally, you can use loop / recur, though that's rarely the most idiomatic option.
(defn find-type [js-data-set]
(some #(goog.object/get js-data-set %) all-type-strs))
I am trying to determine whether a given argument within a macro is a function, something like
(defmacro call-special? [a b]
(if (ifn? a)
`(~a ~b)
`(-> ~b ~a)))
So that the following two calls would both generate "Hello World"
(call-special #(println % " World") "Hello")
(call-special (println " World") "Hello")
However, I can't figure out how to convert "a" into something that ifn? can understand. Any help is appreciated.
You might want to ask yourself why you want to define call-special? in this way. It doesn't seem particularly useful and doesn't even save you any typing - do you really need a macro to do this?
Having said that, if you are determined to make it work then one option would be to look inside a and see if it is a function definition:
(defmacro call-special? [a b]
(if (#{'fn 'fn*} (first a))
`(~a ~b)
`(-> ~b ~a)))
This works because #() function literals are expanded into a form as follows:
(macroexpand `#(println % " World"))
=> (fn* [p1__2609__2610__auto__]
(clojure.core/println p1__2609__2610__auto__ " World"))
I still think this solution is rather ugly and prone to failure once you start doing more complicated things (e.g. using nested macros to generate your functions)
First, a couple of points:
Macros are simply functions that receive as input [literals, symbols, or collections of literals and symbols], and output [literals, symbols, or collections of literals and symbols]. Arguments are never functions, so you could never directly check the function the symbol maps to.
(call-special #(println % " World") "Hello") contains reader macro code. Since reader macros are executed before regular macros, you should expand this before doing any more analysis. Do this by applying (read-string "(call-special #(println % \" World\") \"Hello\")") which becomes (call-special (fn* [p1__417#] (println p1__417# "world")) "Hello").
While generally speaking, it's not obvious when you would want to use something when you should probably use alternative methods, here's how I would approach it.
You'll need to call macroexpand-all on a. If the code eventually becomes a (fn*) form, then it is guaranteed to be a function. Then you can safely emit (~a ~b). If it macroexpands to eventually be a symbol, you can also emit (~a ~b). If the symbol wasn't a function, then an error would throw at runtime. Lastly, if it macroexpands into a list (a function call or special form call), like (println ...), then you can emit code that uses the thread macro ->.
You can also cover the cases such as when the form macroexpands into a data structure, but you haven't specified the desired behavior.
a in your macro is just a clojure list data structure (it is not a function yet). So basically you need to check whether the data structure a will result is a function or not when it is evaluated, which can be done like show below:
(defmacro call-special? [a b]
(if (or (= (first a) 'fn) (= (first a) 'fn*))
`(~a ~b)
`(-> ~b ~a)))
By checking whether the first element of the a is symbol fn* or fn
which is used to create functions.
This macro will only work for 2 cases: either you pass it a anonymous function or an expression.
I'm new in clojure, i try create functions thats will be sort collections and store it in object.
My code:
(defn uniq [ilist]
([] [])
(def sorted (sort ilist)))
I try to run it:
(uniq '(1,2,3,6,1,2,3))
but get error:
#<CompilerException java.lang.IllegalArgumentException: Key must be integer (NO_SOURCE_FILE:0)>
What's wrong?
Thank you.
As with your other question, you're trying to use pattern-matching where it just doesn't apply. Your function would work fine1 if you deleted the ([] []) entirely.
1 You also shouldn't use def here; as the other respondents have noted, you want to use let for establishing local bindings. However, here you don't need any bindings at all: just return the result of the sort call. In fact, the def will cause you to return a Var instead of the actual sorted list.
Since there's no need at all to use either 'let' or 'def', I have to agree with amalloy about Bart J's answer. Sure it warrants the upvotes because it's useful info, but it's not the right answer.
Actually, defining the function is kind of useless, since (sort ilist) would do the trick. The result of the function is the 'object' you want. That is, unless you want to use the result of the sort multiple times at different places in the function body. In that case, bind the result of sort to a function local variable.
If you only need the sort once, don't bother binding it at all, but just nest it inside other functions. For instance if you want to use it inside a unique function (which I guess is what you're wanting to do):
(defn uniq
"Get only unique values from a list"
[ilist]
; remove nils from list
(filter #(not(nil? %))
; the list of intermediate results from (reduce comppair sortedlist)
; (includes nils)
(reductions
; function to extract first and second from a list and compare
(fn comppair
[first second & rest]
(if (not= first second) second))
; the original sort list function
(sort ilist))))
(uniq '(1,2,3,6,1,2,3))
(1 2 3 6)
Then again, you could also just use the built-in distinct function, and take a look at it's source:
(distinct '(1,2,3,6,1,2,3))
(1 2 3 6)
(source distinct)
(defn distinct
"Returns a lazy sequence of the elements of coll with duplicates removed"
{:added "1.0"}
[coll]
(let [step (fn step [xs seen]
(lazy-seq
((fn [[f :as xs] seen]
(when-let [s (seq xs)]
(if (contains? seen f)
(recur (rest s) seen)
(cons f (step (rest s) (conj seen f))))))
xs seen)))]
(step coll #{})))
To store the sorted collection into a variable do this:
(let [sorted (sort your-collection)])
To understand the difference between a let and a def, this should help:
You can only use the lexical bindings made with let within the scope of let (the opening and closing parens). Let just creates a set of lexical bindings. def and let do pretty much the same thing. I use def for making a global binding and lets for binding something I want only in the scope of the let as it keeps things clean. They both have their uses.