This page is not created by, affiliated with, or supported by Slack Technologies, Inc.
2022-11-28
Channels
- # adventofcode (2)
- # announcements (4)
- # babashka (34)
- # beginners (44)
- # biff (5)
- # calva (8)
- # cider (4)
- # clj-kondo (5)
- # clj-on-windows (5)
- # clojure (57)
- # clojure-art (1)
- # clojure-denmark (2)
- # clojure-europe (40)
- # clojure-nl (1)
- # clojure-norway (6)
- # clojure-seattle (1)
- # clojure-uk (2)
- # clojurescript (20)
- # cursive (6)
- # datomic (1)
- # emacs (6)
- # events (5)
- # fulcro (22)
- # helix (5)
- # hyperfiddle (5)
- # jobs (1)
- # joyride (2)
- # lsp (8)
- # malli (8)
- # off-topic (30)
- # pathom (8)
- # pedestal (1)
- # portal (5)
- # proton (1)
- # rdf (2)
- # re-frame (4)
- # releases (1)
- # remote-jobs (1)
- # reveal (8)
- # xtdb (5)
Hello! I have a question about clojure style: Let’s say i have a seq made up of similarly structured seq-pairs, e.g:
[
[["a""b""c"][1 2 3]]
[["foo""bar""baz"][4 5 6]]
]
And I want to map through this seq, but apply a different map function for (first seq-pair) and (second seq-pair)
e.g. in the example above, i want to uppercase all the strings for the first seq and increment the numbers for the second,
getting:
[
[["A""B""C"][2 3 4]]
[["FOO""BAR""BAZ"][5 6 7]]
]
is there a built-in function to do this, or an idiomiatic way to do this?At the moment, I am mapping through the seq twice, first to handle the first seq-pair and then to handle the second seq-pair. I thought of writing a function to like map within the map, but it was feeling too obscure. It felt like I was trading readability for terseness, but also felt like there must be an existing function that does exactly this. Thank you!
Can't think of another core fn for this, or how to avoid map
s in map
s (especially with this data structure).
(mapv (fn [[ss is]] [(mapv str/upper-case ss) (mapv inc is)])
seq-pairs)
... if the functions are fairly static, otherwise something like
(mapv (fn [[fx fy] [xs ys]] [(mapv fx xs) (mapv fy ys)])
(repeat [str/upper-case inc])
seq-pairs)
What about for
and some destructuring?
(for [[v1 v2] [[["a""b""c"][1 2 3]]
[["foo""bar""baz"][4 5 6]]]]
[(mapv s/upper-case v1)
(mapv inc v2)])
=> ([["A" "B" "C"] [2 3 4]] [["FOO" "BAR" "BAZ"] [5 6 7]])
Or something like this, perhaps.
(defn bimap [[f g][xs ys]]
[(map f xs)
(map g ys)])
(let [m [[["a" "b" "c"] [1 2 3]]
[["foo" "bar" "baz"] [4 5 6]]]
fs [str/upper-case inc]]
(map #(bimap fs %) m))
I am uncomfortable with the rigidity of the "spec", specifically that each top element will be a vector of two vectors. If we are looking for a general approach, we would prefer a spec like "Given a sequence of vectors, apply item-wise a vector of transformations. Then we might write a more flexible:
(let [targets [[["a" "b" "c"] [1 2 3]]
[["foo" "bar" "baz"] [4 5 6]]]
xforms [str/upper-case inc]]
(mapv (fn [target]
(mapv (fn [v xform]
(map xform v))
target
xforms))
targets))
how many arguments can a #()
function have
it doesn’t tell you the maximum number of arguments
Good point, are you curious just to the maximum or something you're trying to solve?
Normally Clojure functions can take up to 20 arguments. As #()
should be just alternative syntax for fn
, I'm guessing that applies to it too.
#(apply + %&)
same as normal Clojure function - any
just for the sake of curiosity
thanks
btw looks like this is clojurescript repl. mostly behavior is the same between Clojure and clojurescript but when you ask a question it is better to mention the platform. most people in this channel assume by default questions in this channel are about JVM clojure
should i write a binding vector as [a 1, b 2]
in compare to what?
[a 1 b 2]
there is a clojure style guide - https://guide.clojure.style/
I don't think you will find that many commas in the wild. If the pairs become too difficult distinguish without them, you are more likely to see, as @U4P4NREBY suggested, newlines used for separation.
clojure macros aren’t hygienic 😢
not automatically but there is syntax to expand a symbol to unique identifier
`(let [x# 42] (inc x#))
;; => (let* [x__149__auto__ 42] (clojure.core/inc x__149__auto__))
note that instead of x#
you got x__149__auto__
And the backtick (`) behavior in Clojure is different than Common Lisp, IIRC, in that by default Clojure names are resolved and have their namespace added during expansion of backtick'ed forms, which goes a significant way in avoiding some of the issues that hygiene was meant to address. (I do not claim all issues, only some)
Rich Hickey knows about hygienic Lisp macros, but chose not to implement them in Clojure. Some brief background on this can be found in this talk transcript (or of course the video recording) here (search for "hygienic"): https://github.com/matthiasn/talk-transcripts/blob/master/Hickey_Rich/ClojureIntroForLispProgrammers.md
on new versions at least it also throws an error (warning?) if you have non-hygienic stuff
are there any repls with structural editing support? there is replete repl on mobile which i really like is there one on the pc (preferably windows)?
I believe the strong recommendation is to use the REPL via connecting the editor to it rather than typing it at the prompt. Any reasons to prefer that?
most editors support eval via the REPL and the OS shouldnt be an issue there
i already have nrepl and clojure sublimed installed lol thanks
awesome! with a proper editor+repl setup, you ideally never have to use the prompt 😄
https://practical.li/clojure/clojure-cli/projects/rich-comments.html is a more prevalent form
A common misconception is that "REPL driven development" means "typing into the repl". 😄 In reality, most devs most of the time will type into an editor, and then send individual forms to the repl for evaluation.
Rebel is a rich terminal Repl UI for Clojure, although it has docs and auto-completion other development features are provided by editors https://practical.li/clojure/clojure-cli/repl/ I use a terminal Repl for very minimal coding or for starting & restarting long running processes, e.g. developing APIs and other web services.
https://github.com/tonsky/Clojure-Sublimed looks like a fine editor for Clojure development https://practical.li/clojure/clojure-editors/ lists other Clojure editors available. There is a #clj-on-windows channel for help with running Clojure on Windows if problems arise
Since you’re already on Sublime Text, you could also try Tutkain (https://tutkain.flowthing.me), which comes with ParEdit for structural editing. (The downside, though, is that unlike Clojure Sublimed, Tutkain’s main developer is rather inept.)
I feel this is a really stupid question. But how to sort a list of strings alphabetically in clojurescript,. regardless of case ?
(sort ["BT" "beehive" "battle"]) => ("BT" "battle" "beehive") <<< WAT!
(sort ["bt" "beehive" "battle"]) => ("battle" "beehive" "bt")
?