Fork me on GitHub
#clojure
<
2022-06-13
>
pinkfrog03:06:23

I forgot the typical naming when do in a for. loop? What shall the the x & xs be ?

(loop [[x & xs] col] ,,,)
feeling like xs and col are competing for the same name.

seancorfield04:06:36

That seems reasonable to me. Singular "thing" (`x`) followed by possibly more "things" (`xs`). I'd use coll (for collection) rather than col (which suggests column).

seancorfield04:06:41

The other possibility is (loop [coll coll] ...) and refer to (first coll) inside the loop (and presumably (rest coll) in the recur)

pinkfrog04:06:40

or maybe

(loop [[ h & t] xs]]
this might be better

seancorfield04:06:12

I would tend to assume h was height and t was time, seen outside that h & t context.

seancorfield04:06:28

(I think that guide is overly-narrow in assuming x and y are numbers)

pinkfrog05:06:01

I admit x & xs is idiomatic. It’s just the coll in [ [x & xs] coll] looks weird. The coll shall also be something like xs but sadly the name is already taken.

didibus05:06:20

It's not weird, coll is the initial value of x and xs

☝️ 1
didibus05:06:39

When you recur, you will do (recur xs) you won't use coll anywhere inside the loop

didibus05:06:08

Inside your loop you have x and xs, outside the loop you have coll.

didibus05:06:54

coll refers to the whole collection, while x and xs refers to subsets of coll.

didibus05:06:40

You can also repeat things if you prefer:

(loop [[x & xs] xs]
 ...)
Or:
(loop [[x & coll] coll]
  ...)

didibus05:06:05

Normally I use coll when it's a collection, like a vector, map, set, etc. And I use xs when I'm talking about a seq or something I'll use as a seq. Often my function takes a coll, but rest and next return a sequence, so I find what you had first was best:

(loop [[x & xs] coll]
 ...)

1
didibus05:06:43

(let [coll [1 2 3 4 5 6]]
  (loop [acc 0 [x & xs] coll]
    (if x
      (recur (+ x acc) xs)
      acc)))
coll is the full collection, x is the element as you loop, xs is what's left to loop over.

1
☝️ 1
pinkfrog09:06:20

> When you recur, you will do (recur xs) you won’t use coll anywhere inside the loop (edited) Sounds like you are using x to test if coll is empty or not.

didibus03:06:05

I'm testing x to check if there are any elements left or we've looped over all of them. It's my recursive exit condition. It'll also handle coll being empty, but that's not the main purpose, it's checking if we have anything left to loop over.

didibus03:06:56

I'm not sure, but maybe you're confused about the behavior of loop/recur? It doesn't iterate over coll by itself. It works more like a let binding. You say let x be the first value of coll, and xs be the next values of coll. Then you do something, and you can choose to recur. When you recur, you have to bind new values to x and xs. You need to choose what they'll be bound too in the second loop, it doesn't have to be coll anymore, and most likely it wouldn't be.

Jeongsoo Lee05:06:55

Today I jumped from studying Kotlin for server development to Clojure. It feels like throwing off a straightjacket too tight. I started off with Kotlin because a close friend of mine advised me to move off Clojure since "it won't get me a job", but my gut instinct tells me that I use what I like and most of all makes me productive to the most; Everything else is secondary.

💯 6
simongray09:06:22

“Here’s to the crazy ones…” also works 😛

👍 1
Jeongsoo Lee09:06:39

Thanks! Wish you all and myself luck 🙂

Jeongsoo Lee05:06:11

Oh, and also by the way, clj-kondo is just absolutely amazing to use in Emacs. No need for some Intellij IDEA or something.

clj-kondo 4
Franklin07:06:17

how do I ran a single test in a rich comment/in the repl. I have something that looks as follows that is not working

(comment
  (run-tests
   (deftest test-smart-search-form-fields
     (testing "If other fields list is truthy(not nil) then show dropdown"
       (re-frame-test/run-test-sync
        (js/console.log "does this work?")
        (let [other-field-temp (reagent/atom "")
              other-fields-focus (reagent/atom false)
              other-fields ["one" "two" "three" "four"]]
          (with-mounted-component
            [smart-search-form-fields @other-field-temp @other-fields-focus other-fields]
            (fn [_component]
              (js/console.log (.-innerText (js/document.querySelector
                                            "#smart-search-component")))))))))))

Franklin08:06:33

I think I found a way

(comment
  (deftest test-smart-search-form-fields
    (testing "If other fields list is truthy(not nil) then show dropdown"
      (re-frame-test/run-test-sync
       (js/console.log "does this work?")
       (let [other-field-temp (reagent/atom "")
             other-fields-focus (reagent/atom false)
             other-fields ["one" "two" "three" "four"]]
         (with-mounted-component
           [smart-search-form-fields other-field-temp other-fields-focus other-fields]
           (fn [_component]
             (js/console.log (.-innerText (js/document.querySelector
                                           "#smart-search-component")))))))))
  (run-tests))

