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-03-30T00:10:29.269800Z

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

cschep 2021-03-30T00:10:40.270200Z

i’m requiring core async in a namespace

cschep 2021-03-30T00:10:48.270500Z

and I have added it to my deps.edn

cschep 2021-03-30T00:10:56.270800Z

{: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"}}}

cschep 2021-03-30T00:11:08.271100Z

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

cschep 2021-03-30T00:11:13.271300Z

confusing

alexmiller 2021-03-30T00:11:29.271600Z

Should be :deps

cschep 2021-03-30T00:11:37.271900Z

ah, HA!

cschep 2021-03-30T00:11:58.272100Z

you’re a gem 💎 thanks!!

zackteo 2021-03-30T01:30:47.272300Z

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?

nate 2021-03-30T01:49:08.273800Z

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

2021-03-30T01:49:45.275Z

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

nate 2021-03-30T01:49:45.275200Z

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

alexmiller 2021-03-30T01:54:59.275400Z

we have a ticket for this - please vote for https://ask.clojure.org/index.php/4257/clojure-core-rand-for-seedable-randomness if you're interested

zackteo 2021-03-30T02:08:13.275700Z

Thanks everyone!

zackteo 2021-03-30T02:08:23.275900Z

How do I vote? 😮

alexmiller 2021-03-30T02:14:55.276100Z

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

2021-03-30T02:33:09.276300Z

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

dharrigan 2021-03-30T02:53:56.276500Z

Anything particularly in mind?

zackteo 2021-03-30T03:13:23.276800Z

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

➕ 1
alexmiller 2021-03-30T03:14:16.277200Z

it's pretty good for making programs

👏 3
alexmiller 2021-03-30T03:14:41.277500Z

particularly ones with data and functions

solf 2021-03-30T03:17:37.277600Z

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 😅)

2021-03-30T04:32:50.278300Z

@dharrigan GUIs?

raspasov 2021-03-30T04:39:16.279Z

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

2021-03-30T04:41:27.279200Z

ohh

2021-03-30T04:41:47.279600Z

i have started with clojure for the brave and true

2021-03-30T04:42:02.280Z

and its been an absolute pleasure !

2021-03-30T04:42:18.280400Z

its almost like there's no syntax to learn

✅ 2
2021-03-30T04:43:03.281300Z

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

2021-03-30T04:43:33.281700Z

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

Dimitar Uzunov 2021-03-30T09:36:11.284100Z

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 Uzunov 2021-03-30T09:37:18.284500Z

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

agile_geek 2021-03-30T09:54:14.284800Z

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 Uzunov 2021-03-30T10:07:30.285100Z

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

Dimitar Uzunov 2021-03-30T10:09:08.285300Z

hmm I guess I need to use with-open?

Dimitar Uzunov 2021-03-30T10:09:35.285500Z

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

gon 2021-03-30T10:12:01.285700Z

*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

👍 2
gon 2021-03-30T10:17:53.286Z

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

Dimitar Uzunov 2021-03-30T10:18:01.286200Z

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

Dimitar Uzunov 2021-03-30T10:18:35.286400Z

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

Mark Wardle 2021-03-30T10:28:07.288500Z

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.

agile_geek 2021-03-30T10:34:13.288700Z

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

agile_geek 2021-03-30T10:39:53.288900Z

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))

🙏 1
agile_geek 2021-03-30T10:41:30.289200Z

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_geek 2021-03-30T10:42:52.289500Z

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

agile_geek 2021-03-30T10:44:36.289900Z

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_geek 2021-03-30T10:49:14.293100Z

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 (<http://java.io|java.io>.BufferedReader. *in*)))

Rowan Barnard 2021-03-30T10:54:43.296600Z

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_geek 2021-03-30T10:56:01.296700Z

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

agile_geek 2021-03-30T10:59:02.297Z

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 Barnard 2021-03-30T11:05:52.297300Z

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

agile_geek 2021-03-30T11:06:14.297500Z

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_geek 2021-03-30T11:06:45.297700Z

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

Rowan Barnard 2021-03-30T11:08:12.297900Z

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 Barnard 2021-03-30T11:08:22.298100Z

Thanks for your insight @agile_geek 😉

agile_geek 2021-03-30T11:09:04.298300Z

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

agile_geek 2021-03-30T11:12:25.298500Z

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_geek 2021-03-30T11:13:07.298700Z

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

Rowan Barnard 2021-03-30T11:14:42.298900Z

Ah cool!

Rowan Barnard 2021-03-30T11:14:55.299100Z

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

agile_geek 2021-03-30T11:17:20.299300Z

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 Barnard 2021-03-30T11:20:10.299500Z

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_geek 2021-03-30T11:22:59.299700Z

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_geek 2021-03-30T11:23:24.299900Z

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

agile_geek 2021-03-30T11:24:05.300100Z

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

Rowan Barnard 2021-03-30T11:32:21.300500Z

OK thanks! 👍😃

2021-03-30T11:44:29.300700Z

How to implement a while loop in clojure?

2021-03-30T11:45:58.300800Z

`
(defn looper [num]
(while (&lt; num 10)
(println num)
(+ num 1)
)
)
`

agile_geek 2021-03-31T08:27:44.326800Z

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.

2021-03-30T11:47:03.301100Z

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

vanelsas 2021-03-30T11:50:26.301300Z

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

vanelsas 2021-03-30T11:51:53.301500Z

try something like this (not really useful code)

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

2021-03-30T11:55:14.304Z

You can also do something like

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

2021-03-30T11:56:09.304700Z

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

2021-03-30T11:57:50.307400Z

(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.)

solf 2021-03-30T11:58:07.307800Z

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

Lu 2021-03-30T11:58:50.308600Z

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.

2021-03-30T12:06:45.309200Z

(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)
=&gt; nil

2021-03-30T13:48:02.309400Z

Alrighty! Thanks @lucio

Stephen 2021-03-30T21:29:55.313Z

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 )

seancorfield 2021-03-31T23:14:43.335Z

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

seancorfield 2021-03-31T23:15:34.335200Z

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

seancorfield 2021-03-31T23:16:27.335400Z

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

Stephen 2021-03-30T21:30:57.314100Z

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

Stephen 2021-03-30T21:31:20.314600Z

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

seancorfield 2021-03-30T21:49:48.315600Z

@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.

seancorfield 2021-03-30T21:50:35.316400Z

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).