hi, can someone explain how this re-gex pattern ways of working work? I tried to
(count (re-seq #"1" "1234554321112345678"))
;;=> 4
but if i do this, i got an error
(count (re-seq #(str 1) "1234554321112345678"))
;;=> Execution error (ClassCastException) at user/eval2152 (REPL:238).
class user$eval2152$fn__2153 cannot be cast to class java.util.regex.Pattern (user$eval2152$fn__2153 is in unnamed module of loader clojure.lang.DynamicClassLoader @32d7ce6f; java.util.regex.Pattern is in module java.base of loader 'bootstrap')
I tried to make function where the 1 as parameter.re-seq
can't take a function in the first position. it must be a regex. and you probably meant #(str %)
. What you wrote, #(str 1)
is a function of zero arguments which will return "1"
@dpsutton yes, i meant #(str %)
but it still gives an error
(defn asdf
[x]
(count (re-seq #(str x) "1234554321112345678")))
i think i found the answer
(count (re-seq (re-pattern (str 1)) "1234554321112345678"))
(re-pattern (str 1))
is just (re-pattern "1")
which is basically just #"1"
. you just can't use a function there just the same as you can't add two to a function (+ 1 (fn [] 3))
oh, sorry to be clear, i want to make the number 1 become parameter of a function. sorry for bad english, here's my full code
(defn asdf
[x]
(count (re-seq (re-pattern (str x)) "1234554321112345678"))
*revised(count (re-seq (re-patter x) ...)
i found that some programmer use ->>
macro like this below,
is this some preferences or something? does it has an impact to the program? because i still can't do this yet, i only use simple parentheses.
(defn nb-dig [n d]
((->> (range (inc n))
(mapcat #(str (* % %)))
frequencies)
(first (str d))))
the extra parens there causes me to do a double take. i'd use a let binding or a (get (->> ...) (first (str d)))
to make it a bit more clear what's going on there
@adrianimanuel there’s no impact to the program, it’s just a style choice.
People use it to write something that reads like A.b.c.d instead of (d (c (b A)))
If you want to see the equivalent expression you can do (macroexpand ‘(->> (range 10) (filter even?)))
@devn thank you for the explanation, i got used to (d (c (b A))) since i used ms. excel extensively lol
Excel is a fit predator!
Hi! I have a very easy noob question, that I do not find answer by googling. I've got to lists (:x :y :z) and (\x \y \z). I simply want to construct a map {:x \x :y \y :z \z}. Only thing I found was interleave, which unfortunately does not return a map. Any suggestions?
Cool! Thanks!
Hi, When should I use Java Thread and not Future? (or maybe I should ask, does it matter?) I know that in Future I can wait for the thread to finish and see the return status, and for Java Thread I can’t, right?
@alexmiller just to make sure I got it right: The Future is actually using a Java thread pool that Clojure is holding behind the scene? This pool is also used to run the go blocks. The pool default size is the num of processors, but if needed it will be larger?
Yes, Clojure future
will run on a Java thread pool in the Clojure runtime
Different pool (maintained by core.async) is used to run go blocks
The future thread pool can expand without limits but caches unused threads for a while and will reuse if possible
Thank you very much @alexmiller! Now I’ll try to go and understand the core.async thread pool 🙂 any reading material you recommend ?
I mean, it's just a thread pool, not really anything specific to read about that
🙂 Thanks
I think the javadocs are quite good here: https://docs.oracle.com/javase/7/docs/api/java/util/concurrent/Future.html https://docs.oracle.com/javase/7/docs/api/java/lang/Thread.html
What are you trying to do?
future : You can use futures to run tasks on a separate thread and then forget about them, but often you’ll want to use the result of the task. The `future` function returns a reference value that you can use to request the result. based on https://www.braveclojure.com/concurrency/ as for javathread, i didn't know bout that yet.
@emilaasa Mainly trying to understand the difference 🙂
Futures run a function on a thread
So they are not that much different
Futures use a cached thread pool though so it can be more efficient if you’re doing this a lot (will reuse the same thread if possible)
Thanks @alexmiller, Will Future run as a Java thread at the end? and the difference is only that Clojure allows to cache the result while in Thread we can’t access it?
Futures also have a useful feature - binding conveyance. The future function runs in an environment where any dynamic bindings are set like they were where you created the future
Yes, futures run on a Thread (all Clojure functions implement Runnable so can be passed directly to a thread)
Thanks, so what is this cached thread pool though
that they run on?
It’s one of two in the Clojure runtime
The other is for compute only tasks and is a fixed size pool
And FYI I wrote a whole chapter about concurrency in Clojure in Clojure Applied with more detail
In my mind a Future is a higher level concept than a Thread as well.
As in the Future represents the result of an operation, whereas a Thread might be the actual lower level construct that could get you that result.
hi! getting familiar with clojure.spec
. It's great so far. I have a question though
How can I write a spec to check if a number is a valid uint64?
considering it was fetched from a database column with this type
looks like Java doesn't support unsigned types (which is a big surprise for me)
maybe I should just use nat-int?
@gr.evocatus If it was fetched from the database as a uint64, you may find that is it a BigInt
or BitInteger
rather than a Long
(if it is the latter, it's not going to correctly hold any value larger than Long/MAX_VALUE
) -- in which case it won't satisfy nat-int?
(because 1234N
-- a Clojure BigInt
-- does not satisfy int?
, but does satisfy integer?
).
dev=> (for [pred [int? integer? nat-int? pos-int? neg-int?]
#_=> v [-100N -100 0 100 100N]]
#_=> [v (pred v)])
([-100N false] [-100 true] [0 true] [100 true] [100N false] ; int?
[-100N true] [-100 true] [0 true] [100 true] [100N true] ; integer?
[-100N false] [-100 false] [0 true] [100 true] [100N false] ; nat-int?
[-100N false] [-100 false] [0 false] [100 true] [100N false] ; pos-int?
[-100N false] [-100 true] [0 false] [100 false] [100N false]) ; neg-int?
You can interact with a thread while it runs in semi-arbitrary ways while it runs, I believe. One of the things about a future is you are effectively saying "I don't care to interact with you at all, except for you to tell me when you are done, and what result you got"
You could start a thread and pass messages / intermediate results back and forth N times, or indefinitely.
I could be off on this -- but I suspect at least most futures are created in a context that have the "limited interaction" I mention above.
Thanks everyone! I think it is time for to go and read @alexmiller chapter 🙂
well I disagree that a future may only care about the result (but that is the primary use case). I've certainly used futures to background an operation that interacted with the original thread more than once via promises.
what does clojure-lsp offer over everything in Cider?
clojure-lsp offers high quality static analysis that does not depend on a running instance of your code. this means that it can do quite a bit without running things, but it can miss things that are only apparent with an actual running instance: macros which expand to forms, run time requiring, loading of things, etc. CIDER runs in your project and can basically query all of this stuff from the repl, much like a clojure repl provides. (eg, ns-publics, doc, info, ...)
they can be quite complementary. a standout from the analysis is the clojure-lsp will perform refactorings on your code, introduce lets, extract functions, rename things, etc. CIDER can accomplish this with an extra refactor-nrepl dep, but i don't believe its quite at the level of what clojure-lsp can do
yes, they are complimentary, I would not want to program without a REPL / CIDER, however in CLJS I hardly ever use a REPL because that's too much friction for me. I rely entirely on hot-reloading (figwheel) there or for node projects I just call require
+ :reload
from a nodeJS REPL in my terminal. So clojure-lsp now provides navigation in CLJS whereas before I didn't have this at all for a long time
one feature that I believe CIDER (and maybe even Cursive?) doesn't have is finding keyword references. I demonstrate this in a Youtube video I made yesterday, towards the end.
e.g. it can find references to :clojure.string/foo
even if you write it as ::str/foo
can I write a spec to check some complex conditions like "values of map ::total are sums of values of the same keys of maps inside ::rows"?
@gr.evocatus You can write your own predicates, so you can write specs that check just about anything. I don't quite understand the data structure you are describing so can't go into more depth about how you might want to accomplish that
But how do I do it? Just something like this? (s/def ::reply (s/and (s/keys :req [::rows ::total]) #(some-complex-checks)))
yup. note that if you want to be able to generate values using (s/gen) you'll need to provide your own generator with s/with-gen
Is it possible to make an extend-type
for PersistentHasMap
and PersistentArrayMap
in one go?
it's basically the same thing
(extend-protocol Foo
clojure.lang.APersistentMap
(f [_] :foo-on-map))
worked for me(f {})
and (f (into {} (map (fn [x] [x x])) (range 1000)))
both return :foo-on-map
thx!
You really should not be extending the Clojure concrete types like that - much better to make your protocol extensible via metadata
I heard something somewhere about metadata, so I'm going to go read more
Can I find anything beyond that? https://clojure.org/reference/protocols#_extend_via_metadata
(defprotocol Foo :extend-via-metadata true (f [_]))
(defn decorate-map [m] (with-meta m {`f (fn [_] :foo-on-map)}))
(f {:a 1}) ;; error, no impl
(f (decorate-map {:a 1})) ;; :foo-on-map
that's all there is to it
also read the section right above that - https://clojure.org/reference/protocols#_guidelines_for_extension
types like APersistentMap, PersistentHashMap, PersistentArrayMap should be considered concrete implementation details inside of Clojure, not public APIs you can rely on, so you should really never be extending protocols to them. IPersistentMap is the proper generic interface, but even that I would be hesitant about as protocol extension on interfaces can open you up to diamond inheritance resolution issues
@huxley One of the things that is really nice about extending protocols via metadata is that you can use anything that supports metadata, such as a Clojure function. In next.jdbc
, it provides a function to support Stuart Sierra's Component library for creating database connection pools, and it uses a function (that returns the pool) with metadata to implement Component's stop
function: https://github.com/seancorfield/next-jdbc/blob/develop/src/next/jdbc/connection.clj#L287-L318
I'm going to start reading
thx
awesome thank you (and ty borkdude, too)
just FYI he is the author of the fantastic static analysis tool