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])
> 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)}
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.
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}]
As a beginner, Instarepl looks really helpful and I would love it if there were a new maintainer https://github.com/LightTable/ClojureInstarepl
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?
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
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.
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.
look at how https://github.com/sicmutils/sicmutils is rendering to latex, maybe useful to you
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!Is 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!
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))
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)