Fork me on GitHub
#clojure
<
2023-01-23
>
roklenarcic08:01:07

Which operation do you use by default (when you have no immediate reason to prefer one): rest or next ?

lispyclouds08:01:26

i pretty much always use rest as its more lazy, always gives a seq and generally more consistent in scenarios like the base case for recursions i feel.

didibus15:01:23

I tend to use rest.

Algo_20208:01:43

I am trying to list all the Tos of an email message in a single string addresses like this:

(defn get-tos
  [message]
  (let [addresses (str "")]
    (for [p (.personalization message)]
      (for [email (.getTos p)]
        (addresses (str address (.getEmail email))))) ;;Trying for appending the string to the `addresses` var
    addresses))
The problem is, Clojure doesn't support modifying the let binding and also the assignment in the commented line is incorrect. I am from C++ background and new to Clojure. Is there an idiomatic way to append addresses and then return that address?

thheller09:01:19

look up things like map, reduce and in general all the sequence stuff

thheller09:01:29

for your case a simple for with a join works fine

thheller09:01:32

(defn get-tos [message]
  (->> (for [p (.personalization message)
             email (.getTos p)]
         email)
       (str/join ", ")))

thheller09:01:47

str/join being (:require [clojure.string :as str]) in your ns

thheller09:01:17

also note that three backticks allows you to create multi line code snippets

thheller09:01:36

just 3 backticks, foo, 3 backticks

Martin Půda09:01:35

Could you provide some example data and expected result?

skylize14:01:42

In Clojure, we generally expect things to be immutable. That means you cannot change an existing value, and must instead create a new value that derives from the old one. A high level description of @U05224H0W's suggestion above: • Build a sequence of all the addresses. • Create a new string from joining each item in the sequence with ", ". If you needed more advanced control than clojure.string/join for joining the sequence, then you could use reduce or recur. For both, iterating involves repeatedly calling a function, and each function returns a new value derived from the previous iteration. In other words, instead of trying to edit the existing string, you would repeatedly return a new string with changes applied. If you need more help, the #C053AK3F9 channel is more appropriate for this kind of question, .

2
👍 2
kwladyka21:01:33

RUN clojure -A:build:test:check-syntax-and-reflections -Stree This are all my aliases (build:test:check-syntax-and-reflections). I expected this command to download ALL dependencies. But when I run RUN clojure -T:build uber "{:version \"$VERSION\"}" It downloads

#11 3.568 Downloading: org/clojure/tools.logging/1.2.1/tools.logging-1.2.1.pom from central
#11 3.568 Downloading: commons-codec/commons-codec/1.11/commons-codec-1.11.pom from central
#11 3.618 Downloading: org/apache/commons/commons-parent/42/commons-parent-42.pom from central
#11 3.682 Downloading: org/apache/apache/18/apache-18.pom from central
#11 3.809 Downloading: org/clojure/core.memoize/1.0.253/core.memoize-1.0.253.pom from central
#11 3.857 Downloading: org/clojure/core.memoize/1.0.253/core.memoize-1.0.253.jar from central
#11 3.911 Downloading: commons-codec/commons-codec/1.11/commons-codec-1.11.jar from central
#11 3.914 Downloading: org/clojure/tools.logging/1.2.1/tools.logging-1.2.1.jar from central
#11 6.156 Downloading: org/clojure/tools.namespace/0.2.11/tools.namespace-0.2.11.pom from central
#11 6.235 Downloading: org/clojure/pom.contrib/0.1.2/pom.contrib-0.1.2.pom from central
#11 6.374 Downloading: org/clojure/tools.namespace/0.2.11/tools.namespace-0.2.11.jar from central
#11 6.376 Downloading: org/clojure/java.classpath/0.3.0/java.classpath-0.3.0.jar from central
what I miss? Everything should be downloaded in first step.

phronmophobic21:01:34

Is there an overlap in declared dependencies between the aliases? There might be a dependency in build that is also declared with a different version by test or check-syntax-and-reflections

