beginners

Getting started with Clojure/ClojureScript? Welcome! Also try: https://ask.clojure.org. Check out resources at https://gist.github.com/yogthos/be323be0361c589570a6da4ccc85f58f.
Daniel Tobias 2021-01-05T04:43:15.134700Z

Required namespace "react" never defined i am trying to build an application that is using reagent and i am getting this error. it is literally just the figwheel template for reagent

jumar 2021-01-05T04:43:46.134800Z

In Andy's example, the PersistentArrayMap is used so it preserves insertion order but the same holds for PersistentHashMap :

(def m1h (-> (hash-map :very-first -1) (assoc 0 :added-first) (assoc 92612215 :added-second)))
(keys m1h)
;; => (0 92612215 :very-first)

(def m2h (-> (hash-map :very-first -1) (assoc 92612215 :added-first) (assoc 0 :added-second)))
(keys m2h)
;; => (92612215 0 :very-first)

Daniel Tobias 2021-01-05T04:55:31.135400Z

lein cljsbuild once min does not work at all, always results in depedency errors here

Daniel Tobias 2021-01-05T04:55:45.135800Z

created the project with lein new figwheel appname -- --reagent

seancorfield 2021-01-05T05:00:47.136700Z

@dan.yb.tobias When you run lein new figwheel appname -- --reagent, it says you need to run npm install -- did you do that?

seancorfield 2021-01-05T05:01:02.137Z

(which means you need npm itself installed)

Daniel Tobias 2021-01-05T05:01:57.137300Z

ah somehow i missed it, ill give it a try ty

Daniel Tobias 2021-01-05T05:02:29.137600Z

@seancorfield still errored out

Daniel Tobias 2021-01-05T05:02:43.137800Z

(same error)

Daniel Tobias 2021-01-05T05:02:56.137900Z

Jan 04, 2021 9:02:27 PM com.google.javascript.jscomp.LoggerErrorManager printSummary
WARNING: 4 error(s), 0 warning(s)
ERROR: JSC_MISSING_MODULE_OR_PROVIDE. Required namespace "react" never defined. at /D:/Userfiles/Documents/Projects/Clojure/webpage/reagent-sample2/target/cljsbuild-compiler-1/reagent/core.js line 5 : 0
ERROR: JSC_MISSING_MODULE_OR_PROVIDE. Required namespace "react_dom" never defined. at /D:/Userfiles/Documents/Projects/Clojure/webpage/reagent-sample2/target/cljsbuild-compiler-1/reagent/dom.js line 5 : 0
ERROR: JSC_MISSING_MODULE_OR_PROVIDE. Required namespace "react" never defined. at /D:/Userfiles/Documents/Projects/Clojure/webpage/reagent-sample2/target/cljsbuild-compiler-1/reagent/impl/component.js line 6 : 0
ERROR: JSC_MISSING_MODULE_OR_PROVIDE. Required namespace "react" never defined. at /D:/Userfiles/Documents/Projects/Clojure/webpage/reagent-sample2/target/cljsbuild-compiler-1/reagent/impl/template.js 

Daniel Tobias 2021-01-05T05:05:39.138800Z

using lein new reagent-frontend reagent-sample +shadow-cljs to make the app works but i like the other one since it's easier to remember :^)

seancorfield 2021-01-05T05:06:02.139200Z

