Fork me on GitHub

So I think I am feeling some of the pains of printing with lazy stuff. What’s the ‘proper’ way to do this? I basically map over a list of commands and run sh on it (this is a babashka script) but I get the prints of everything before the actual invocation of the command


Is it just do to a doall? I call my shell func repeatedly and that seems to be the main culprit


Reduce or run! Could be helpful, depending on what you need from the result of the calls

🙏 3

yeah I need just a list of the results, so dorun won’t work, and I could get reduce to work but doall does exactly what I need


I am basically timing how long something takes and want to run it a few times to get an average


Thank you, but none of those fit the bill for me. I need to return values


Are there any good video tutorials on using Clojure from the ground up? Not just “this is the language” but rather “this is how you set up a good dev environment and how you design and deploy a Clojure application”. It’s totally fine if it’s focused on the language as well as the other parts are there as well. Paid courses are OK.


I think that is the best in this topic

👍 3
Old account16:03:39

Hello, I have a very weird situation in my REPL (`lein repl`) that can not be normal behavior How can require be not available from everywhere :thinking_face: O I am doing something stupid? :face_with_hand_over_mouth:

Adrian Imanuel16:03:47

i'm not an expert, but

(ns newgsheet3.core
     (:require [clj-time.core :as time]
             [google-apps-clj.credentials :as gauth]
             [ :as gdrive]
             [ :as mime-types]
             [ :refer :all :as gsheets])
     (:import [ CellData RowData]))
