Fork me on GitHub
#beginners
<
2021-03-30
>
cschep00:03:29

Could not locate clojure/core/async__init.class, clojure/core/async.clj or clojure/core/async.cljc on classpath.

cschep00:03:40

i’m requiring core async in a namespace

cschep00:03:48

and I have added it to my deps.edn

cschep00:03:56

{:dependencies
 {org.clojure/clojure {:mvn/version "1.10.3"}
  org.clojure/core.async {:mvn/version "1.3.610"}
  org.suskalo/discljord {:mvn/version "1.2.2"}}}

cschep00:03:08

(:require [clojure.core.async :as a]
            [discljord.connections :as c]
            [discljord.messaging :as m]))

cschep00:03:58

you’re a gem 💎 thanks!!

zackteo01:03:47

Hi everyone, may I ask is there a way to provide a fixed seed for rand-nth or for the whole of a small clojure program?

nate01:03:08

I was trying to find how to do this a bit ago and found that you couldn't. I found this lib: https://github.com/trystan/random-seed

andy.fingerhut01:03:45

There is not. You could copy and paste rand-nth, and implement it using a JVM method that allows one to provide a seed, e.g. from the class java.util.Random: https://docs.oracle.com/javase/8/docs/api/java/util/Random.html

nate01:03:45

I ended up not using it, but I will if I need consistent randomness in the future.

zackteo02:03:13

Thanks everyone!

zackteo02:03:23

How do I vote? 😮

Alex Miller (Clojure team)02:03:55

log in with your github id, click the up vote button

zackteo03:03:23

Okay done! I think I was also just surprised that there weren't any votes

3
Surya Poojary02:03:09

What can I use clojure for ? Aside from web dev?

dharrigan02:03:56

Anything particularly in mind?

Alex Miller (Clojure team)03:03:16

it's pretty good for making programs

👏 9
Alex Miller (Clojure team)03:03:41

particularly ones with data and functions

solf03:03:37

Pff another niche language. I never work with programs that use data and functions, it's all classes and methods in the real world (I usually don't, but I'll add /s this time as I don't want to risk having a bad rep here 😅)

raspasov04:03:16

@surya.rubyist excellent for UI work, particularly React/ReactNative

Surya Poojary04:03:47

i have started with clojure for the brave and true

Surya Poojary04:03:02

and its been an absolute pleasure !

Surya Poojary04:03:18

its almost like there's no syntax to learn

6
Surya Poojary04:03:03

though i'm not a professional programmer but i want to build stuff, with clojure as my primary tool.

Surya Poojary04:03:33

There's something very different about this beauty of a language

Dimitar Uzunov09:03:11

I’m using slurp, and when I stop the evaluation of my main function I get http://java.io.IOException: Stream closed in my REPL when I try to rerun it.. I think I’m missing something conceptually as I kind of expected that slurp will take care of the streams. Can someone recommend a resource on this topic?

Dimitar Uzunov09:03:18

I can workaround this by restarting the repl but it feels wrong

agile_geek09:03:14

Hard to tell without seeing the code but this doesn’t sound like anything to do with slurp but more to do with how you are evaluating the code? Is the slurp inside the -main function and you are running that fn in the repl? Depending on how you have written the code it’s possible that the -main fn once it completes is closing the REPL thread for example.

Dimitar Uzunov10:03:30

Its this expression: (Integer/parseInt (slurp in))

Dimitar Uzunov10:03:08

hmm I guess I need to use with-open?

Dimitar Uzunov10:03:35

the weird thing is that this snipped seemed to work for a while

gon10:03:01

*in* is opened by JVM at the starting, and slurp when returns close it, so the second time you try to access to it it's closed, you would need to use line-seq to read from stdin

👍 6
gon10:03:53

with-open would have the same behaviour, it's a macro that at the end closes the stream..

Dimitar Uzunov10:03:01

hmm I want to read a line at a time, so I switched to read-line for now

Dimitar Uzunov10:03:35

thanks! I guess I didn’t know that some functions close the stream

agile_geek10:03:13

None of the io fn’s and macros leave streams open as that would leave a hanging resource and cause a ‘memory leak’

