Lol I love how destructuring on the sequential order instead of the names takes care of a suite of problems I regularly see in JS.
Clojure does both array and map destructuring, if that’s what you’re referring to:
(defn foo [{:keys [foo]}]
foo)
(foo {:foo 42})
(defn bar [[_ bar]]
bar)
(bar [10 40])
2😄> Does what I was looking for. There’s little documentation on the cap function. What does it do?
cat
is a transducer (https://clojure.org/reference/transducers). I like to think of it as just the cat
part of mapcat
or concat
.
> Actually I should have used (apply concat coll), works as well
Yeah, there are many ways to skin this cat (pun intended, I guess): https://web.archive.org/web/20190925191622/http://chouser.n01se.net/apply-concat/
apply concat
works, but doesn't return a vector. You can vec
it, of course, but then there's little reason to use it over into [] cat
.
If you don't actually need a vector, then you can also do either (sequence cat [[[1 2 3]] [[12 13 14] [10 50 60]]])
to get a lazy seq or (eduction cat [[[1 2 3]] [[12 13 14] [10 50 60]]])
to get an eduction, depending on what you need. Transducers are nice in that they are performant and they compose well.
But yes, apply concat
is another option, as is mapcat identity
, or mapcat seq
, etc.
is there a way to make leiningen automatically update pom.xml whenever there are changes to the project dependencies?
Consider this? <https://github.com/liquidz/antq>
this will update your pom.xml and your project.clj too 🙂
that's in a bit different direction... i'm using lein-ancient currently for that purpose and it's alright
my issue is that when somebody on the team changes/adds dependencies in project.clj they have to manually do a lein pom afterwards
which is prone to be forgotten
thus i'd want to automate updating pom.xml but i have no idea how
antq can update the pom directly, by excluding others
<https://github.com/liquidz/antq#--skipproject_type>
also, if you were to use antq, for example, then it would update the project.clj and the pom.xml too
alternatively, you could have a git commit hook (assuming you are using git) that would invoke the update to the pom (via lein or antq) before committing.
thanks, i'll give it a try
but as i said, the issue isn't really about keeping dependencies up to date, it's about keeping pom.xml and project.clj in sync without any manual intervention
:thumbsup: 🙂
Perhaps a git hook might help?
that has occurred to me, but i find git hooks really difficult to share across the team.
do you know a way that could be overcome? (eg i can't check .git/hooks/pre-push in)
Based on a quick browse through google, I believe git > 2.9 supports defining the location of the hooks -> you can create a directory for them and commit them. I haven’t tried this, but it might be what you’re looking for.
https://chamikakasun.medium.com/how-to-share-git-hooks-with-the-team-37424603dd91
i think i've seen that too, but i couldn't get a repo-local config of that working
How would you write the Python example at the bottom idiomatically in Clojure? I guess you could use
(apply merge-with <some-custom-func> (into {} [[1, 2], [1, 4], [2, 5], [2, 4]]))
But can I get away with using a built-in function?
from collections import defaultdict
l = [[1, 2], [1, 4], [2, 5], [2, 4]]
d = defaultdict(list)
for (parent, child) in l:
d[parent].append(child)
print(dict(d.items()))
# {1: [2, 4], 2: [5, 4]}
(doc group-by)
Derp. It is a function I know inside out 😳
So the solution is group-by
then merge-with
.
I am sure someone can do it moar purdy:
(def l [{:a 1 :b 2} {:a 1 :b 3} {:a 4 :b 5}])
(def g (group-by :a l))
(zipmap (keys g) (for [l (vals g)] (flatten (for [{:keys [a b]} l] [b]))))
;; {1 (2 3), 4 (5)}
user=> (def l [[1, 2], [1, 4], [2, 5], [2, 4]])
user=> (reduce (fn [m [k vs]] (assoc m k (mapcat next vs))) {} (group-by first l))
{1 (2 4), 2 (5 4)}
1🙏or (reduce (fn [m [k vs]] (update m k conj vs)) {} l)
, don’t even need the group-by
I love this answer. The fact that I can conj to nil Haskell-style and get a list is going to make much of my code cleaner.
1😊Sorry if this is the wrong channel... Garden/Spade specific. I'm trying to get started with the re-frame template and I included garden+spade but I can't figure out how I would set a hover
attribute for my links 😄 any tips? https://gist.github.com/Sose/79e79d9b37efdbfe50cb202d94c3e3c7 or if anyone knows any example projects online that use garden+spade so I could dig around their code
okay, I figured it out with help from https://libraries.io/clojars/hendekagon%2Fgarden ... it's [:&:hover {:color :blue}]
With a modern OS, if you use the right IO API (the one java nio uses), time isn't wasted on threads waiting on IO - the IO call suspends the thread and the completion of the IO is the kernel's signal to wake the thread. the hard part from a developer point of view is managing the inter thread coordination (clojure's immutability helps make that a lot simpler, core.async can help too if used correctly)
the book Java Concurrency In Practice can help a lot if you are planning on micro-optimizing concurrent code https://jcip.net/ - it's a really counter intuitive domain and unless you are already experienced with concurrency, the optimizations you end up needing are likely not to look like the ones you are imagining right now.
for truly high throughput situations the dominating concerns end up being things like cache usage and playing nicely with speculative execution
just a small thing - take
is redundant on repeatedly
- you can replace (take n (repeatedly f))
with (repeatedly n f)
with those changes:
(defn random-string-list
[list-length string-length]
(repeatedly list-length
(fn []
(apply str (repeatedly string-length
#(rand-nth letters))))))
my hunch (or vague recollection of the actual explanation) is that things that act like entities coming as first arg works with message passing / OO conventions from smalltalk (as later adapted by java, c++ and friends) (message thing arg)
and things that act like collections coming last (action parameter things)
works with data processing idioms coming from lisp (map, filter, etc. etc.) - for me personally the flip in order helps me categorize them as they are different idioms of programming
as the RH quote above describes, both idioms existed in common lisp with the introduction of CLOS (the OO system for common lisp), and clojure just follows along
1fun trivia, many don't realize that common lisp was one of the first few languages with a full featured object system
a note: there's no such thing as a "clojure regex" - on the jvm clojure uses java regex, in cljs clojure uses javascript regex - this is the best cross platform regex guide I've found and I return to it often: http://www.regular-expressions.info/ - it has great comparison of the featureset / syntax of various regex systems (from grep, ed, sed, java, perl, c ...)
bad site design / UI, but top quality info that's well organized once you figure out how it's meant to be navigated
As a beginner, Instarepl looks really helpful and I would love it if there were a new maintainer https://github.com/LightTable/ClojureInstarepl
> doesn't work for deeply nested elements, 2 levels is the max if you actually need this, tree-seq is probably the easy way to do it
(->> [[1 2 3] [[4 5 6]] [[[7 8 9]]]]
(tree-seq coll? identity)
(filter #(and (vector? %)
(number? (first %)))))
([1 2 3] [4 5 6] [7 8 9])
of course you can throw vec
on the end if the result needs to be a vector
isn't that what i did above?
my apologies - my eyes blur and I lose cognitive function when I see "flatten" in code
no worries, yours is much cleaner
oh I see now, you put the filtering logic inside the tree-seq child predicate
kind of
yes, i prefer your way, shows that i lack experience =)
I think you can get this functionality in a few other editors — but automatic evaluation is normally disabled because it can be fairly awkward to use (it will often trigger while you’re editing code and evaluate an “incomplete” expression which could well do something unexpected or unwanted) and it only saves you one key chord in most editors anyway since eval form / eval top-level form is usually just a hot key operation.
What editor are you using @rob370?
@noisesmith mind enlightening why flatten is that bad? :)
In clojure it's an antipattern because it's so common to use vanilla sequential structures to hold data, and a flatten
(as in clojure.core/flatten) call in your processing eliminates this structure.
(unless the sequential data is inside a hash-map or whatever to dead-end the recursive flatten)
flatten is extremely slow and tends to encourage / facilitate poor design
Got it, time to play with tree-seq and clojure.walk
Does the Java standard library contain an impl of top-k (C++ calls it std::partial_sort
)?
Edit: Looking for a more efficient equivalent of #(take %2 (sort %1))
I solved this problem with a bounded size heap: <https://github.com/dpsutton/heap-keep/>
As a transduction no less. Thanks! Was wondering if the Java std lib had it, because it's a (relatively) common operation.
That being said, the Priority Queue does much of the heavy-lifting, so that's good to have.
yeah. and you can take the idea. i think the priority queue can give you an unordered array or collection of items or you can drain the heap and have sorted results. it's essentially bounded heap sort in that way
1✔️Seems like this would fit right-in, in xforms
:
https://github.com/cgrand/xforms
I’m using IntelliJ with Cursive, but I guess the thing that seems really valuable to me is more just seeing the flow of data through the program moreso than evaluating with a keypress vs. not https://www.youtube.com/watch?v=H58-n7uldoU
I don’t think that feature ever made it into a released version of LT — by the time it got out into the wild, it was pretty much a “regular editor” and a lot of the cool features shown off in the early videos had been dropped 😐
is it okay to use unicode characters for variable/function names? like, using xᵢ
and xᵢ₊₁
?
@julian608 As wise people say. Always code as if the guy who ends up maintaining your code will be a violent psychopath who knows where you live.
4➕1😆Why would you want to do that though?
I think it would be useful for implementing mathematical formulas
I don't even know how to write subscript characters, imagine what people gonna feel using or modifying your code.
that's a valid point
for example, in your in-lined variable above i could barely read the subscript characters, they are so small
they mess up the monospace font in my editor, too... I think I'll avoid using them. but what about greek letters for angles?
same thing, nobody wants to write code copy pasting from a character table
we don't have greek keyboards
Well, some of us do 😛 Personally speaking, I wouldn't feel too comfortable working on a project that used unicode like that. Ligatures might be an ok compromise, if your editor supports them. That way, you could type out ascii but you'd end up seeing unicode.
1look at how https://github.com/sicmutils/sicmutils is rendering to latex, maybe useful to you
Thank you all, great help and discussion
1. What do I do, when I have a n-arrity function and I want to apply partially first other argument than the first? 2. How to pass an argument as the regex, into (str/split <string> <regex>)? I would like to wirte something like this, in which I face (2.)
(defn split-reg [filename reg]
(->
(str/split filename #reg)
(second)))
Then, I want to apply this function in the following manner, in which I think of (1.):
(map #(split-reg % "my-regex") <coll>)
I don't believe you can pass the literal syntax. e.g #"..." directly as an argument. There are a couple libraries that seem to get around this limitation, but i wouldn't jump to them if you only have a couple cases.
^ wrong see sean corfields response below
Some useful termonology: https://clojure.org/reference/reader#_dispatch The dispatch macro causes the reader to use a reader macro from another table, indexed by the character following The dispatch character is # and the next character in this case is " so it knows it's a regex.
regel is a library that would allow for the functionality you want https://github.com/lambdaisland/regal
You could either pass the literal regex in as #"my-regex"
or you could call re-pattern
on a string to turn it into a regex: (re-pattern "my-regex")
(although there are some caveats about special characters).
So your call would be (map #(split-reg % #"my-regex") <coll>)
in the first case — which would be the preferred way to do things.
My patterns are all numbers and/or letters, generally upper-case. But, I wish to apply it to a lot of different patterns. That would nicely work with re-pattern, I suppose?
Yes, if the pattern is a variable string coming from some other code, that would be the better approach.
(defn split-reg [filename reg]
(second (str/split filename (re-pattern reg))))
(map #(split-reg % some-string) some-coll)
dev=> (clojure.string/split "This is a string!" (re-pattern " "))
["This" "is" "a" "string!"]
That did work great!
(defn split-reg [filename reg]
(->
(str/split filename (re-pattern reg))
(second)))
#'user/split-reg
$ ls |> (map #(split-reg % "teste"))
("1.txt" "2.txt" "3.txt")
Thank you!1Is their a way I can do this:
(defn format-element [element]
(cond->> (re-matches #"^:\w+$" element)
(to-register)
(re-matches #"^(:\w+)\[(\d+|\w+)?\]" element)
(to-reg-array)))
I tried (some->>
as well.
I want to take a string and do a regex on it, then depending on what re-matches it matches against, pass the resulting matches to a function to format it.What I'm trying to avoid is having to do the regex match twice, once to match to know if the string matches then again to get access to the actual matches
I have this, but feels clunky
(def matchers-and-formatters {#"^:\w+$" to-register
#"^(:\w+)\[(\d+|\w+)?\]" to-reg-array})
(defn format-element [element]
(loop [matchers (keys matchers-and-formatters)
formatters (vals matchers-and-formatters)]
(if (seq matchers)
(let [res (first (re-matches (first matchers) element))]
(if res
((first formatters) res)
(recur (rest matchers) (rest formatters))))
element)))
(defn format-element [el]
(some (fn [[rx fmt]]
(when-let [match (first (re-matches rx el))]
(fmt match)))
matchers-and-formatters))
(untested)That seems to work and is nice! I wasn't aware of when-let, I'll need to go read and understand this. Thank you!
1👍if you care about the captures, don't throw them away by calling first
i.e. pass the whole result of re-matches
to the formatter
(defn format-element [el]
(some (fn [[rx fmt]] (some-> (re-matches rx el) fmt))
matchers-and-formatters))
1👍1❤️and let the formatter destructure
Man, i have so much to learn. That's so concise
Thanks for the help guys, i have stuff to look up (Y)