beginners

Getting started with Clojure/ClojureScript? Welcome! Also try: https://ask.clojure.org. Check out resources at https://gist.github.com/yogthos/be323be0361c589570a6da4ccc85f58f.
cschep 2021-04-02T00:02:33.422Z

I’m not sure how exactly to ask this question but the gist is that I have a program that is a loop, that is a chat bot, so it sits and loops and listens to input and responds, pretty starightforward. Doing REPL driven development on it has been challenging because when I run the listening loop it hangs the REPL

cschep 2021-04-02T00:02:42.422300Z

is there a way to async that loop in the “background”

cschep 2021-04-02T00:02:51.422700Z

and then i can poke and and update a function it calls

cschep 2021-04-02T00:03:01.423Z

to have a more interactive experience?

2021-04-02T18:14:24.470800Z

one option to consider is that the bot and the repl can listen to different file descriptors, either because you have multiple connections to one repl process, or you use a dedicated pipe/fifo - a question of making an alternate binding for *in* connected to a different tty

2021-04-02T18:14:52.471Z

(a process with multiple repl connections already makes multiple *in* bindings for you)

dpsutton 2021-04-02T00:06:22.424Z

generally a loop will call some function with some kind of message and then recur. from the repl you would want to not start the loop but just call the function that handles the message

dpsutton 2021-04-02T00:08:12.425300Z

kind of a "functional core, imperative shell" type thing. top level you have a loop which takes a message from a socket/web endpoint/queue/what have you and then does actions based on it, and then back to the top of the loop

cschep 2021-04-02T00:29:07.425800Z

i’d love to be able to poke at it while it’s running the loop and getting stuff from the server

cschep 2021-04-02T00:29:14.426100Z

in that case i’d be passing my own messages in yeah?

cschep 2021-04-02T00:37:07.426800Z

i think it’s waiting on a channel for input

cschep 2021-04-02T00:37:08.427Z

(a/<!! event-ch)

cschep 2021-04-02T00:37:23.427400Z

in go i would call this as a go routine

cschep 2021-04-02T00:37:27.427600Z

and it wouldn’t block anything while it did its thing

cschep 2021-04-02T00:38:02.427800Z

core async has go routines? woah

zackteo 2021-04-02T07:17:28.428700Z

Hi is there an iterate that allows for side effects?

zackteo 2021-04-02T07:19:29.429Z

am I looking for doseq?

zackteo 2021-04-02T07:23:28.429500Z

I want to do something like

(take-while #(>= number-of-weeks %)
            (iterate
              (partial + (rand-nth days-store1)) (rand-nth days-store1)))

zackteo 2021-04-02T08:00:53.430600Z

^ this runs but the result used for rand-nth is fixed

zackteo 2021-04-02T08:04:54.433900Z

Is there a function or a better way to do what I want.? Am trying to create a simulation of when a factory will refill its stock. So (def days-store1 [2 3 3 4 4 5 5 6]) is saying after there is a 1/8 chance that after 2 days, there is a need to restock. And then it undergoes a renewal process. So it any of those number of days in days-store1 are equally likely again

hindol 2021-04-02T08:15:08.434300Z

Did you try repeatedly?

zackteo 2021-04-02T08:17:12.434500Z

whoops I did not. But I'm not sure how I might want to form the sequence with repeatedly

hindol 2021-04-02T08:20:15.434800Z