agile_geek10:03:53

Although read-line is one way to go this is a little more explicit in what is happening with the *in* stream.

(doseq [ln (line-seq (java.io.BufferedReader. *in*))]
   (println ln))

🙏 3
agile_geek10:03:30

So as you can see this code starts a new BufferedReader for *in* on every evaluation. I haven’t looked at the details of read-line but I suspect it’s doing similar.

agile_geek10:03:52

Beware that example needs something to force realising the lazy sequence to make the print work

agile_geek10:03:36

So if you eval it in a REPL the Print in the REPL will force the sequence realisation but it wouldn’t work with just the println from a -main if called via command line.

agile_geek10:03:14

In that case if all you wanted to do was print your input you could use run! to map a side effectful fn (like println) over the sequence. (run! println (line-seq (.BufferedReader. *in*)))

Mark Wardle10:03:07

Is there a clever way of referencing a specific alias in a deps.edn git library reference? It may change how I structure my repositories…. Thank you.

Rowan Barnard10:03:43

Been following along in the Living Clojure book doing the exercises on 4Clojure, I just struck my first problem which taxed my brain a bit (still in the easy problems, I don't think I'm very good at this! 😂) The problem is Penultimate Element and asks "Write a function which returns the second to last element from a sequence." The solution I came to was: (fn [coll] (loop [c coll] (if (= (rest (rest c)) '()) (first c) (recur (rest c))))) I notice looking at another user's solution they used "empty?" in the if test, I forgot about that function, just wondering though is my use of = like this to test against an empty sequence is OK or not?

agile_geek10:03:01

Typically you’d use empty? and not test against a quoted empty list

agile_geek10:03:02

By the way the idiomatic way to test for a not empty sequence is to use seq as empty? is actually (not (seq xs)) so (not (empty? xs)) expands to (not (not (seq xs)))

Rowan Barnard11:03:52

Ah OK thanks @U05390U2P 👍 So my usage isn't idiomatic but will mine break in some way or is it fine?

agile_geek11:03:14

BTW you could simplify by removing the loop recursive binding and just recurse on the fn itself.

(fn [coll]
     (if (empty? (rest (rest coll)))
       (first coll)
       (recur (rest coll))))

agile_geek11:03:45

It would probably work ok as an empty list would equal an empty sequence.

Rowan Barnard11:03:12

Yeah I noticed other users did that too but they even had much simpler implementations than that which just used function chains and no explicit recursion on their behalf

Rowan Barnard11:03:22

Thanks for your insight @U05390U2P 😉

agile_geek11:03:04

Yep I probably wouldn’t use recursion but you can.

agile_geek11:03:25

Depends on whether the exercise demands the use of recursion as a learning exercise. For example you could use butlast to get a seq of all items except the last and then take the last of that new seq, e.g. (last (butlast coll))

agile_geek11:03:07

Or you could reverse the seq and take the second (second (reverse coll))

Rowan Barnard11:03:55

I will give that a try, some things it doesn't accept though if it makes it too easy I guess

agile_geek11:03:20

Yeah we don’t explicitly use recursion very often (usually we rely on high order functions like map and reduce ) but it’s useful to understand how it works as that’s what those fn’s use under the covers.

Rowan Barnard11:03:10

OK yeah it seems it is idiomatic to use what is already there in terms of functions, I am guessing my solution is probably what many people first do when they attempt this after coming from a bit of an imperative programming background, it will take me a while to learn the functions to use and the best way of doing things 🙂

agile_geek11:03:59

Yep. Knowing how to think about recursion rather than looping over a sequence is really important when coming from an imperative background (as I did!). For example loop is just a binding for var’s and a point recurjumps to and not an imperative looping statement

agile_geek11:03:24

Same with for - it’s a list comprehension and not a for statement

agile_geek11:03:05

Don’t worry if none of that makes sense yet. It will.

Rowan Barnard11:03:21

OK thanks! 👍😃

Surya Poojary11:03:29

How to implement a while loop in clojure?

Surya Poojary11:03:58

`
(defn looper [num]
(while (< num 10)
(println num)
(+ num 1)
)
)
`

vanelsas11:03:26

This is because you are not really updating the num var that you are using inside the while condition (it is immutable). You wil have to replace it with an atom that can be updated

vanelsas11:03:53

try something like this (not really useful code)

(defn looper [x] 
  (let [num (atom x)] 
    (while (< @num 10) 
      (println @num) 
      (swap! num inc))))

manutter5111:03:14

You can also do something like

(doseq [n (range 10)]
  (println (inc n)))
1
2
3
4
5
6
7
8
9
10
=> nil
(loop [n 1]
  (println n)
  (when (< n 10)
    (recur (inc n))))
1
2
3
4
5
6
7
8
9
10
=> nil

manutter5111:03:09

The first one is shorter and more idiomatic, the second one gives you more flexibility and control.

manutter5111:03:50

(Caveat: you may also see the for function, but beware, it’s not like for/`next` in other languages. The for function in Clojure returns a lazy list of values, meaning it will work fine at the REPL, and then when you go to use it in your program, it won’t actually loop when you think it should.)

solf11:03:07

Reminds me that when I started doing clojure, I didn’t learn how to do an “explicit” loop (i.e. not using higher order functions that did the actual loops) until very late

manutter5112:03:45

(do
  (println "Here's a `for` statement:")
  (let [nums (for [x (range 10)] (print (str (inc x) ", ")))]
    (println "The `for` is above this line, but the loop hasn't run yet!")
    (println "It will run when we actually use the lazy list of numbers:")
    (prn nums)))
Here's a `for` statement:
The `for` is above this line, but the loop hasn't run yet!
It will run when we actually use the lazy list of numbers:
(1, 2, 3, 4, 5, 6, 7, 8, 9, 10, nil nil nil nil nil nil nil nil nil nil)
=> nil

agile_geek08:03:44

Strictly speaking there isn’t a loop or for statement in Clojure. There is recursion and there are list comprehensions. For example for in Clojure is a list comprehension i.e. it is an expression that returns a lazy sequence but it can bind values to a local var inside the for form in order to produce that lazy sequence.

Surya Poojary11:03:03

;; it prints infinite 1 when called like (looper 1)

Lu11:03:50

If you find yourself needing some mutable state in your logic, there’s 99% chances you can use more idiomatic clojure to achieve the same result. In fact, if you need to manipulate your num within your function block, then loop recur is a better approach, or if you need to run n side effects then doseq works better.

Stephen21:03:55

Can someone point me somewhere where I can get a VERY BASIC project setup with only clj (+rum +ring, maybe some routing) and cljs. I want to ONLY use clojure clj and shadow-cljs. (NO lein or boot). I am a bit desperated xD ( https://clojureverse.org/t/how-to-start-with-clj-shadow-cljs-rum/7403/4 )

sova-soars-the-sora20:03:10

1 Lein -> clojure 2 Shadowcljs -> clojurescript 3 shared-components.cljc with reader conditionals 4) ensure html is identical on serverside and clientside when hydrating components Does this solve your problem?

seancorfield23:03:43

@ULE3UT8Q5 That is not going to address his question at all.

seancorfield23:03:34

He would still need to find a template that actually produces the setup he wants. I don’t know of any.

seancorfield23:03:27

(also, if you check out that thread on ClojureVerse, you’ll see he has it working now)

Stephen21:03:57

My basic goal is the define a rum component on the serverside, send it to the webpage and hydrate it with clientside rum. I want to only use clj and shadow-cljs

Stephen21:03:20

I feel it can not be, that no one has ever done that before... :(

seancorfield21:03:48

@stephen788 You definitely can run shadow-cljs via the Clojure CLI but it is not the recommended/preferred way. The docs are pretty thin on that. I recommend joining the #shadow-cljs channel and asking in there.

seancorfield21:03:35

I picked Figwheel Main for cljs dev because it seems to be easier to use with the CLI but I haven’t done much with it yet (distracted by other things).

sova-soars-the-sora20:03:10

1 Lein -> clojure 2 Shadowcljs -> clojurescript 3 shared-components.cljc with reader conditionals 4) ensure html is identical on serverside and clientside when hydrating components Does this solve your problem?