kwladyka21:01:25

I see. Good point. Thank you.

kwladyka22:01:22

RUN clojure -A:build -Stree
RUN clojure -A:test -Stree
RUN clojure -A:check-syntax-and-reflections -Stree
It didn’t solve it. Still download new deps.

phronmophobic22:01:28

I'm wondering if -Stree has something to do with it. Does using clojure -P:build help?

kwladyka22:01:43

RUN clojure -P build is how it should be run? I didn’t use it so far. If so, then it still doesn’t work.

kwladyka22:01:51

I mean not download all

kwladyka22:01:27

-P	Prepare / dry run (CI servers, Containers)	deps, path
-P -M:aliases	Prepare / dry run including alias deps and paths	deps, path
-P -X:aliases	Prepare / dry run including alias deps and paths	deps, path
What is the right way to use it? doc make me confuse.

phronmophobic22:01:45

Ah, I probably messed up the syntax

phronmophobic22:01:54

maybe clojure -P -T:build ?

phronmophobic22:01:59

and then clojure -P -A:test for the others

kwladyka22:01:35

hmm interesting, it works

kwladyka22:01:53

so -Stree lie about deps?

kwladyka22:01:33

hmm RUN clojure -P -T:build:test:check-syntax-and-reflections doesn’t download all too. It needs combination of both

phronmophobic22:01:42

I don't think so. I'm not totally sure how it works, but I think -Stree is an override used to print dependencies. So it downloads whatever is needed to print the tree, but might skip downloads that aren't required to print the tree?

phronmophobic22:01:29

I know -T and -A can affect the classpath differently (in addition to multiple aliases that might resolve to different dependencies)

kwladyka22:01:14

yeah, only one explanation. Although I don’t know how it works under the hood.

phronmophobic22:01:40

clojure build tools has a programmatic interface that you could probably use to figure out exactly was is happening, but I think the general takeaway is to try -P as a the first arg to the exact command that you want to download dependencies for to get the best results.

kwladyka22:01:10

RUN clojure -A:test -Stree
RUN clojure -A:check-syntax-and-reflections -Stree
RUN clojure -A:build -Stree
RUN clojure -P -T:build
so many lines but this is the only one solution wich download 100%

phronmophobic22:01:42

you need clojure -A:build -Stree and clojure -P -T:build ?

kwladyka22:01:57

I am trying right now

kwladyka22:01:33

no, only -P

phronmophobic22:01:45

intuitively, it seems like clojure -P -A:test should be preferred to clojure -A:test -Stree

kwladyka22:01:59

yes

RUN clojure -P -A:test
RUN clojure -P -A:check-syntax-and-reflections
RUN clojure -P -T:build
this also do the job

👍 2
kwladyka22:01:32

not printing tree, but well I didn’t look on it too often

kwladyka22:01:41

offtopic but can be useful While we are in the topic I discovered huge bug from my side which I was repeating: If you have Dockerfile with multi stage build and test build is not used later, then it is not even executed during build! So you never run tests… I have no idea when it changed, but in the past it was always executing…

kwladyka22:01:22

# tests
FROM deps-with-code as tests
RUN clojure -T:build test
So if you don’t use tests later in Dockerfile tests are totally ignore during build

kwladyka22:01:03

which is strange because even Docker doc say something different

practicalli-johnny23:01:08

I use clojure -P with either -M or -X execution flags

RUN clojure -P -X:env/test:package/uberjar
I would avoid the -T execution option when downloading deps as it will ignore deps from the Clojure project. -A flag is mostly for running a repl now, so use -M as the new -A This is how I cache dependencies in Docker https://practical.li/blog/posts/build-and-run-clojure-with-multistage-dockerfile/

👍 2
phronmophobic00:01:29

> I would avoid the -T execution option when downloading deps as it will ignore deps from the Clojure project. Right, but I think the goal is to download the necessary deps for running clojure -T:build test in the future without extra downloads.

kwladyka14:01:54

yeah to cache all deps and not download on each run