This page is not created by, affiliated with, or supported by Slack Technologies, Inc.
2021-06-13
Channels
- # babashka (1)
- # beginners (11)
- # cider (8)
- # clj-kondo (7)
- # clojure (35)
- # clojure-italy (2)
- # clojurescript (6)
- # conjure (5)
- # datomic (10)
- # duct (7)
- # fulcro (9)
- # helix (2)
- # introduce-yourself (5)
- # lsp (3)
- # malli (7)
- # meander (3)
- # off-topic (8)
- # pathom (3)
- # podcasts (2)
- # portal (9)
- # reitit (7)
- # releases (3)
- # shadow-cljs (43)
- # sql (25)
- # tools-deps (3)
Hi guys, I built a defprotocol implemented in many defrecord. Here an oversimplified version:
(defprotocol A
(foo [_ b])
(bar [_ b]))
(defrecord R1 []
A
(foo [_ b]
(- b 10))
(bar [_ b]
(+ b 10)))
(defrecord R2 []
A
(foo [_ b]
(* b 10))
(bar [_ b]
(/ b 10)))
I don't find a smart way to carry the same tests (= a (-> a (.foo) (.bar)))
on all implementations without copying some boilerplate for R1, R2, R3, ... Is there any way to factorize?Also checkout https://clojuredocs.org/clojure.test/are
(are [a] (= a (-> a foo bar))
r1
r2)
FYI you should not use Java interop to invoke protocol methods on a record, you should invoke the protocol method
Idiomatic question, is this proper clojure idiom to use for updating a data structure based on an expensive calculation?
It's convenient to use let to store a series of intermediate results that depend on previous let values. I'm not sure if that is expected practice.
(defn buncha-calcs
"returns processed-data with a-data and b-data data structure fields updated"
[processed-data input-data]
(let [stage-1 (expensive-calc input-data)
a-results (calc-a (:a-data processed-data) stage-1 )
b-results (calc-a (:b-data processed-data) stage-1 )
]
(assoc
(assoc processed-data :a-data a-results )
:b-data b-results)))
> It's convenient to use let to store a series of intermediate results that depend on previous let values. I'm not sure if that is expected practice.
That's exactly what let
is meant for.
assoc
can take multiple key-values, which means, you can do this with one call to assoc
, like this:
(defn buncha-calcs
"returns processed-data with a-data and b-data data structure fields updated"
[processed input]
(let [stage-1 (expensive-calc input)
a-results (calc-a (:a-data processed) stage-1)
b-results (calc-a (:b-data processed) stage-1)]
(assoc processed :a-data a-results :b-data b-results)))
I also removed the -data
suffix from the arg-names. Because Clojure is a very data-centric language, IMO it's reasonable to assume something is data unless mentioned otherwise. This is a personal opinion though.
Now, you are effectively applying the function calc-a
to the values of two keys, along with an extra argument. update
does this more directly as opposed to manually getting the value, applying the function, and assoc
iating it back-in. Looks like this:
(defn buncha-calcs
"returns processed-data with a-data and b-data data structure fields updated"
[processed input]
(let [stage-1 (expensive-calc input)]
(update
(update processed :a-data calc-a stage-1)
:b-data calc-b stage-1)))
Finally, operations like assoc
, dissoc
, conj
and update
are collection-level functions (take a collection as their first arg and return a collection), and compose well with the thread-first macro (`->`), which when used the code becomes more linear to read:
(defn buncha-calcs
"returns processed-data with a-data and b-data data structure fields updated"
[processed input]
(let [stage-1 (expensive-calc input)]
(-> processed
(update :a-data calc-a stage-1)
(update :b-data calc-a stage-1))))
^ This is the most idiomatic way to write this IMHO.
And if you haven't encountered threading macros before, I highly recommend checking out http://clojure.org/guides/threading_macros.
PS: FYI you can use triple back-ticks to format multiline code-snippets.Hi, I’m having this error when publishing to heroku.
Could not transfer artifact net.sf.saxon:saxon:pom:9 from/to jboss ( ): Connection reset
This could be due to a typo in :dependencies, file system permissions, or network issues.
If you are behind a proxy, try setting the 'http_proxy' environment variable.
Uberjar aborting because jar failed: Could not resolve dependencies
My dependencies:
:repositories [["enonic" " "]]
:dependencies [[camel-snake-kebab "0.4.2"]
[clj-http "3.10.1"]
[environ "1.2.0"]
[integrant "0.8.0"]
[integrant/repl "0.3.1"]
[io.xapix/paos "0.2.4"]
[metosin/reitit "0.5.10"]
[org.clojure/clojure "1.10.1"]
[org.postgresql/postgresql "42.2.14"]
[ovotech/ring-jwt "1.3.0"]
[ring "1.8.2"]
[seancorfield/next.jdbc "1.1.613"]
[buddy "2.0.0"]
[clojure.java-time "0.3.2"]
[ring/ring-mock "0.4.0"]
[ring-cors "0.1.13"]]
Does anyone knows how to solve this?