I can repro your problem (but I don't have npm installed which is why I wanted to check you had run that step).

seancorfield 2021-01-05T05:06:26.139800Z

I recently started playing with ClojureScript and I used the figwheel-main template, not the figwheel one.

seancorfield 2021-01-05T05:06:47.140300Z

But then I'm using the Clojure CLI, not leiningen (except for helping beginners with lein 🙂 )

Daniel Tobias 2021-01-05T05:07:29.141Z

haha yeah I am trying to learn but i am constantly having issues

seancorfield 2021-01-05T05:10:44.141500Z

I got the impression that figwheel-main had superseded plain ol' figwheel...

seancorfield 2021-01-05T05:11:03.141700Z

https://figwheel.org/

raspasov 2021-01-05T05:11:21.142100Z

@seancorfield that’s definitely the case

Daniel Tobias 2021-01-05T05:12:45.142500Z

so i should try the same thing but with figwheel-main ok

2021-01-05T05:26:13.143100Z

Ah, yes, sorry I didn't force the use of PersistentHashMap, but the example I had written up earlier did do so, as jumar's example does.

13tales 2021-01-05T05:59:29.157200Z

Hey. I’m learning CLJS by working on a little project, and I have a question about a good and idiomatic approach to a fairly simple problem. For context, I mostly work as a JS/React dev. What I want to do: write a function that takes a collection, makes an HTTP request based on each value in the collection, and when they’re all complete, returns the results. I’ve done this before in JS; inside of a call to Promise.all, my code maps over the input array, uses await to wait for the HTTP response, and then does some simple operations based on the response and returns the resulting output. What’s a good way to do it in CLJS? I’m reading about core.async and find it comprehensible enough, but it’s a lot to absorb, and I’m curious how a proficient Clojure(script) developer would typically do this. 😅

13tales 2021-01-05T06:01:05.158600Z

(Sure, I could use JS interop to use the promises that I’m familiar with, but that seems like it might defeat the point)

13tales 2021-01-05T06:11:18.159900Z

I think the bit that I’m finding hardest to figure out is how to wait until all the requests have returned before returning the final output 😕

seancorfield 2021-01-05T06:19:15.162Z

@thomas.armstrong I'm just starting to (re-)learn cljs so I'll be interested to hear what people suggest. I'd be able to do this in Clojure on the JVM without having to think about it much, since multi-threading is so common, but cljs is an unknown for me...

raspasov 2021-01-05T06:19:29.162100Z

@thomas.armstrong I would use core.async for that, yes

13tales 2021-01-06T04:53:01.247700Z

So, for anyone who’s curious about where I ended up on this, I went pretty far down the rabbit hole learning about core.async, watched Tim Baldridge’s 2013 talk, and I feel like I understand it all a bit better now. For context, my goal is to take some geographic coordinates, and a collection of dates, make API requests to retrieve sunset and sunrise times for the specified location for all of those dates, and then calculate some angles based on those times (that part not finished yet). Here’s my solution to making all the async requests and combining them into a single map:

(defn <get-times-for-date [lat long date]
  (let [build-result (fn [times]
                       {date times})]
    (go
      (-&gt; (http/get "<https://api.sunrise-sunset.org/json>"
                    {:query-params {"lat" lat "lng" long "date" date}
                     :with-credentials? false})
          &lt;!
          :body
          :results
          (select-keys [:sunset :sunrise])
          build-result))))

;; Still need to do the actual angle calculation
(defn &lt;get-angles [lat long]
  (go
    (let [times (-&gt;&gt; (mapv (partial &lt;get-times-for-date lat long) dates)
                     (a/map merge)
                     &lt;!)]
      (println times))))

13tales 2021-01-05T06:22:02.162600Z

How would you do it with core.async in clojure? As I understand it so far, the main difference in CLJS is that only the (go ...) versions of the core.async functions are available, since the JS runtime is only ever single-threaded.

13tales 2021-01-05T06:24:10.163Z

Mmm. I understand that core.async is pretty much a given, since javascript HTTP requests are asynchronous by nature. How would you wait for all HTTP requests to complete before returning the result?

raspasov 2021-01-05T06:24:39.163200Z

(a/go
  ;initiate requests (replace (a/timeout... ) with a function that makes an HTTP request and returns a channel
  (let [resp-channel-1 (a/timeout (rand 1000))
        resp-channel-2 (a/timeout (rand 1000))
        ;wait for response
        resp-1         (a/&lt;! resp-channel-1)
        resp-2         (a/&lt;! resp-channel-2)]
   
    (println resp-1 resp-2)))

raspasov 2021-01-05T06:25:00.163400Z

(:require [cljs.core.async :as a])

seancorfield 2021-01-05T06:25:17.163600Z

I wouldn't use core.async for this in Clojure - I'd just use threads directly on the JVM, either via pmap (sledgehammer), future, or more likely an executor / thread pool -- depending on the likely size of the collection.

13tales 2021-01-05T06:27:20.163800Z

Ohhh :thinking_face: You’d create a separate channel for each request? I’d been thinking more along the lines of creating a single channel, putting each response as it arrived, and then consuming from it .

raspasov 2021-01-05T06:27:49.164Z

One thing I’m gonna say though: even though this core.async “fun” 🙂 can get pretty elaborate, I’ve established over the years that it’s better to minimize the amount of concurrent HTTP requests you’re making (if possible); now, if you’re calling different services and not a service that you control, you might have no choice

seancorfield 2021-01-05T06:27:56.164200Z

@raspasov So, for a collection of URLs, you'd map over the collection to call async http fns that returned channels, then you'd map over the channels to take the values? Or use alts! over the collection of channels? (looping until you had all the values back?)

seancorfield 2021-01-05T06:28:30.164400Z

(again, I guess it depends on how many HTTP requests you'd end up making?)

13tales 2021-01-05T06:28:38.164600Z

Ah, gotcha. Sounds like a different world to JS 😄

raspasov 2021-01-05T06:28:52.164800Z

Unfortunately core.async doesn’t allow you to (map a-fn coll)

seancorfield 2021-01-05T06:29:11.165Z

The JVM is very different. I've done almost zero JS stuff in my life. I've spent decades working on the JVM.

raspasov 2021-01-05T06:29:18.165200Z

So some imperative-flavored looping can be involved…

raspasov 2021-01-05T06:29:58.165400Z

Basically you can’t (map <! seq-of-channels)… you’re probably aware of that, it’s the same in Clojure

13tales 2021-01-05T06:30:16.165600Z

> it’s better to minimize the amount of concurrent HTTP requests you’re making For sure. Unfortunately, the API I’m calling only accepts one parameter per request, and the number of requests will be small (< 20)

seancorfield 2021-01-05T06:30:36.165800Z

But you can map a function over a collection that would produce a sequence of channels.

raspasov 2021-01-05T06:30:45.166Z

@seancorfield right

raspasov 2021-01-05T06:30:52.166200Z

@thomas.armstrong right, so I just showed manually doing it over two channels,

raspasov 2021-01-05T06:31:15.166400Z

So let’s see for many…

seancorfield 2021-01-05T06:31:38.166600Z

You could map a blocking take over the channels 🙂 since you need to wait for them all to complete anyway.

seancorfield 2021-01-05T06:32:58.166800Z

@thomas.armstrong What do you need to do with the HTTP results once you get them? Do you just want a collection of results or are you handing them off for further processing?

13tales 2021-01-05T06:33:03.167Z

@raspasov Yeah, much appreciated; I can see how that would would work. I guess the thing I’m most curious about now, in terms of the approach that an experienced CLJS dev might take, is: why many channels instead of one channel? I’m new to the whole concept of channels, so still trying to build a mental model.

raspasov 2021-01-05T06:33:40.167200Z

@seancorfield yes 🙂 that is a nice one in JVM Clojure

13tales 2021-01-05T06:34:18.167400Z

@seancorfield Not much. A little extra processing per result, but just on the level of extracting some values from the response and then doing some simple arithmetic.

seancorfield 2021-01-05T06:35:31.167600Z

@raspasov Ah, there is no blocking take in cljs?

raspasov 2021-01-05T06:35:58.167800Z

@seancorfield no

raspasov 2021-01-05T06:36:12.168Z

No (thread…), (<!!… etc

raspasov 2021-01-05T06:36:14.168200Z

@thomas.armstrong there’s so many ways you can approach this; and to be fair, there’s no perfect solution, it depends on what you’re trying to achieve; you can have one long-lived channel that processes all requests; you can put channels on that channel and have one (go (loop []… (recur)) for the whole application that takes channels off the main channel, waits for a response and does something with it

raspasov 2021-01-05T06:37:07.168400Z

channels on channels is pretty neat… I’ve used it; but if you can avoid having long-lived global channels, I’d prefer it; less “state” to manage

seancorfield 2021-01-05T06:38:51.168600Z

Haha... this is why my cljs learning journey will be painful: I'm so used to a multi-threaded environment!

13tales 2021-01-05T06:40:10.168800Z

@raspasov > there’s so many ways you can approach this Yeah, that’s my dilemma. So much power, so little understanding (right now) of how to use it 😅

13tales 2021-01-05T06:40:43.169Z

Thanks for the responses. You’ve given me a starting point, I think.

raspasov 2021-01-05T06:58:28.169400Z

(comment
  ;This takes at most ~2000 ms to execute
  (let [process-seq-of-channels
        (fn [chans]
          (a/go
            (loop [chans chans]
              (if-not (empty? chans)
                (let [ch   (first chans)
                      resp (a/&lt;! ch)]
                  (println resp)
                  (recur (rest chans)))
                (println :done)))))

        fake-http!
        (fn [req idx]
          (let [resp-ch (a/chan 1)]
            ;TODO Do HTTP request!!!
            (a/go
              (a/&lt;! (a/timeout (rand-int 2000)))
              (a/put! resp-ch {:resp req :idx idx}))
            ;TODO end
            ;return channel
            resp-ch))]
    (a/go
      ;initiate requests, replace fake-http! with a function that makes an HTTP request and returns a channel
      ;MUST use (doall...) to send the requests right away!
      (let [resp-chans (doall (map fake-http! (repeat 10 {:req 1}) (range 10)))]
        (println :starting)
        (process-seq-of-channels resp-chans)))))

raspasov 2021-01-05T07:05:18.169700Z

I also really like this library https://github.com/jamesmacaulay/cljs-promises , it’s old, there’s more fancy ones nowadays, but this approach has never let me down… basically it allows to extend JS promises to return (let [[val error?] (<! a-promise)])

raspasov 2021-01-05T07:13:12.170100Z

Core.async is not the most beginner friendly thing; errors can be confusing, etc; some people try to avoid it but I do like it; the trade-off is worth it for many of my use cases; it allows to easily synchronize not only HTTP requests but many different events in your application; for example I’m working on a React Native app, and using TensorFlow Lite; I need to wait for the library itself to initialize (doesn’t happen on application launch), and then some ML models to load before I proceed with different setup fns; so core.async is a great tool for that; Look at (promise-chan), useful for such cases

raspasov 2021-01-05T07:17:40.170300Z

So above I showed a case where you launch-off multiple requests at the same time; that works nice for a demo and a one-off; in a long-lived application, I often find it desirable to have one global channel that processes responses one by one; Sometimes being able to reason about the sequence of incoming responses might be desirable (in situations around login, user setup etc); otherwise, the less you care about the sequence in which responses are being received, the better

raspasov 2021-01-05T07:19:19.170500Z

In my experience, for ClojureScript, simply using (defonce a-global-channel) is enough… alternatively you can use https://github.com/stuartsierra/component

raspasov 2021-01-05T07:19:31.170900Z

But I’d start with defonce…

seancorfield 2021-01-05T07:19:32.171100Z

@raspasov For the fake-http! function, instead of declaring a channel and returning it, could you just have the go block return the hash map (since go blocks automatically return a channel that, when taken, returns the last value in the go block?

seancorfield 2021-01-05T07:20:07.171300Z

Also, for doall-`map`, why not use mapv instead which is eager?

raspasov 2021-01-05T07:20:09.171500Z

Yes, you can; I just wanted to complete each channel with a random timeout

raspasov 2021-01-05T07:20:30.171700Z

@seancorfield mapv works as well 👍

raspasov 2021-01-05T07:20:58.171900Z

I just wanted to point it out, because it tripped me even after years of doing this 🙂

raspasov 2021-01-05T07:21:13.172100Z

I just wrote (map …) and I’m like “why is this taking longer than 2 seconds” Lol

2021-01-05T07:22:31.172300Z

js/Promise.all would be the no-lib way to 'wait' for a bunch of stuff to be ready. in recent projects I've been happily using promesa lib which adds some nice sugar over js promises, (including as-if-sync macros like core.async). also worth mentioning, promesa works with https://github.com/juxt/clip (replacement for component lib) so you can have a system with async components

👍 2
raspasov 2021-01-05T07:25:06.172600Z

@seancorfield I see what you mean…

raspasov 2021-01-05T07:26:22.172800Z

Improved fake-http!:

(comment
  ;This takes at most ~2000 ms to execute
  (let [process-seq-of-channels
        (fn [chans]
          (a/go
            (loop [chans chans]
              (if-not (empty? chans)
                (let [ch   (first chans)
                      resp (a/&lt;! ch)]
                  (println resp)
                  (recur (rest chans)))
                (println :done)))))
        fake-http!
        (fn [req idx]
          (a/go
            (a/&lt;! (a/timeout (rand-int 2000)))
            {:resp req :idx idx}))]
    (a/go
      ;initiate requests, replace fake-http! with a function that makes an HTTP request and returns a channel
      ;MUST use (doall...) to send the requests right away!
      (let [resp-chans (doall (map fake-http! (repeat 10 {:req 1}) (range 10)))]
        (println :starting)
        (process-seq-of-channels resp-chans)))))

raspasov 2021-01-05T07:28:22.173100Z

It has become a habit for me to sometimes make things around core.async extra verbose 🙂 It helps for debugging, (timbre/spy …) saves the day in many cases; But this is a good simplification

13tales 2021-01-05T07:40:30.173500Z

@henryw374 Yeah, it would’ve been easiest to fall back to JS, but I wanted to learn the “Clojure” way to do it 😅

raspasov 2021-01-05T07:40:34.173700Z

@seancorfield @thomas.armstrong actually I just realized there’s also (pipeline …) in core.async in CLJS which is pretty cool… I’ve used it in JVM Clojure and it is really good; it can provide a more managed approach vs. the “manual one-off” I’m showing above; definitely worth checking out

raspasov 2021-01-05T07:41:17.173900Z

@thomas.armstrong But it requires familiarity with transducers

13tales 2021-01-05T07:42:42.174100Z

@raspasov I think I’ll have to bookmark it for later. Feeling like I’ve got a lot to chew on here already 😄

raspasov 2021-01-05T07:43:00.174300Z

@thomas.armstrong for sure

13tales 2021-01-05T07:44:16.174500Z

Are there separate docs for clojurescript core.async vs the clojure version? I know there are differences, but all I seem to find are the docs for the JVM version.

raspasov 2021-01-05T07:45:09.174700Z

@thomas.armstrong one last word of caution; assuming you’re moderately familiar with JavaScript, and you don’t need crazy backward compatibility, I’d avoid most CLJS HTTP libraries and just directly call the browser/JS HTTP APIs that return promises or callbacks

👍 1
raspasov 2021-01-05T07:46:04.174900Z

@thomas.armstrong I believe the docs are mostly the same

13tales 2021-01-05T07:47:09.175200Z

Mmm. The lack of &lt;!! etc tripped me up a little bit until I understood what was going on.

raspasov 2021-01-05T07:47:16.175400Z

As far as (go…) stuff, it should all be the same; CLJS core.async is a subset of JVM core.async (of sorts)

raspasov 2021-01-05T07:48:04.175600Z

Yes, only single ! in CLJS and no (thread…)

raspasov 2021-01-05T07:48:13.175800Z

Otherwise, it should be the same

raspasov 2021-01-05T07:49:12.176Z

Ok calling it a night, have fun! 🙂

13tales 2021-01-05T07:51:30.176200Z

Thanks again. Very much appreciated!

👍 1
1
Christian 2021-01-05T11:41:56.179Z

I feel like it is something easy, but I can't manage to make it work I want to use the elements of a vector as arguments for my function

(assoc {} :a 4 :b 3)
(def argvec [:a 4 :b 3])
(assoc {} argvec)??

Antonio Bibiano 2021-01-05T11:59:14.179300Z

I think you are looking for apply

Antonio Bibiano 2021-01-05T11:59:42.179500Z

(apply assoc {} argvec)

✅ 1
Christian 2021-01-05T12:00:31.179800Z

For some reason I thought that I will get back this ({:a 4}, {:b 3})

Christian 2021-01-05T12:00:39.180100Z

I was sure I tested that 😄

Christian 2021-01-05T12:01:19.180800Z

Thank you

🙌 1
pavlosmelissinos 2021-01-05T12:33:58.192900Z

What's the proper way to round a float to up to x decimal points, removing any trailing zeros (non-significant digits)? clojure.core/format satisfies the first requirement but not the second e.g. assuming the same syntax as format, this is the behaviour I'm expecting: (my-format "%.4f" 0.0001557) -> 0.0001 (same behaviour as format) (my-format "%.3f" 0.00001) -> 0 (`0.0` is also fine, but not format's 0.000) (my-format "%.8f" 0.1) -> 0.1(format outputs 0.10000000 here) The use case is creating an automated report so the output should ideally return a value, e.g. satisfy the string? predicate, rather than print the result. This could probably be done with cl-format but it doesn't seem like a good fit unless it can return a value rather than print to stdout

Daniel Stephens 2021-01-06T11:49:11.268800Z

DecimalFormat from java interop might also be useful

(fn format-decimal [d]
   (some-&gt;&gt; d
            (.format (doto (DecimalFormat. "0.0###")
                       (.setRoundingMode RoundingMode/DOWN)))))

😎 1
pavlosmelissinos 2021-01-06T12:13:47.279100Z

Oh nice, that seems to be exactly what I was looking for! Couldn't for the life of me figure out how to make it work, so thanks a lot @dstephens! 🙂

🎉 1
flowthing 2021-01-05T12:38:45.193500Z

cl-format returns a string if you pass nil as the first argument.

🙏 1
pavlosmelissinos 2021-01-05T12:40:37.193700Z

You're obviously right, don't know how I missed that :man-facepalming: Thanks!

flowthing 2021-01-05T12:41:33.194Z

Welcome. There's also with-out-str, which you might find useful with functions that print to stdout, but you obviously don't need it here.

👍 1
NoahTheDuke 2021-01-05T14:20:23.195900Z

quick question: i have a list of predicates, and a sequence of items. i want to remove all items from the sequence where at least one of the predicates is true. i'm looking for the counter-point to every-pred, something like any-pred. does that exist?

NoahTheDuke 2021-01-05T14:22:16.196600Z

ope, looking at the every-pred source, i see some-fn directly below it. i think that's what i'm looking for

flowthing 2021-01-05T14:22:37.196700Z

Yeah, it's some-fn: (remove (some-fn odd? neg?) [3 -2 4]).

NoahTheDuke 2021-01-05T14:22:57.196900Z

thank you

Christian 2021-01-05T16:11:10.198500Z

Why is partial arguably better than an anon function?

;; good
(map #(+ 5 %) (range 1 10))

;; (arguably) better
(map (partial + 5) (range 1 10))
From: https://guide.clojure.style/#partial

alexmiller 2021-01-05T16:11:58.199100Z

I'd argue it's not better :)

alexmiller 2021-01-05T16:12:20.199400Z

so maybe we should all just agree that it's arguable :)

2
1
Michael W 2021-01-05T16:20:37.201500Z

partial is very rigid, you can't use it unless you are giving arguments in order. If you want to give a function the second argument instead of the first, you are stuck using anon functions. It's only a small step to just not use partial at all.

dpsutton 2021-01-05T16:21:44.202600Z

style is fundamentally subjective. if you're inclined to look through it, allow yourself to be convinced or not. they are arguments about which style is better and up to you to find them convincing.

2021-01-05T16:25:23.203500Z

I'd definitely use (partial + 5) instead of #(apply + 5 %&amp;), I'd hope most would agree

👍 5
2021-01-05T16:26:15.204Z

in general I like when I can replace apply in anon-fn with partial

nnichols 2021-01-05T16:32:22.204300Z

There are some differences to consider: https://clojuredocs.org/clojure.core/partial#example-5f283b00e4b0b1e3652d7331

📎 1
alexmiller 2021-01-05T16:36:21.204700Z

Rich considers anonymous functions to be more idiomatic in Clojure than partial

Christian 2021-01-05T17:21:59.205800Z

Thanks for the insight, I would not have seen the connection from apply and partial

sova-soars-the-sora 2021-01-05T17:25:56.206600Z

too many arguments in programming : P

Harley Waagmeester 2021-01-05T17:35:54.208600Z

when i run lein uberjar it gives me this warning -> Warning: The Main-Class specified does not exist within the jar. I used to make a uberjar with this project often, but not lately.

Harley Waagmeester 2021-01-05T17:36:01.208900Z

I wonder what changed

Harley Waagmeester 2021-01-05T17:36:32.209500Z

i have :main and :aot in the project.clj file.

Harley Waagmeester 2021-01-05T17:37:07.209700Z

Leiningen 2.9.4 on Java 14.0.2 OpenJDK

Harley Waagmeester 2021-01-05T17:38:37.210100Z

and :gen-class of course

Harley Waagmeester 2021-01-05T17:42:53.210900Z

i don't see any classes anywhere, it isn't compiling anything, everything runs in cider ok

2021-01-05T18:01:58.212500Z

@codeperfect a project doesn't need a compiled main in order to run, but if you don't create one for your uberjar, you'll need to provide java with some other entry point

2021-01-05T18:02:26.213100Z

a popular choice is to skip aot-compiling and to pass your ns name as an arg to clojure.main

2021-01-05T18:03:06.213600Z

if you have :aot set, make sure that the :main and aot options agree(?)

Harley Waagmeester 2021-01-05T18:15:36.214800Z

i used a backup repository with an identical project.clj file and lein uberjar works there...

Harley Waagmeester 2021-01-05T18:15:40.215Z

strange

2021-01-05T18:20:50.215500Z

in that case check your lein versions, and try running lein clean and see if that changes the result

Harley Waagmeester 2021-01-05T18:24:18.217300Z

lein versiona are the same i did lein clean, what lein uberjar does is doing is putting the entire project directory tree into the standalone jar file, all the source code

2021-01-05T18:24:32.217500Z

that's the normal behavior

2021-01-05T18:24:52.217800Z

unless you explicitly ask for the source not to be included in the jar

2021-01-05T18:26:16.218400Z

in fact a lot of standard tooling breaks if the libraries you use are not packaged that way

Harley Waagmeester 2021-01-05T18:31:32.219300Z

but there are no class files of my code, and i don't know why it isn't compiling

2021-01-05T18:32:55.221100Z

OK, the problem can be subdivided - uberjar is a supertask that calls the compile task if your project is configured to be compiled, you can try running lein compile as a task on its own and at least verify that works

2021-01-05T18:33:11.221600Z

the likely issue here is that the config that causes compilation is erroneous

2021-01-05T18:34:06.222100Z

either it doesn't compile, doesn't compile to the expected output location, or isn't being configured to compile

2021-01-05T18:34:42.222600Z

also it might be good to move this conversation to #leiningen as it's definitely a lein / lein config issue

Harley Waagmeester 2021-01-05T18:43:27.224100Z

lein compile creates the classes, but lein uberjar still isn't putting them in the jar, maybe i'd rather have a nice cup of tea and watch tv

Harley Waagmeester 2021-01-05T18:45:33.224800Z

i do get a warning about ring -> Warning: parse-version not declared dynamic....(ring/util/parsing.clj:5)

Harley Waagmeester 2021-01-05T18:45:56.225200Z

eh, some cookies with my tea

2021-01-05T18:49:59.226100Z

if the classes are being created but are not showing up in your jar, make sure your target directory agrees with your uberjar classpath

2021-01-05T18:50:25.226400Z

at this point it's probably easier to just look at the project.clj

Harley Waagmeester 2021-01-05T18:59:26.228600Z

ah, the project.clj is different now, somehow ':prep-tasks ^:replace []' was put in there, i haven't used lein uberjar for months, working now 🙂

2021-01-05T19:04:14.230Z

yeah, it's a good practice to attempt to make an uberjar at least as often as you modify project.clj to head off subtle things like this

2021-01-05T19:04:45.230600Z

(similar practice is recommended with optimized cljs compilation)

2021-01-05T19:08:45.232300Z

Hi, I'm wondering how can I short circuit a for loop in Clojure? I'm iterating an integer vector twice checking for specific sum, but would like to stop once I find a first match. How would one do that?

2021-01-05T19:09:15.233Z

This is my currenct code:

(defn find-all-sums-to-2020 [expenses]
  (for [x expenses, y (rest expenses)
        :let [sum (+ x y)]
        :when (= sum 2020)]
    [x y]))

(defn find-sum-to-2020 [expenses]
  (first (find-all-sums-to-2020 expenses)))

2021-01-05T19:09:18.233100Z

@diego559 for is not a loop, but it is lazy, you can just stop consuming it

2021-01-05T19:09:39.233400Z

there's also the `:until` :while arg

2021-01-05T19:11:30.233900Z

what you are doing there is the normal way to stop it early

2021-01-05T19:14:27.234700Z

So (first) function will evaluate only the first result and therefore stop the inner for from continuing, is that what you are saying?

2021-01-05T19:14:50.235100Z

right, more precisely it never asks the inner for another value, so the value isn't calculated

2021-01-05T19:15:11.235700Z

that's how laziness works - you don't stop it from the outside, you just never force it to execute, so it doesn't

2021-01-05T19:15:32.236100Z

Great, thank you

2021-01-05T19:16:11.236800Z

the distinction becomes important when you have chunking (so asking for one item might make it decide to calculate 32 items) - you aren't forcing it to stop, you're asking it to calculate

2021-01-05T23:16:39.244300Z

Hey all, I wrote a program to ping and get an async response from a server via a single function. It was just a test and I'm wondering if I can get feedback on design patterns, idioms, if there is a much better way to do this. Also, specifically on line 61, how can I run the load-foo calls in parallel, and then print responses, without having the program exit? https://gist.github.com/jaybutera/dabbcda1e89c8ffed33773d73b420907#file-main-clj-L60