seems like a #figwheel-main question. assuming its not covered in the docs https://figwheel.org/config-options.html#connect-url
is there a way to have the reader insert the line number in what it read?
E.g., (this is a line which contains .#(get-reader-line-number) the line number in it)
Why is `(seq x)` the idiomatic version of `(not (empty? x))`?
I'm not sure this is a satisfactory explanation, but empty?
is (not (seq ,,,))
, so (not (not (seq ,,,)))
isn't very idiomatic.
You can see from the source code how empty?
is actually implemented
(not (seq coll))
https://github.com/clojure/clojure/blob/clojure-1.10.1/src/clj/clojure/core.clj#L6206
So as mentioned above, the not
's really cancel themselves out...
Ah, that does make sense.
Should the same be used for strings or is (not (clojure.string/blank? x))
appropriate?
I suppose (complement clojure.string/blank?)
is actually more idiomatic in that case..
If I use it pervasively I define it as a function.
Not to my knowledge
Since (coll? "x")
is false
, my understanding is that (seq "x")
is not the appropriate way to check for a blank string and I should use clojure.string/blank?
as I showed above.
I get that if I use it often it should be defined as a fn in my code so as not to repeat it often.
Regular expressions will give you a lot of expressiveness when checking strings and are often used with re-seq
, re-find
and re-matches
There is a simple example here
https://github.com/practicalli/exercism-clojure-guides/blob/master/bob/src/bob.clj
This is a useful regex cheatsheet
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/Regular_Expressions/Cheatsheet
Thanks guys.
I’ve written a little betting squares app as an exercise for learning Clojure. Is it appropriate to ask members of this channel to critique it? Looking for feedback on FP, idiomatic Clojure and code organization plus any other feedback. https://github.com/git4skatz/footballsquares
Small things I notice:
1. load
is almost never what you want. instead do something like (:require [footballsquards.score :as score] ...)
in your ns
` form.
2. i'd personally recommend using vectors rather than lists where a you just need a generic sequential thing.
3. case
rather than condp
for compile-time-known values
4. -1
seems like a really odd exit code
5. use (ns footballsquares.*)
instead of (in-ns '*)
6. the are cases where you use the generic symbol coll
to indicate multiple "types" of things: players, squares, charities. use distinct, descriptive symbols to avoid confusion
generally (aside from some other smaller whitespacing things that are more preference than anything), things looks pretty good to me! good job!
I'm loving the https://github.com/brandonbloom/backtick. Bravo @bbloom... well done
Thanks!!
can someone help me understand why the nil?
function uses (clojure.lang.Util/identical x nil)
rather than (= x nil)
Speed
checking (source =)
it would hit (clojure.lang.Util/equiv x y)
and does a bunch of work depending on the type of x, when it just needs to compare identical x nil
great so semantically it is the same?
i.e., there are no values which are = to nil without being identical to nil?
I cannot think of any values x
such that (= x nil)
is true but (identical? x nil)
is false. nil
in Clojure is the reference null
in the JVM, which I believe is effectively a null pointer.
That does not change the warning that identical?
is rarely what you want to use in Clojure.
(= (reify Object (equals [x y] true)) nil)
it seems you can get there but its your own shenanigans that do so
does the clojure compiler have a clojure specific optimizer which for example sees an explicit call to (= nil x)
and compiles it as (indential nil x)
?
do you suspect there is?
None that I am aware of.
There is no Clojure optimizer
The compiler mostly tries to make really obvious bytecode and then relies on hotspot to be an amazing dynamic optimizer with 100s of person years of work in it
you can always try the #code-reviews channel for feedback too
Thanks!
Hi, two noob questions on cljs.core.async. 1. Is it ok to read all available channel values inside the go-loop? I have a buffered channel where UI updates are posted and I would like to bulk it together. Code example:
(go-loop []
(let [v (async/<! b)
all-vals (loop [vals [v]]
(let [next-v (async/poll! b)]
(if (some? next-v)
(recur (conj vals next-v))
vals)))]
(js/console.log (str "Read " (count all-vals) " from channel") all-vals)
(recur)))
1. It seems that I'm able to put 2 more messages than buffer size on a chan. Am I doing something wrong?
thanks in advance!quick question: is it possible to do a with-redefs
but for an atom? On the clojure page it says that the change to the variable is visible in all threads. Id like a thread safe way of doing this
with-redefs is not thread-safe
unclear to mean if you are talking about a var referring to an atom or using an atom as an alternative to vars
Here is my problem: I have large code where I realize at the end of my logic we need to add a check that requires adding an argument in a whole chain of functions. I was thinking if it was possible to just have a global variable and then set that global variable in a thread safe manner as the value to be passed? But this doesnt sound right at all on second thought 😕
any solution to this?
say i have fn a, b, c, d. a calls b, b calls c, c calls d. I realize i need an argument on d, so i have to change all the callers of d, and all the callers of the callers of d etc. In my scenario, this branches out a lot, and it doesn't seem ideal to add an arg everywhere potentially hundreds of places.
@chaow one answer is to use a dynamic var and binding
but using a dynamic var has all the downsides of global state so it's worth thinking very carefully about whether that's a worthwhile tradeoff
yes thats the issue, the code i need to run is parallel
so it seems like there's not a lot of other solutions, seems a bit against the DRY priniciple to have the args repeated everywhere only for one single use 😞
depending what you're doing, dynamic bindings work fine with some parallel constructs in clojure (many things like future will propagate dynamic bindings to threads)
I’m pretty sure there are other options, but it’s difficult coming up with them based on the provided description
if you have a chain of functions, it’s likely you can chain them without having them directly call each other.
@chaow If you're still at that point in evolving your design, perhaps consider passing a hash map down the call chain instead of individual arguments? That way only the top-level code has to change (to assoc
in the new field that function d
needs).
Also, REPL-driven development would tend to lead you to develop d
first and you would probably have its arguments locked in before you write code that calls it. Not always true, of course, but working bottom-up via the REPL does help reduce this kind of refactoring churn in my experience.
the thing is im working in a company handling a lot of real time data so i really think dynamic vars aren't really safe to use. It was hard to do this at the design level because I wasn't there yet, im a fairly recent hire. I talked to my manager and we ended up dropping the feature because of how much code change we would need to do, guess this is a cost/benefit trade-off situation :man-shrugging:
I'm finding the error messages in Clojure pretty tough to track down what is actually wrong.
(ns clj-codewars.scratch2
(:require [clojure.string :as str]
[clojure.set :as set]))
(defn number->digits [num]
(->> num str (map (comp read-string str))))
(defn disarium-number [number]
(number->digits num) ; ***** error here, num should be number! *****
)
(disarium-number 89)
When I try to send (disarium-number 89)
to the REPL, the error I get is
Error printing return value at clojure.lang.Util/runtimeException
EOF while reading,
Not even any indication of where the error actually occured... Is their a package that can give me better help here for finding where the actual errors are in my code?Is this something that clj-kondo would help with?
@qmstuart your error is unfortunate, since num
is a function in clojure core apparently
so what happens is that in disarium-number
you are not using your argument number
, but you are passing the function clojure.core/num
to number->digits
clj-kondo will warn you about an unused argument in this case, so that could have been helpful
i suspect there's some unbalanced parens going on based on the error being "EOF while reading". And at that point there's largely not much clojure can do to make the error message better
@dpsutton the function clojure.core/num
is stringified and then read as code.
ah i totally glossed over that read-string was involved. good catch
user=> (map (comp read-string str) (str clojure.core/num))
Error printing return value at clojure.lang.Util/runtimeException (Util.java:221).
EOF while reading
(c l o j u r e . c o r e $ n u user=>
@qmstuart also, more generally, read-string
is a powerful function (it can even cause arbitrary code to execute in some situations), and in your case Long/parseLong
would be the safer (and weaker) option
oh, good to know! thanks!