as for yours
(require '[ :as io])


Yeah, in-ns catches a lot of people out. When you use it on a "new" namespace that has not been loaded (via require), you get a completely "empty" namespace: with not even clojure.core referred into it.


A good rule of thumb is "never use in-ns" (but of course there are times when it is useful).

✔️ 3

Another good rule of thumb is "never type into your REPL" (always evaluate code from your editor), which also side-steps this issue.

Old account18:03:32

I was experimenting in . I wonder can I see some sources of functions but (apply require clojure.main/repl-requires) because I guess it is CLJS. Also this environment is more like REPL as far as I understand.

Old account17:03:44

what to require to have source and doc available in my REPL it is available in 'user namespace?


(require '[clojure.repl :refer :all]) should also work.

Old account15:03:12

thanks 😉

🙂 3

(apply require clojure.main/repl-requires)


that's exactly how a clojure main repl starts up.

Jan Ignatius18:03:31

Evening all. I'm just starting and the overall Clojure syntax is giving me a bit of a headache. Could some one shine some light to why these two are not equal? (for [x [1 2 3]         y [1 2 3 4]         :when (not= x y)]     [x y])  (def a [1 2 3])  (def b [1 2 3 4])  (for [a b :when (not= a b)][a b])

Jan Ignatius18:03:58

They evaluate as follows: ([1 2] [1 3] [1 4] [2 1] [2 3] [2 4] [3 1] [3 2] [3 4]) ([1 [1 2 3 4]] [2 [1 2 3 4]] [3 [1 2 3 4]] [4 [1 2 3 4]])


You likely meant a a b b in the second for

Jan Ignatius18:03:24

I may have misunderstood how the a and b expand inside the for statement


Imagine it is a let


The difference is in a let a name is bound to the given value, but in a for a name is bound to each element in the given seq

Jan Ignatius18:03:11

I'll need to spend some time with this, it seems 😄

Jan Ignatius18:03:16

Thank you for the help.


I personally find for quite difficult, I was told you should mostly use Map or Filter

Jan Ignatius19:03:08

Seems I need to read it as "For a in a and b in b ..."


for can definitely be counter-intuitive/surprising for folks coming to Clojure from other languages where for is a loop rather than a comprehension.


Once you get used to it, it can sometimes make code a lot more readable than a combination of map and filter -- if you specifically need some lazy processing of data.


@email113 Specifically for your example, you can get there in a series of small steps that transform your code:

(for [x [1 2 3] y [1 2 3 4] :when (not= x y)] [x y])
;; define a and b as you have above
(for [x a y b :when (not= x y)] [x y]) ; pure substitution of value with symbol bound to same value
(for [a a y b :when (not= a y)] [a y]) ; rename local symbol x to a
(for [a a b b :when (not= a b)] [a b]) ; rename local symbol y to b
When you have immutable data, substitution and renaming become simpler and more mechanical.

Jan Ignatius19:03:06

So I could use any unused variable name inside the for that I just need to assign/bind(?) to a and b respectively, something like: (def a [1 2 3]) (def b [1 2 3 4]) (for [asdf a hjkl b :when (not= asdf hjkl)] [asdf hjkl]

Jan Ignatius19:03:28

I think the re-use of the variable name threw me a bit

Henri Schmidt19:03:46

@email113 the names bind to the elements of sequence a and b respectively. Not to the sequences themselves.


Right, hence hiredman's comment that it is like let: for introduces new, local symbols bound to (elements of) sequences, as does loop (which also isn't like loops in other languages).

Jim Strieter19:03:01

Noob here Is there a way to use some-> with & args? For instance: (defn f [x & funcList] (some-> x funcList)) ?


there's probably a cleaner way to write it, but it can be accomplished with reduce:

(reduce (fn [x f]
          (let [new-x (f x)]
            (if new-x
              (reduced nil))))
         ;; (constantly nil)

🙌 3
Jim Strieter20:03:30

Is there a way to write a macro to do this?


There's not much benefit in writing a macro for this example. You could write a function that does this.


It possibly already exists in clojure.core.


@smith.adriane If x is nil, you would want to short-circuit that earlier, which simplifies the code anyway: (reduce (fn [x f] (if (some? x) (f x) (reduced nil))) x func-list)

😬 3
👍 6
Jim Strieter20:03:03

I want to pass in some parameter x followed by a list of functions fList

Jim Strieter20:03:43

A single call to the outer function should feed x into the first function in fList, pass that result into the 2nd, etc. until all functions have been called

Jim Strieter20:03:54

I wrote a function that does this, but I'm trying to learn Clojure libraries so I wanted to check if there's a well known function that already does that


But you also want to stop when you hit a nil right?


Otherwise you could just do ((apply comp func-list) x) or (reduce (fn [x f] (f x)) x func-list)

Jim Strieter01:03:27

When I type: ((apply comp '((+ 1) (+ 1))) 1) I get: Execution error (ClassCastException) at clj-event-loop.core/eval2305 (form-init8093888511408098339.clj:1). clojure.lang.PersistentList cannot be cast to clojure.lang.IFn


You have a quoted list in there so it's just data, not functions.


((apply comp [inc inc]) 1) will work.


Also (+ 1) is not a function, it's a value: (+) is 0, (+ 1) is 1, (+ 1 2) is 3.


inc is "add 1" or your could use (partial + 1) and get a function that adds one.

Jim Strieter13:03:35

I want to use this to cascade method calls on a large Java object. Large in that it takes up a few 100 MB RAM. Is Clojure going to mutate the state of that instance for every method call? (I'm not opposed to immutability in and of itself, but if the JVM has to copy several MB by value for each method call, I need to find a mutable way of doing it.)


If it's a Java object, it follows Java rules and it will do whatever the methods on it do. If it is a Clojure data structure (immutable), then it will use structural sharing and only copy the minimum that it needs to. For the latter, you can often use transient/`persistent!` around the pipeline of operations to allow Clojure to optimize the mutation/copying.


yeah I was thinking comp 😄


relevant things: apply juxt comp partial


So I have a question. Sometimes users have an outdated copy of the login page for one of our applications. Which throws an anti-forgery error when they try to log in. Is there a way to make sure the page is fetched freshly when they open it up even if its cached? Or is there some straightforward solution to this outdated x-csrf token?


Seems like

<meta http-equiv="Cache-Control" content="no-cache, no-store, must-revalidate" />
will do the trick


from : > no-cache > The response may be stored by any cache, even if the response is normally non-cacheable. However, the stored response MUST always go through validation with the origin server first before using it, therefore, you cannot use no-cache in-conjunction with immutable. If you mean to not store the response in any cache, use no-store instead. This directive is not effective in preventing caches from storing your response. > > no-store > The response may not be stored in any cache. Note that this will not prevent a valid pre-existing cached response being returned. Clients can set `max-age=0` to also clear existing cache responses, as this forces the cache to revalidate with the server (no other directives have an effect when used with `no-store`).


I think the no-cache is superfluous alongside no-store