Jeongsoo Lee08:06:02

It looks like it's clojurescript. I'd recommend posting this to the clojurescript channel instead 🙂

Franklin08:06:36

yeah.. it is... I figured clojure.test and cljs.test APIs are the same... will post in the correct channel next time though

1
rgm14:06:57

I may not be understanding the question, but once you've run the deftest block, then you can invoke your test as (test-smart-search-form-fields) ... they're just no-argument functions.

Franklin16:06:55

mmmh... cool.. will try that out next time

Ben Sless09:06:22

Assuming I need to log requests through a web handler, and I'd rather log the request and response together and implement this as a middleware, where would you put it considering it can error out at multiple phases?

jumar14:06:44

How can it error out at multiple phases?

Ben Sless16:06:36

Content negotiation failure Schema validation failure Exception from handler Etc

jumar17:06:17

All of that is done by some middleware in the chain, right. I think this request logging middleware should be applied very early in request processing, perhaps even be the very first one

simongray16:06:47

This is a situation where interceptors make a lot of sense.

simongray16:06:49

Put the interceptor at the front and log in both the :leave and the :error fns. They can in principle even be the same exact function. http://pedestal.io/reference/error-handling

Ben Sless17:06:29

It can be done in with middleware, too, just need to handle it correctly, main concern is losing data before content negotiation

mars0i16:06:15

I would like to be able to test whether stdout is in a full-fledged terminal, or is instead a vim buffer when using vim-iced. This affects how I want to display diagnostic output. Any suggestions? (I'm asking in the general clojure channel because I don't think the answer will be specific to vim-iced or even vim.)

nbardiuk17:06:37

I don't know if there is a solution. I would look at class of *out* variable that holds reference to output writer. I've just tested on my machine that *out* in repl is instance of OutputStreamWriter but when I run it using nrepl tooling (in your case vim-iced) it is instance of PrintWriter . The writer for nrepl is different because server rebinds *out* to some temporary writer in order to capture output and send to the nrepl client. I suspect that you could hack something around this

mars0i17:06:27

Thanks @U076FM90B. That's a good idea. I just checked, and they are both java.io.Printwriter in my case. But there may be some other indirect way to test--I'll think about it. I normally use Leiningen, which normally starts nrepl. vim-iced also uses nrepl. So I think that's why both the terminal repl and vim-iced use java.io.Printwriter. I see that when I start clj it uses java.io.OutputStreamWriter . So a workaround might be to use clj instead, which could be a good idea anyway (though I still haven't got a deps.edn that does what I want). Or maybe I can configure nrepl in a special way so that I can tell the difference?

nbardiuk17:06:45

I don't have more ideas how to hack it 🙂 Would it be hard to reorganise code such that you could run simpler output from vim tools and complex from terminal? One another hack would be to define dynamic var with a flag that you want simple vs complex output and then bind it only for vim evaluation`(binding [your-flag-to-simplify-printing true] (some-code-that-prints))`

mars0i17:06:54

I think I have a workaround. (System/getenv "TERM") returns "xterm-256color" in my terminal. I can change that string, but if I connect vim-iced to my running nrepl, it will send (System/getenv "TERM") to that nrepl and get back whatever value TERM has there. However, I can force vim-iced to start its own nrepl, in which case TERM = "dumb".

👍 1
Ken Allen17:06:12

I haven’t tested this but you could check (System/console). In theory it will be nil if output is being redirected

mars0i17:06:26

@U076FM90B, yes, that's not a bad idea at all. I try to avoid dynamic variables, but this is a situation in which it would be convenient and reasonable to use.

mars0i17:06:56

Thanks @U03HTB6V19B. (System/console) is returning nil in all cases involving nrepl, i.e. all of the ways I'm used to working. In clj there's a non-nil object returned.

Colin P. Hill18:06:21

Anyone have a recommendation on a JVM library for validating JSON against a JSON schema? Lot of Java options out there, wondering if anyone has testimonials that can narrow the field for me.

emccue18:06:27

For clojure, once you parse the json then malli is good

valtteri18:06:48

Malli can generate JSON schema but parsing JSON schema -> malli is not supported yet. It’s on the backlog though.

valtteri18:06:10

pssst contributions welcome 😉

valtteri18:06:44

There’s a (stale) PR about it actually

Colin P. Hill19:06:15

With its current feature set, Malli doesn't really fit my needs. JSON Schema is my starting point, not something I'm trying to produce.