(take 10 (repeatedly #(rand-nth [1 2 3 4 5]))) => (2 5 3 1 2 5 3 5 3 2)

zackteo 2021-04-02T08:21:24.435Z

Yeap I got that part 🙂 but how might i sum it up with the earlier element

zackteo 2021-04-02T08:22:00.435200Z

so if the random seq produced is [1 2 3 4 5] I want [1 3 6 10 15

zackteo 2021-04-02T08:22:33.435400Z

I want to take-while the last number in the seq is under 1280

hindol 2021-04-02T08:23:05.435600Z

(take 10 (map + (repeatedly #(rand-nth [1 2 3 4 5])) (repeatedly #(rand-nth [1 2 3 4 5]))))

zackteo 2021-04-02T08:25:44.435800Z

hmmm thanks for all your help but map doesn't take the earlier element :thinking_face:

zackteo 2021-04-02T08:26:30.436Z

I want something like [1 5 7 10 14 19 22 26 .....]

zackteo 2021-04-02T08:27:38.436200Z

maybe reductions

zackteo 2021-04-02T08:28:54.436400Z

cool I got it 😄

zackteo 2021-04-02T08:29:38.437Z

(take-while #(>= number-of-weeks %) (reductions +
                                                (repeatedly #(rand-nth [1 2 3 4 5]))))

zackteo 2021-04-02T08:29:48.437200Z

Thanks @hindol.adhya for your help 😄

zackteo 2021-04-02T08:30:12.437400Z

Wait ....

zackteo 2021-04-02T08:30:21.437600Z

no I still can't use take-while

hindol 2021-04-02T08:53:43.438100Z

Okay, now I finally understood what you mean by [1 3 6 10 15], 😅

zackteo 2021-04-02T08:54:14.438300Z

Sorry if I wasn't too clear 😅

hindol 2021-04-02T08:55:13.438500Z

The technical term is cumulative sums. reductions is definitely the right way. I don't understand what you mean by side effect of rand-nth?

hindol 2021-04-02T08:56:58.438700Z

https://mathworld.wolfram.com/CumulativeSum.html

zackteo 2021-04-02T08:57:24.438900Z

Currently. The take-while will only evaluate the rand-nth once. Meaning if the evaluation is 3 it will always increment by 3

zackteo 2021-04-02T08:58:01.439100Z

Whoops yeap am familiar with cumulative sum but didn't think of using that to describe what I wanted whoops

hindol 2021-04-02T09:01:59.439300Z

(take-while #(>= 1280 %)
            (reductions +
                        (repeatedly #(let [n (rand-nth [1 2 3 4 5])]
                                       (println "Rand:" n)
                                       n))))
I still don't get it. It seems rand-nth is called every time.
Rand:  3
Rand:  3
Rand:  5
Rand:  5
Rand:  1
Rand:  1
Rand:  1
Rand:  5

hindol 2021-04-02T09:04:12.439500Z

Sorry, I shared the link to cumulative sum thinking you might not know the term. But if you already know it, great.

raspasov 2021-04-02T09:26:38.440Z

(run!
  (fn [x] 
    ;TODO do side effect
    (println x))
  (take-while
    #(>= 1280 %)
    (reductions + (repeatedly #(rand-nth [1 2 3 4 5])))))

zackteo 2021-04-02T09:30:49.440200Z

The rand-nth is the part that needs the side effect. Let me try...

raspasov 2021-04-02T09:50:21.441100Z

Why does rand-nth need side effect? Perhaps you mean that you need the value that rand-nth produces to be used in a side-effect?

raspasov 2021-04-02T09:56:25.441300Z

(reduce
  (fn [accum item]
    ;item is the output of rand-nth
    ;TODO side effect here
    (println item)
    
    (if (<= 1280 accum)
      ;stop reducing
      (reduced accum)
      ;else, reduce further
      (+ accum item)))
  ;initial value of accum
  0
  ;infinite lazy seq
  (repeatedly #(rand-nth [1 2 3 4 5])))

raspasov 2021-04-02T09:59:03.441500Z

If you want to do side effects, reduce is a good choice

oxalorg (Mitesh) 2021-04-02T12:08:58.445300Z

Hey all! I'm going to be recording a screen cast about how to setup a Clojure + ClojureScript setup from SCRATCH! I struggled quite a bit when starting out trying to create a full-stack project without using templates. So hopefully this would help someone! I'm planning on starting with a blank directory and then walking through each of the following (in order): • deps.edn and REPL Driven Development • Ring + Jetty backend server • JSON api handler + HTML page handler • Hiccup and rendering html • CSS files • Simple vanilla clojurescript example (no additional tools) • Auto building cljs->js (no additiona tools, except cljs itself) • Solving server startup with `dev/user.clj` • REPL jacking in with dev profile • Easier server lifecycle management (basic introduction to the reloaded flow) • Adding in shadow-cljs and jacking in with clj&cljs BOTH • Adding Reagent and fetching our API from frontend • Adding Integrant • Small quick notes on repl_sessions and easy deployment What do you think would be some other important points to cover? or any other suggestions?

👍 5
👏 1
blak3mill3r 2021-04-05T01:12:09.088400Z

cider seems to work better with figwheel than with shadow-cljs (although I am not an expert on the latter, perhaps I was doing it wrong)

blak3mill3r 2021-04-05T01:12:21.088600Z

like, all the nice cider features were missing

1
oxalorg (Mitesh) 2021-04-05T06:04:43.104300Z

Oh! Could you perhaps mention a few features you're missing with cider & shadow-cljs? I haven't noticed anything in particular and found that after a bit of middle ware setup it works perfectly!

blak3mill3r 2021-04-06T13:14:59.185500Z

the one I specifically remember missing (with a cider cljs repl) was cider-inspector

blak3mill3r 2021-04-06T13:20:49.185700Z

cider-enlighten I think was another

blak3mill3r 2021-04-06T13:55:56.186100Z

also completions weren't working for me

oxalorg (Mitesh) 2021-04-07T17:30:04.226800Z

Yup, inspect and enlighten don't work for me either, but I rarely use them! Completions do work fine me though :thinking_face:

blak3mill3r 2021-04-07T23:46:57.241900Z

good to know... I'll fool around with the emacs side next time and get completions working. Thanks!

1
Dimitar Uzunov 2021-04-02T12:11:08.445900Z

making a jar file for deployment

💯 2
oxalorg (Mitesh) 2021-04-02T12:12:04.446100Z

Thanks yes I could talk quickly about it showing an example. I was trying to stay away from deployment as I wanted to create a separate video on it 🙂

Dimitar Uzunov 2021-04-02T12:13:09.446300Z

it is more of a build phase anyway 🙂

👍 1
✔️ 1
2021-04-02T12:15:03.447100Z

backend and frontend routing may be

💯 1
oxalorg (Mitesh) 2021-04-02T12:50:40.447400Z

Thanks. Yes routing is something I want to cover but I'm confused to what depth? I do plan to add a simple (case (:uri request).. router in my jetty handler to explain the flow of how routers work at their core. I mostly tend to use reitit as it's quite nice on both backend and frontend, do you think I should cover those to setup separately? Or are you thinking more along the lines of a single shared router between both frontend and backend?

2021-04-02T13:11:40.448200Z

I m thinking of separate routing setup for backend and frontend. I don't know that shared routing setup is even possible. If it is possible, would love to see this setup. Im thinking in the lines that, e.g. in nodejs/react app, we mostly add experess and react router at the start. because even a smallish app tend to have few pages on front end and few crud operations on backend.

oxalorg (Mitesh) 2021-04-02T13:13:52.448400Z

> I don't know that shared routing setup is even possible. > If it is possible, would love to see this setup. It's definitely possible with reitit, I don't have much experience with it but it would be a great way to learn and document. I would love to do this separately!! Thanks

oxalorg (Mitesh) 2021-04-02T13:14:35.448600Z

> Im thinking in the lines that, e.g. in nodejs/react app, we mostly add experess and react router at the start. > because even a smallish app tend to have few pages on front end and few crud operations on backend. Yes that is indeed true, but with adding routers do you think I need to talk a bit about content negotiation/encoding, middlewares or maybe interceptors too? :thinking_face: Edit: Maybe that would be a bit too much haha. I'll think about the most minimal example I can whip up with reitit

2021-04-02T13:20:30.449Z

Yeh indeed, negotiation/encoding and middleware come into play. And it may drag the direction to library usage, instead of minimal setup. May be you can have another screen cast, that is more involve with routing after the setup one

💯 1
🚀 1
oxalorg (Mitesh) 2021-04-02T13:21:06.449200Z

> May be you can have another screen cast, that is more involve with routing after the setup one Yes looks like that would be best! Thanks for your suggestions and feedback, super appreciate it 😄 ^_^

💯 1
🙏 1
2021-04-02T13:22:50.449600Z

Here how i setup a minimal reitit example. May be it can be further simplify.

(def app
  (ring/ring-handler
   (ring/router
    ["/api"
     ["/scramble" {:post  scramble-handler}]]
    {:data {:muuntaja m/instance
            :middleware [muuntaja/format-middleware]}})
   (ring/routes
    (ring/create-resource-handler {:path "/"})
    (ring/create-default-handler))))

🙌 1
2021-04-02T13:24:46.450Z

thanks @mitesh looking forward to the screen cast. :cljs:

1
oxalorg (Mitesh) 2021-04-02T13:24:48.450200Z

Lovely! I was thinking something very similar, but I also understand that this can get really daunting for someone quite new 🙈

oxalorg (Mitesh) 2021-04-02T13:25:26.450600Z

> looking forward to the screen cast. Thanks haha, I'll be sure to ping you once I have it up 🙂:nyantocat:

2021-04-02T13:28:06.450900Z

Yes pls do. I m fairly new in clojure land, And when I was try to setup my project, I was not able to find such screen cast. So I m sure, it will help a lot of new comers

💯 1
1
🙌 1
oxalorg (Mitesh) 2021-04-02T13:32:44.451400Z

I had the exact same experience! Trying my best to fill in this assumed gap, I already have a few beginner friendly clojure videos up here: https://www.youtube.com/channel/UCd588hDu4bszrSHlLXC8eZA If you're interested in checking it out 🙂

2021-04-02T13:41:48.451900Z

🙌 wow Im sure I will go through each of these videos one by one. thanks of making and sharing, 🎯

1
🥳 1
oxalorg (Mitesh) 2021-04-02T13:54:39.452200Z

Thanks a lot this means a lot! :sharkdance: 🙏

Endre Bakken Stovner 2021-04-02T14:33:41.454300Z

In the below code the let only differs for the outer loop.

(for [[rulename jobs] (group-by :in-rule jobinfo)
        job jobs
        :let [{:keys [params shell script]} (rules rulename)]]
Still, is the let computed anew for each inner iteration?

Endre Bakken Stovner 2021-04-05T05:25:36.096Z

Had no idea I could move the let. Thanks!

Endre Bakken Stovner 2021-04-02T14:34:29.454400Z

What about re-frame? It is on the very top of the stack though.

✔️ 1
sova-soars-the-sora 2021-04-02T14:38:16.454700Z

I like using Selmer for html templates so you can pass in variables and invoke them in the html template {{like-so}} I also like using rum a lot for cljs development, and it can actually render html on the serverside faster than hiccup if i recall correctly. Nice list. I think the goal ought to be to get to a repl as fast as possible and after each big step.

💯 1
🙌 1
zackteo 2021-04-02T15:07:09.454900Z

@raspasov no, I meant that if I use rand-nth only evaluates once. But I want it to reevaluate each time it is called in the seq

raspasov 2021-04-02T15:20:42.455500Z

I believe you’re mistaken. Look at the doc string for repeatedly :

Takes a function of no args, presumably with side effects, and
returns an infinite (or length n if supplied) lazy sequence of calls
to it

Adie 2021-04-02T15:22:14.455900Z

I have registered cursive with intellij. I now want to run the tests of one of my clojure services. How do I run the tests using cursive?

raspasov 2021-04-02T15:22:20.456Z

If you run the code I pasted, you’ll see ‘item’ being printed many times. It’s different each time.

raspasov 2021-04-02T15:23:32.456200Z

Also, the total sum at the end is different each time, which also shows that rand-nth is being called many times.

NoahTheDuke 2021-04-02T15:31:10.456400Z

to find out, you could embed a (do (println "hey") (rules rulename))

NoahTheDuke 2021-04-02T15:31:23.456600Z

but you can also move the :let above the job jobs line

💯 2
NoahTheDuke 2021-04-02T15:33:15.456800Z

user=> (for [a (range 1 5) :let [b (inc a)] c (range b)] c)
(0 1 0 1 2 0 1 2 3 0 1 2 3 4)

pavlosmelissinos 2021-04-02T15:35:11.457800Z

You've tried the instructions on Cursive's documentation and they don't work for you? https://cursive-ide.com/userguide/testing.html If so, it would help if you could be more specific

zackteo 2021-04-02T15:50:15.458500Z

Hi Everyone, how would yall approach a problem of generating a list of numbers that looks like [0 0 2 0 2 0 0 0 2 .... ] where the interval between the 2 are randomly chosen. Perhaps using something like rand-nth [2 2 3 4 5]

dpsutton 2021-04-02T15:55:43.459200Z

i'd probably make a lazy seq that would compute the random interval, put that many 0's and a 2, and then cons onto the "recursive" call

Elliot Stern 2021-04-02T15:57:50.459400Z

mapcat seems useful

Elliot Stern 2021-04-02T16:02:19.462400Z

(mapcat #(repeat % 0) random-intervals) will generate lists of 0 s of the specified lengths, then concatenate them together. I’ll leave it as an exercise to append the 2 and to generate random-intervals. (edit: replicate -> repeat)

dpsutton 2021-04-02T16:09:44.462600Z

TIL replicate

hindol 2021-04-02T16:12:21.463Z

Me too. But repeat is favored over replecate.

hindol 2021-04-02T16:12:39.463100Z

(take 100
      (flatten
       (interpose 2 (map #(repeat % 0) (repeatedly #(rand-nth [2 2 3 4 5]))))))
Something like this?

alexmiller 2021-04-02T16:35:50.463600Z

replicate is deprecated

oxalorg (Mitesh) 2021-04-02T16:45:35.463700Z

> What about re-frame? It is on the very top of the stack though. I plan to cover reagent, reframe, and building entire dashboards / admin panels / and complex real world projects with clojurescript. But those are for a separate video and I've been a bit lazy haha. I do have an intro to reagent video up with a simple todo app if you're interested in checking it out: https://www.youtube.com/watch?v=tRYreGS53Z4 🙂

👍 1
oxalorg (Mitesh) 2021-04-02T16:47:16.464100Z

> I like using Selmer for html templates I'm a bit on the opposite end here 🙈. After using html templating systems like Selmer over the years, I've come to really appreciate the hiccup approach (and to some extent even jsx). Composing html using clojure functions makes html painfree and powerful! But maybe selmer does make more sense to someone new :thinking_face:

oxalorg (Mitesh) 2021-04-02T16:49:00.464400Z

> Nice list.  I think the goal ought to be to get to a repl as fast as possible and after each big step. Yes EXACTLY!! 💯 REPL driven development makes everything so much more lively, I definitely want to give a feel of how to use the clj+cljs REPLs together.

oxalorg (Mitesh) 2021-04-02T16:58:51.466200Z

Every element in the sequence basically has a random chance of being either a 0 or a 2 (assuming 2's can be adjacent to each other). So something like this should also be enough:

(repeatedly 10 #({0 0 1 2} (rand-int 2)))
;; => (0 2 0 2 0 2 0 0 0 0)

pavlosmelissinos 2021-04-02T17:10:53.468Z

or maybe even (repeatedly 10 #(rand-nth [0 2])) ? this way you have some control over the distribution of the numbers, e.g. you can say (repeatedly 10 #(rand-nth [0 0 2])) if you want to have "twice" as many 0s as 2s (twice doesn't really make sense here, i'm using it figuratively)

alexmiller 2021-04-02T17:12:07.468500Z

you might also look at test.check generators to make these kinds of things

💡 2
alexmiller 2021-04-02T17:15:33.469Z

helpfully, spec makes them for you if you can describe the sequence

alexmiller 2021-04-02T17:15:43.469300Z

% clj -Sdeps '{:deps {org.clojure/test.check {:mvn/version "0.9.0"}}}'
Clojure 1.10.1
user=> (require '[clojure.spec.alpha :as s] '[clojure.spec.gen.alpha :as gen])
nil
user=> (gen/sample (s/gen (s/+ (s/cat :a (s/* #{0}) :b #{2}))))
((2) (2 2) (2) (0 2 0 0 2 0 0 2 0 2) (0 2 0 2 0 0 0 0 2 0 0 0 0 2) (0 0 0 0 2 0 0 0 0 2 0 0 0 2 0 0 2) (0 0 0 0 0 2 0 2) (0 2 0 0 0 0 0 2 0 0 0 0 0 0 0 2 0 2) (0 0 0 0 0 2 0 0 0 0 2 0 0 0 0 0 2 0 0 0 0 0 2 0 0 0 0 0 2 0 0 0 0 0 0 0 2 0 0 0 0 0 0 2) (0 0 0 0 0 2 0 0 0 0 0 2 0 0 0 0 0 2 0 0 0 0 2))

🤯 2
sova-soars-the-sora 2021-04-02T17:17:25.469600Z

what is s/*

sova-soars-the-sora 2021-04-02T17:17:35.469800Z

oh, multiply?

sova-soars-the-sora 2021-04-02T17:17:48.470Z

head scratching

pavlosmelissinos 2021-04-02T17:18:53.470100Z

https://clojure.org/guides/spec#_sequences > * - 0 or more of a predicate/pattern (check out the examples in the docs, they're really helpful)

sova-soars-the-sora 2021-04-02T17:37:14.470600Z

Ah, like FSM notation. So + is "one or more" ? thank you i will check out the link

2021-04-02T18:20:59.471300Z

btw replicate is deprecated, use repeat

👍 1
2021-04-02T19:17:44.472100Z

s/* => “Zero or more instances of” (like in regex)

alexmiller 2021-04-02T19:22:55.472800Z

https://clojure.org/guides/spec

yiorgos 2021-04-02T19:34:18.474100Z

Is there an easy way to parse a date string like this Fri, 02 Apr 2021 18:00:17 GMT into a date instance? I’ve tried with java.time.Instant/parse but didn’t work

2021-04-02T19:37:52.474200Z

DateTimeFormatter, in java time, will do that if you give it a pattern

👍 1
dpsutton 2021-04-02T19:38:15.474600Z

do you know how you ended up with that string?

yiorgos 2021-04-02T19:41:45.475200Z

Last-Modified header has a value like that, for example curl -I -X GET <https://martinfowler.com/feed.atom>

dpsutton 2021-04-02T19:50:07.475800Z

oh bummer

((juxt #(get % "Date") #(get % "Last-Modified"))
                              (:headers (http/get "<https://martinfowler.com/feed.atom>")))
["Fri, 02 Apr 2021 19:49:39 GMT" "Fri, 02 Apr 2021 18:00:17 GMT"]
was hoping those wouldn't be strings like that programatically.

yiorgos 2021-04-02T19:51:43.476Z

yeah 🙂

yiorgos 2021-04-02T20:00:20.477300Z

in case someone else finds it useful, the way I achieved that:

(def t (.parse java.time.format.DateTimeFormatter/RFC_1123_DATE_TIME "Fri, 02 Apr 2021 18:00:17 GMT"))
(java.time.Instant/from t)

Joseph Rollins 2021-04-02T20:52:18.479500Z

maybe more of a spacemacs question... I have both the clojure layer and lsp layer enabled and when I open a new file I get the namespace autogenerated twice e.g.:

(ns my-ns)

(ns my-ns)
anyone know how I can disable 1 of these two from filling in the namespace?

ericdallo 2021-04-02T20:52:39.479600Z

yes

ericdallo 2021-04-02T20:53:15.479800Z

Check *Conflict with clj-refactor when creating new files* https://emacs-lsp.github.io/lsp-mode/tutorials/clojure-guide/

🙌 1
Joseph Rollins 2021-04-02T20:53:59.480100Z

awesome, thanks!

👍 1
blak3mill3r 2021-04-02T21:44:48.480400Z

This is great! I'd love to see figwheel-main in there as well

😊 1
zach 2021-04-02T22:37:01.481900Z

would anyone know how to include XML CDATA in a hiccup map? I am writing a babashka script that takes an edn file with markdown and turns it into an RSS feed. e.g.

[:item
  [:title "new post"]
  [:link "<https://posts.com>"]
   [:description (markdown-&gt;html "**some stuff**")]]

borkdude 2021-04-02T22:39:27.482500Z

@webmaster601 according to the readme of clojure.data.xml:

[:-cdata "not parsed &lt;stuff"]

zach 2021-04-02T22:40:31.482700Z

oh, my gosh, thank you!

zach 2021-04-02T22:40:50.483100Z

Also, thank you for babashka. It is incredible!

❤️ 1