This page is not created by, affiliated with, or supported by Slack Technologies, Inc.
2021-03-30
Channels
- # babashka (18)
- # beginners (90)
- # calva (33)
- # clara (6)
- # cljfx (11)
- # cljs-dev (22)
- # cljsrn (9)
- # clojure (71)
- # clojure-australia (2)
- # clojure-czech (15)
- # clojure-europe (27)
- # clojure-germany (9)
- # clojure-nl (4)
- # clojure-serbia (3)
- # clojure-uk (10)
- # clojurescript (17)
- # conjure (12)
- # data-oriented-programming (2)
- # deps-new (6)
- # fulcro (29)
- # graphql (10)
- # hugsql (6)
- # jobs (1)
- # lsp (59)
- # malli (8)
- # off-topic (76)
- # pathom (15)
- # polylith (130)
- # re-frame (9)
- # reagent (15)
- # releases (4)
- # rewrite-clj (6)
- # ring (6)
- # rum (9)
- # shadow-cljs (116)
- # specter (5)
- # testing (7)
- # tools-deps (24)
- # vim (6)
- # xtdb (17)
Could not locate clojure/core/async__init.class, clojure/core/async.clj or clojure/core/async.cljc on classpath.
{: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"}}}
(:require [clojure.core.async :as a]
[discljord.connections :as c]
[discljord.messaging :as m]))
Should be :deps
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?
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
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
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
log in with your github id, click the up vote button
What can I use clojure for ? Aside from web dev?
particularly ones with data and functions
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 😅)
@surya.rubyist excellent for UI work, particularly React/ReactNative
i have started with clojure for the brave and true
and its been an absolute pleasure !
though i'm not a professional programmer but i want to build stuff, with clojure as my primary tool.
There's something very different about this beauty of a language
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?
I can workaround this by restarting the repl but it feels wrong
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.
Its this expression: (Integer/parseInt (slurp in))
hmm I guess I need to use with-open?
the weird thing is that this snipped seemed to work for a while
*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
with-open would have the same behaviour, it's a macro that at the end closes the stream..
hmm I want to read a line at a time, so I switched to read-line for now
thanks! I guess I didn’t know that some functions close the stream
None of the io fn’s and macros leave streams open as that would leave a hanging resource and cause a ‘memory leak’
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))
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.
Beware that example needs something to force realising the lazy sequence to make the print work
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.
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 (
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.
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?
Typically you’d use empty?
and not test against a quoted empty list
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)))
Ah OK thanks @U05390U2P 👍 So my usage isn't idiomatic but will mine break in some way or is it fine?
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))))
It would probably work ok as an empty list would equal an empty sequence.
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
Thanks for your insight @U05390U2P 😉
Yep I probably wouldn’t use recursion but you can.
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))
Or you could reverse the seq and take the second (second (reverse coll))
Ah cool!
I will give that a try, some things it doesn't accept though if it makes it too easy I guess
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.
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 🙂
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 recur
jumps to and not an imperative looping statement
Same with for
- it’s a list comprehension and not a for statement
Don’t worry if none of that makes sense yet. It will.
OK thanks! 👍😃
How to implement a while loop in clojure?
`
(defn looper [num]
(while (< num 10)
(println num)
(+ num 1)
)
)
`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
try something like this (not really useful code)
(defn looper [x]
(let [num (atom x)]
(while (< @num 10)
(println @num)
(swap! num inc))))
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
The first one is shorter and more idiomatic, the second one gives you more flexibility and control.
(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.)
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
(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
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.
;; it prints infinite 1 when called like (looper 1)
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.
Alrighty! Thanks @lucio
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 )
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?
@stephen788 you can try https://github.com/seancorfield/clj-new if you want a template
@ULE3UT8Q5 That is not going to address his question at all.
He would still need to find a template that actually produces the setup he wants. I don’t know of any.
(also, if you check out that thread on ClojureVerse, you’ll see he has it working now)
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
@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.
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).
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?
@stephen788 you can try https://github.com/seancorfield/clj-new if you want a template