This page is not created by, affiliated with, or supported by Slack Technologies, Inc.
2019-09-26
Channels
- # announcements (2)
- # babashka (9)
- # beginners (95)
- # calva (4)
- # circleci (2)
- # clj-kondo (5)
- # clojure (57)
- # clojure-berlin (2)
- # clojure-conj (3)
- # clojure-europe (6)
- # clojure-italy (14)
- # clojure-nl (3)
- # clojure-switzerland (5)
- # clojure-uk (32)
- # clojuredesign-podcast (5)
- # clojurescript (29)
- # clojutre (16)
- # code-reviews (6)
- # data-science (6)
- # datomic (9)
- # fulcro (33)
- # graalvm (2)
- # jobs (1)
- # jvm (1)
- # kaocha (6)
- # leiningen (4)
- # off-topic (3)
- # re-frame (31)
- # reagent (16)
- # reitit (22)
- # remote-jobs (2)
- # shadow-cljs (70)
- # spacemacs (19)
- # sql (9)
- # tools-deps (13)
- # xtdb (2)
- # yada (3)
hi. I've just started using Cursive. What is the equivalent ctrl+shift+f
command to format code? What does the default ctrl+alt+l
do?
seems to be only for consistent indentation? Using it for this doesn't do anything..
(+
3
2)
I'm following 4-clojure right now, and I'm just being OC about this example (= 8 ((fn add-five [x] (+ x 5)) 3))
... seems not formatted for readability.
This and many other 4Clojure tests are single and relatively short expressions. You will see lots of these in the 4Clojure challenges.
This particular example is a function call to =
with two arguments, so there is a case for saying there is little room for additional formatting.
In my own 4Clojure examples I do format function definitions, but tend to leave simple expressions on one line https://github.com/practicalli/four-clojure I have a number of 4Clojure walk throughs on my YouTube channel if it helps http://yt.vu/+practicalli
looks like there isn't a gofmt
for clojure yet? I guess I have to ignore this for now
With Cursive (and IntelliJ in general for that matter) just hit the Shift key twice to bring up a search dialog which allow you search for (amongst other things) commands. Against each it'll also display the shortcut key (if any). In your case it's probably Ctrl+Alt+L.
Also, on a related note if you're new to Cursive you might find the commands under structural code menu useful. (Edit->Structural Editing).
Unfortunately there's not! cljfmt
is the closest available currently, but it will only fix indentation, not "opinionated" things like the line breaks in your examples.
@thirdy.derivera Cursive generally formats stuff according to the Clojure Style Guide (subject to any customizations you might make in the Preferences), but it won’t do things like condensing vertical spaces like in your example. And I agree, your 4clojure example could definitely use some nicer formatting.
Here’s the style guide link for anyone who might not have it: https://github.com/bbatsov/clojure-style-guide
This and many other 4Clojure tests are single and relatively short expressions. You will see lots of these in the 4Clojure challenges.
This particular example is a function call to =
with two arguments, so there is a case for saying there is little room for additional formatting.
In my own 4Clojure examples I do format function definitions, but tend to leave simple expressions on one line https://github.com/practicalli/four-clojure I have a number of 4Clojure walk throughs on my YouTube channel if it helps http://yt.vu/+practicalli
hi people, I'm having some good time with dates in clojure. There are some corner cases that is killing me. I created a function to convert # inst (java.util.Date) to java.time.LocalDate
(defn date->localdate
"Convert #inst objects into java.time.LocalDate."
[date]
(-> date
(.toInstant)
(.atZone (ZoneId/systemDefault))
(.toLocalDate)))
when I try to convert #inst "1550-12-31T23:59:59.999-00:00"
I get a localDate of "1551-01-10"I tried to use clj-time.coerce
to see if I did something wrong and to my surprise they also provide the same answer
ok, I found an explanation https://stackoverflow.com/questions/23975205/why-does-converting-java-dates-before-1582-to-localdate-with-instant-give-a-diff
It is because of Pope Gregory! 🙂
Imagine, there were 150 years of countries neighboring each other in Europe where their calendars were 10 days off from each other, and different countries switched in different years. Must have been a pain in the neck.
why can’t time be the same everywhere
A lot of Eastern Orthodox churches are still on the Julian calendar, which is why they celebrate Christmas in January.
Hello. I'm writing tests and wondering something that has vexed me before. If I have a series of pure functions that are called to build up a larger map, each one acting on different values, but each function outputting something possibly different depending on the previous value and possibly another thing passed in (let's say a config).
(defn get-large-map
[config]
(->> {}
(a config)
b
(c config)
(d config)
e
f
(g config)))
Maybe this comes down to personal style/taste, but I can't figure out the best way to go about writing tests for this code.
Do I write tests for each function in the chain, covering each output case for that function, and then also write a test for the different overall outputs of get-large-map
? My concern is that when I write a test for the output of b
, if checking against the whole map outputted, I'm also testing a
again, and so on with each successive function in the chain. Then later if I change something in the way a
outputs, it likely will break the tests for every function after a
, since a
is the "seed."But if I only write functions for get-large-map
against the entire outputted map, then there's no real need to test a
, b
, and so on. However, I think that one test would require several cases, and again if I change something in the way a
outputs, all those cases likely break.
Maybe each test should not be checking against the whole map outputted (a "snapshot" test), and instead be checking only the keys/values it modified?
If the purpose of b
is to add 2 keys to its input map, and pass everything else through unmodified, then it does seem that a test that passes in a map with 10 keys, and verifies that those 10 keys come through unmodified, would be an overly-detailed test of b
Also, consider that perhaps not all functions need tests.
If b
is add 2 keys to the map and pass everything through unmodified, and the keys are constant, and the values are simple functions of the input, maybe don't bother to write a test for b
. If e
is a function you have never written before, and you are not sure you understand all of the cases yet, but you think maybe you have it correct, perhaps that could use some tests, especially near the edges of your understanding.
I mean, if you are in a work environment where you are pressured to write tests for every single function, then ... maybe have a discussion with colleagues about whether they actually do that, and what they consider acceptable. If there are no team requirements here, then testing I think is best done where you think you are most likely to have mistakes.
If b
is as simple as I described, maybe you write one test case for it, and it only checks that the two new keys are present in the return value.
Yeah that makes sense. I've taken it upon myself to write these tests, and the team approves, but it's up to me how they're written. I'll try to keep it simple, like you said.
I have a complicated regex that I'd like to add some comments to, by doing something like
(re-pattern (str "\s+" ; blah
"\w+" ; blah
"etc"))
but I'm getting an error about unsupported escape characters. What's the most literate way of dealing with this?(I'm wondering if there's some way of doing this that won't require adding an extra slash for escapement to each existing slash.)
;; If you want to embed (ignored) whitespace and comments from #
;; characters until end-of-line in your regex patterns, start the
;; pattern with (?x)
user=> (re-find #"(?x) # allow embedded whitespace and comments
\\ # backslash
\d+ # one or more digits
\s+ # whitespace
\S+ # non-whitespace"
"\\ it sh0uld match in \\5 here somewhere.")
"\\5 here"
it's not like clojure implemented any of that, it's standard Java regex syntax :D it's nice though
this site is great for cross platform regex translation and features https://www.regular-expressions.info/
https://www.regular-expressions.info/javascript.html
No \A or \Z anchors to match the start or end of the string. Use a caret or dollar instead.
No atomic grouping or possessive quantifiers.
No Unicode support, except for matching single characters with \uFFFF.
No named capturing groups. Use numbered capturing groups instead.
No mode modifiers to set matching options within the regular expression.
No conditionals.
No regular expression comments. Describe your regular expression with JavaScript // comments instead, outside the regular expression string.
@csd it's documented here, if you select Java and Perl in the dropdowns for comparison you can see both support it https://www.regular-expressions.info/refmodifiers.html
sadly there's no URL anchor to link directly to a pair of langauges
😆 if you pull up Javascript on that page, it has n/a
or no
for every single feature
oh, interesting, you can get some of those features in js via a library https://www.regular-expressions.info/xregexp.html
I want to send the pprint/print-table result to a file. How would I redirect the out to a file?
with-out-str
should do the trick @hoertlehner
hahah! I had even seen this expression somewhere in my code. I assumed I wanted to remove \r\n in the strings.
(spit "file.txt" (with-out-str (clojure.pprint/pprint {:a "a" :b "b"})))
user=> (require '[ :as io])
nil
user=> (binding [*out* (io/writer "print.out")]
(clojure.pprint/pprint {:a 1 :b {:c 2 :d 3} :e 4}))
nil
user=> (slurp "print.out")
"{:a 1, :b {:c 2, :d 3}, :e 4}\n"
user=>
Any code executed inside the binding
that writes to stdout *out*
would append to that file.
(funny that we both answered with pprint
when you asked about print-table
-- but the same principles apply)
The cheatsheet is not intended to be complete documentation, but it does give a clue about this in the IO "to writer" section, to use binding
on *out*
: https://clojure.org/api/cheatsheet . and also http://jafingerhut.github.io/
@andy.fingerhut I had looked at a cheatsheet, this is where I had the idea to ask this question. Because before I looked at the source, and only saw printlns in the print-table function. So I thought that that would not be logical..
alternatively, pprint takes a writer argument and it's easy to make a string writer
user=> (let [w (java.io.StringWriter.)] (pprint {:a 0 :b 1} w) (str w))
"{:a 0, :b 1}\n"
that one doesn't work for print-table though
Hi.
How could I retreive the key of the maximum value inside a map?
I'm trying to return the most frequent element in a vector.
I've already made a frequencies map using frequencies
, but I don't know how to retrieve the key with the highest value (which whould be the most frequent element inside the original vector).
(last (keys (sort-by val freq-map)))
works.
But I'm not sure it's the best solution.
user=> (apply max-key val (frequencies [:a :b :c :a :b :a]))
[:a 3]
*edited to make the return value more clearthe return value is the key/value pair where the value had the largest number
If you had to choose only the key would you do (first (keys (apply max-key val (frequencies [:a :b :c :a :b :a])))
or the other solution?
(key (apply max-key val (frequencies ...)))
Oh, didn't know I could call just key. Thanks for the help. I'll use that.
that is probably a good candidate for ->>
pipelining instead of nesting (or let with named intermediate values)
that call to keys
would have errored because a k/v pair is more vector-like than map-like
you can use first
instead of key
or peek
, last
or second
instead of val
, but I think in this case key/val
make things clearest
I assumed key would work for a single-keyed map.
I've looked for "key" in clojure docs and it receives "e", a map entry.
Is it possible to create a map entry without creating a map?
I did is based on a few examples in the docs: (key (first {:a 1}))
right - the max-key call above returns a map-entry
you can create a map-entry via interop, but wanting to do so is probably a sign you are doing something wrong
user=> (key (clojure.lang.MapEntry. :a 0))
:a
Oh, no. I was just wondering. Thank you.
Interestingly, there's a predicate to test for such a thing -- map-entry?
-- but no matching constructor function.
based on code I've seen that attempts to use map-entries directly, my suspicion is that the reason it isn't provided is that it's not what real code needs; if your performance needs are such that you require creating a map-entry instead of a two element vector, you probably shouldn't even be writing clojure code
best case you end up with code of limited utility that acts like the idiomatic version without actually being meaningfully different
more likely you introduced tech debt / bugs
I thought it was principally used for when walking or traversing to distinguish regular vectors from key value pairs
sadly that only works with prewalk or more specifically, sadly that doesn't work for clojure.walk/postwalk, as it never creates map-entries
If you really want it, there is
user=> (map-entry? (clojure.lang.MapEntry/create 1 2))
true