beginners

Getting started with Clojure/ClojureScript? Welcome! Also try: https://ask.clojure.org. Check out resources at https://gist.github.com/yogthos/be323be0361c589570a6da4ccc85f58f.
practicalli-john 2021-06-13T06:58:29.107300Z

clojure.set/map-invert is useful when using a hash map as a dictionary and wish to translate in both directions, e.g. encode/decode. for is often used to generate hiccup for web pages, avoiding a lot of repetitive code. cycle and rand-nth to generate repeating sequences and random selection, e.g for creating a carousel of video thumbnails on the London Clojurians website. I've been using a lot of conditional functions recently, and or if when cond Also using :`clojure-keywords` and {:hash "maps"} as functions to extract data. Hopefully those are fairly well known though šŸ˜‰

caumond 2021-06-13T15:40:02.114700Z

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?

caumond 2021-06-13T15:41:13.114800Z

Right now, I have to copy my tests on all deftest for every defrecord...

indy 2021-06-13T15:54:48.115Z

Wrap the tests in a function that takes the record as arg?

caumond 2021-06-13T16:03:36.115200Z

Hmm, fair enough. Some "utility test functions" including testing sentences.

indy 2021-06-13T16:10:06.115400Z

Also checkout https://clojuredocs.org/clojure.test/are

(are [a] (= a (-> a foo bar))
     r1
     r2)

indy 2021-06-13T16:13:12.115600Z

Actually this is what are is for, my bad for not recommending it at the start

alexmiller 2021-06-13T17:54:28.116800Z

FYI you should not use Java interop to invoke protocol methods on a record, you should invoke the protocol method

eric wolf 2021-06-13T19:07:08.117700Z

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)))

jaihindhreddy 2021-06-13T21:18:01.118100Z

> 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 associating 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.

šŸ’” 1
šŸŽÆ 1
omendozar 2021-06-13T22:02:03.119600Z

Hi, Iā€™m having this error when publishing to heroku.

Could not transfer artifact net.sf.saxon:saxon:pom:9 from/to jboss (<https://repository.jboss.org/nexus/content/repositories/deprecated/>): 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" "<https://repo.enonic.com/public/>"]]
  :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?

eric wolf 2021-06-13T23:58:57.119800Z

Thanks, that is super helpful