This page is not created by, affiliated with, or supported by Slack Technologies, Inc.
2020-04-08
Channels
- # announcements (6)
- # babashka (78)
- # beginners (84)
- # bristol-clojurians (5)
- # calva (50)
- # chlorine-clover (45)
- # cider (14)
- # clj-kondo (18)
- # cljs-dev (2)
- # clojars (2)
- # clojure (387)
- # clojure-android (3)
- # clojure-europe (6)
- # clojure-gamedev (3)
- # clojure-germany (3)
- # clojure-nl (18)
- # clojure-spec (5)
- # clojure-uk (36)
- # clojurescript (8)
- # clojurex (1)
- # conjure (1)
- # css (1)
- # cursive (32)
- # data-science (1)
- # datomic (11)
- # docker (61)
- # duct (17)
- # emacs (7)
- # figwheel-main (3)
- # fulcro (19)
- # jobs-discuss (3)
- # joker (1)
- # leiningen (23)
- # malli (11)
- # mount (6)
- # off-topic (30)
- # pathom (14)
- # pedestal (2)
- # phzr (1)
- # re-frame (11)
- # reagent (3)
- # reitit (5)
- # ring-swagger (3)
- # rum (1)
- # shadow-cljs (113)
- # slack-help (9)
- # spacemacs (16)
- # specter (4)
- # sql (14)
- # vscode (2)
- # windows (3)
- # xtdb (12)
Hey! I'm just curious about one thing... I was taking a look at the count
code and I found a call to a method ret1
(https://github.com/clojure/clojure/blob/30a36cbe0ef936e57ddba238b7fa6d58ee1cbdce/src/jvm/clojure/lang/RT.java#L643). this method seems to be used just to make the value of arg null, by calling like this: ret1(blah, blah = null)
. Does anyone know the reason for the existence of this method? why not just make something like:
countFrom(Util.ret1(o));
o = null;
Or even not change the value of o
because it’s local and it’s going to disappear when the method finishes its execution.Hi Alex! Sorry if I'm being annoying, but I'm just curious. Why is it necessary to make this clearing? The local variable will not just disappear anyway?
it's pretty tricky. the big thing we want to avoid is a strong gc reference to the head of a seq, and locals are treated as strong gc reference. So the ret1 trick has two parts to it - calling with the value and returning it turns the local into a stack value, and the second arg is unused but gives a convenient place to drop the statement that nulls out the local
some of this same work is also done by the compiler when it generates bytecode, but this is a handy tool to use for this problem in the Java code parts of Clojure
Thanks!
I got a little stuck with reagent with a cljs snippet below. Can someone explain this behavior?
I am experimenting with (hello-world)
vs [hello-world]
. The document renders in both cases, but h1
is only updated if I use [hello-world]
.
According to documentation https://reagent-project.github.io/docs/master/reagent.core.html#var-render, the second parameter of render
can be vector of hiccup syntax. That's why I planned to just simply encapsulate into a function, and return with the vector. I think this is what is called form-1
.
I have read https://cljdoc.org/d/mthomure/reagent/0.8.1-custom-components/doc/frequently-asked-questions/why-isn-t-my-component-re-rendering-
1. Yes I am using ratom through import reference. 2. I do deref with @number
. 3. My state is global. 4. It is not inside a seq.
So to my understanding (hello-world)
should work. Tried with reagent 0.8.1 (slightly modified code do to import changes) and 0.10.0 too without success. What am I missing?
(ns ^:figwheel-hooks proba.core
(:require
[goog.dom :as gdom]
[reagent.dom :as rdom]
[reagent.core :as reagent :refer [atom]]))
(defonce number (atom 0))
(defn hello-world []
[:div
[:h1 @number]
[:button {:on-click #(swap! number inc)} "inc"]])
(rdom/render
[hello-world] ; vs (hello-world)
(gdom/getElement "app"))
I’m not sure how it works for [hello-world]
(i’d be keen to know!) but when you use (hello-world)
I imagine that expression is being evaluated first, at compile time, including the deref hence being stuck with your initial value.
Thanks. That would explain indeed. Maybe the atom has some runtime initialization code that is prerequisite for linking the atom and the dom object together. Just the atom being global may not be enough.
I’m really keen to understand this - I started looking through the reagent source (for reagent.dom/render
) and couldn’t see where this linking occurs as I had the same hunch
See the source here: https://github.com/reagent-project/reagent/blob/master/src/reagent/dom.cljs#L27
Maybe hello-world
will work? (without the parens)
Your question is very targeted and the #beginners channel might not have the right audience who can answer.
I use cljfmt, which can be activated manually with lein but also has a vim plugin. The plugin sometimes messes up my git diffs by changing it's mind on indentation for functions I haven't touched, but it's pretty good and I just run the proper lein version before I commit
I checked it out but I ended up using parinfer-rust. Not because it's better, I really can't tell yet, I knew about parinfer and I like rust, I was curious. Also seemed like a more recent thing.
Hello, I'm having a problem with conversion from float to long (long (reduce + (map #(Math/pow % 17) (digits 21897142587612075)))) => 21897142587612072
this number is narcissistic so the output should be the same as the input, can somebody give me an idea whats happening?
user=> (long (Math/pow 9 17))
16677181699666568
user=> (apply * (repeat 17 9))
16677181699666569
the problem is you get into float territory which can represent larger numbers but at the cost to precision
maybe rely on double
for double-precision float then?
had to dig this page up for the first time in a decade https://docs.oracle.com/javase/tutorial/java/nutsandbolts/datatypes.html
Use math.numeric-tower
or write your own exponentiation without floating point math.
A simple (defn pow [a e] (reduce * (repeat e a)))
should to the trick despite being linear-time.
what is digits
It converts all the digits of a number into a vector
(defn digits [n]
(if (pos? n)
(conj (digits (quot n 10)) (mod n 10) )
[]))
Nice! This works too:
(defn digits [n]
(->> (iterate #(quot % 10) n)
(take-while (complement zero?))
(map #(rem % 10))
(reverse)))
And this:
(defn digits [n]
(map #(Character/digit % 10) (str n)))
Not for negative nums of course.pretty implementation
yeah maybe just changing long to double will be enough?
I'm not sure for which part about the code you are talking about, can you specify? thanks!
I managed to narrow the problem to off by 1 😆
(long (reduce + (map #(long (Math/pow % 17)) (digits 21897142587612075))))
user=> (long (Math/pow 9 17))
16677181699666568
user=> (apply * (repeat 17 9))
16677181699666569
I think the solution here is don't use Math/pow ?
https://github.com/clojure/math.numeric-tower has many useful math functions (that won't munge in coercion) or you could just make your own iterative multiplier fn to exponentiate.
I think the solution here is don't use Math/pow ?
https://github.com/clojure/math.numeric-tower has many useful math functions (that won't munge in coercion) or you could just make your own iterative multiplier fn to exponentiate.
Is there a way to catch a certain error ONLY IF it satisfies some predicate other than the exception type?
no, that's a constraint of the JVM
there are some libraries like slingshot that provide more sugar around ExceptionInfos
In my application, I have a recursive functions, and in some cases an exceptional situation occurs which I can handle at the call site.
Other times the exception cannot be handled.
everyone who reads your code will understand an if statement inside a catch statement with a rethrow 🙂
I'm currently using ex-info
, so at the call site I need to do a (try ... catch)
and somehow detect the fixable one, otherwise don't catch.
is rethrow the thing? but then the stacktrace will be wrong. right?
Or should I create my own exception type and catch that?
can I create a subclass of ExceptionInfo and use that to distinguish the fixable case from the others?
Rather than throwing an exception, I could just call the handler function directly. I could dynamically bind the handler function at the call site.
This would have the handler called without unwinding the stack.
you can rethrow with the original stack
how can I do that?
just throw the thing you caught
ah ok. I'll give it a try.
in Scala in such a situation, I can tell the original throw NOT to create a stacktrace, because I know I'm going to handle it.
Can I do that in clojure?
It doesn't change the semantics, but it is faster, as the system doesn't have to bother building a stacktrace which is expensive in heavy recursion cases.
you can construct an exception object without a stack trace (or even cache a static one - which I have totally abused when using exceptions as control flow)
not really any difference here between Java/Scala/Clojure - they are all working from the same toolbox
none of that stuff above is normal or the default, so more steps are required
I need to re-think how I want to handle this. It's getting complicated.
I think to get the suppression, you have to subclass Throwable and have the constructor call the one Throwable constructor that takes the enableSuppression flag to avoid fill the stack trace. That's all a pain to create in Clojure (concrete derivation is intentionally not easy).
I think I need to screen share with a clojure expert to ask how to handle this situation. Or perhaps I need to sleep on it and come back tomorrow.
The situation is that I want to calculate a "derivative" with respect to some "foo". Does not matter what foo is for this example.
the derivative function is heavily recursive, and sometimes when it gets to a leaf level, it figures out that "foo" is too big and needs to be split. the leaf code which figure this out knows how to suggest splitting foo into two or three pieces, at which case the caller of derivative needs to retry with the two or three pieces.
I could figure out the splitting at the call site but it would end up being much more work.
Currently derivative is called within a call to (reduce (fn [...] ... (derivative x wrt)) [initval] all-wrt-values)
inside reduce, you can call reduced
to short-circuit
if you need to stop consuming elements of all-wrt-values and exit the reduce early
@noisesmith. That is a really great feature, but does not apply to my situation now. I want continue reducing, it is just one call to derivative which needs to try again.
That Being Said, I will definitely use reduced
in other situations!!!
Thanks for the great suggestion
Sorry that it doesn't help now though 😞
I think I'll sleep on it and try tomorrow ... it's time to cook supper.
and my cats are begging for their supper as well.
I don't think I understand what is being done to the stack trace by catching and rethrowing that concerns you
right, the re-throw is happening from inside the same stack, it won't be misleading
re-throwing from inside catch is a preferred idiom