the BigInteger
hash code is different by 60 :man-shrugging:
at this point I don’t recall where I saw the hash code called out, maybe a very early Joy of Clojure edition? :thinking_face:
but the largest N you have seen so far might not be the largest N items by the time you reach the end, so you lose some stats about early occurrences of the largest N sometimes?
Need some help on this. Will you defprotocol Foobar with only a SINGLE defrecord FoobarImpl implementing the protocol? This way helps unit test so that we can write a defrecord FoobarTestImpl, but on the other side, I feel writing code in this way only for testing is unnecessarily complicated. Why not directly write functions working on the passed-in data? And we can use with-redefs to change the function logics under testing.
I do it and know of other teams also doing it it's the sort of thing that may look ugly from the outside, but once you just try it one sees only a useful, clean pattern that's not even particularly verbose (I'm a fan of implementing protocols via metadata; this also kills some code-reloading issues)
Interestingly, protocols can be considered to reify side-effects (or "side-causes"), yielding a functional (-ish) architecture
Hi. Didn’t quite get this part: protocols can be considered to reify side-effects (or “side-causes”), yielding a functional (-ish) architecture.
under vanilla clojure, if you want to perform a side-effect, you normally just do it, inline:
(write-to-db! ...)
such calls make a given defn impure. There's no automated way to analyse impure functions, instrument them, etc
by having protocols to perform all side-effects, you can get a comprehensive listing all sorts of side-effects/side-causes going on in your codebase. It's easier to determine if a given defn is impure: if it receives an object that implements a protocol as an argument, then it's almost certainly impure
there are various other gains as you can imagine: swapping implementations (for making tests faster/deterministic) etc
I’m not a fan of creating a protocol purely for mocking during testing. That feels both too-OOP-ish and just plain unnecessary.
with-redefs
has its problems but using functions feel like the “right” approach to me — why not pass in the function that you might otherwise want to redef? Or refactor your code so you don’t have a (presumably) side-effecting call in the middle of it?
When I call realized?
on a "pending after start realize" delay
it blocks my call until realized.
Is it expected
(repl example in the first comment)
(let [x (delay
(Thread/sleep 1000))
start (System/currentTimeMillis)
diff! #(- (System/currentTimeMillis)
start)]
(prn [:before (realized? x) (diff!)])
(future
@x
(prn [:after-deref (realized? x) (diff!)]))
(Thread/sleep 100)
(prn [:after-start-deref (realized? x) (diff!)]))
[:before false 0]
[:after-start-deref true 1001]
[:after-deref true 1001]
=> nil
I think there’s an IPending or something similar that gets involved with this
https://ask.clojure.org/index.php/10004/calling-realized-delay-currently-executing-blocks-caller
in the queue for 1.11
regarding difference between Clojure's hash
and Java's hashcode
see https://clojure.org/guides/equality#equality_and_hash
Has anybody here had to create POJOs before? I have a specific requirement to interface with jackson-databind, which runs on POJO's with specific Java annotations on the POJO classes, constructors and getters. Has anybody done this kind of thing before? I can get one POJO declared with gen-class, but the syntax is cumbersome for the many POJOs I need to create. I thought I'd use a macro to create the gen-classes for me, but with my own macro I can't pass in the meta-data that gen-class needs for annotations... Does anybody have some advice for me?
I had a similar case when implementing a web service API where I needed java classes with lots of annotations (and no args constructors, mutable fields with setters,…) to generate the WSDL. In the end I decided to just define the classes as plain Java code, instead of constructing them by gen-class etal.
Have you tried using defrecord? It supports Annotations I believe. Some Java APIs need a default constructor though and in that case gen-class is all I've come up with when I needed it.
Hey! Quick question: How can I efficiently update every nth element in a vector? As in, I want something faster than iterating over every single element. Thanks! (I just posted the same question on #beginners, not sure if I should have posted here instead)
Vectors are associative collections, so just (assoc v 17 x)
.
Oh, sorry, I missed the "every" word. Then just mapv
.
Thanks! I tried to understand it but I don't see how that would be done (I'm still a beginner, sorry...) And wouldn't that still require iterating over the entire vector?
A possible way using transients. This multiplies each 3rd element by 10
(let [data [1 2 3 4 5 6 7 8 9 10]
step 3]
(persistent!
(reduce
(fn [data i]
(assoc! data i
(* (get data i) 10)))
(transient data)
(range 0 (count data) step))))
;; [10 2 3 40 5 6 70 8 9 100]
Ah but if you’re beginner there’s also the more straight-forward way without using transients:
(let [data [1 2 3 4 5 6 7 8 9 10]
step 3]
(reduce
(fn [data i]
(assoc data i
(* (get data i) 10)))
data
(range 0 (count data) step)))
;; [10 2 3 40 5 6 70 8 9 100]
Thank you! Do you know if this offers better performance than the solution Alex gave? I'll paste it here:
(loop [coll v, i 0]
(if (< i (count v))
(recur (assoc coll i (inc (nth coll i))) (+ i 10))
coll))
it should be faster, yes I didn’t see the (+ i 10)
, it’s pretty much the same written differently
but only marginally so?
The transient version however should be noticeable faster. You could also add transients to Alex solution though
Here’s the official guide if you’re interested in performance: https://clojure.org/reference/transients
mapv
uses transients by itself. Don't try to optimize without measuring and at places that aren't bottlenecks.
Fair point, but mapv
would still have to loop over every item, which can be very bad depending on how big is the nth
Ahh, right, I see - you have created a transient from the already existing data. Makes sense, and I'm especially blind today for some reason.
I also tried defrecord but could not make it work
Since vector is associative you can use update
as well with an index as second argument:
(update [0 0 0 0 0] 2 inc)
;; => [0 0 1 0 0]
Ah I see there’s no transient version update!
, that’s why above used assoc
Indeed, for the non-transient version update
is better
I'm not a JAVA guy and I just briefly know what a "POJO" is, but i thikn that these links can help https://github.com/clojure/java.data https://clojure.org/reference/datatypes#_java_annotation_support
Any profiler recommendations? It's all Clojure code, and so far I just want to know which functions we're spending the most time in
probably the easiest clojure-oriented profiler. you can use any JVM profiler too (YourKit, JProfiler, VisualVM etc)
Just published an article about Jive, an architecture where UI code is server-rendered but still web-based. This enables native backends with the reach of web. Give it a read and share your thoughts! https://kalavox.medium.com/jive-for-artisanal-software-2df0d675c104
> It doesn't exist yet
Bear in mind that by default it shows on-CPU time - if you are interested in wall clock time there’s another option for it
Has a reflection cache been considered for Clojure? I.e. cache the lookup of the method based on the type of the receiver and types of args?
What’s the unsaid problem that is trying to solve?
(drink beverage of choice)
@ghadi I'm just trying to gain information if something like this has been discussed before
The problem could be that repetitive lookups are a waste, but I'm not sure if that is true. I'm just thinking out loud, hoping that someone will say something smart or will provide a link to an existing JIRA :)
Context: I am working on an issue in the context of a graal-compiled binary where reflection works a bit different, since not all classes might have all information available, but sometimes methods can be found by visiting super classes and doing lookups on those, which seems quite wasteful to do repetitively. So I wondered if this topic had come up before.
😂 at the ninja edit -- I saw it. I have only considered it in the context of making a cache at reflective callsites. That would reflect only at the first invocation, then remember the dispatch for subsequent invocations.
for that use-case (slow "unresolved/reflective call" ), it's probably better to not reflect
aka tell the developer to be explicit
the topic of asking putting a method reflection cache in the compiler has come up some years ago
but again, that's an impl thing, not a problem thing
can you describe the graal thing some more?
Solved part 2
yeah ok. two things:
1) the SCI interpreter is using reflection at runtime to perform interop calls (this can be optimized more, but that's how it works currently)
2) Graal native binaries support reflection configs. This makes it possible to reflect at runtime like you would in the JVM. But if you don't provide a config for class X
let's say, and you wanted to call Object.notify
on an instance of X
, you would reflect on the class X, but find nothing. However, when you visit the superclass, e.g. Object, and you had a reflection config for Object, then you would still find notify
and would be able to call it. This is more work than you would normally have to do on the JVM in the clojure.lang.Reflector
. Depending on which class you hit, you would hit that path or not, so I would have to do some benchmarking etc to see how bad the overhead is there, but that's where I'm coming from.
I don't know of anything like this in jira. The general rule is if it matters, stop using reflection. So, not much interest historically in trying to optimize the not optimized case.
ok, thanks
I have a weird bug when working with RELEASE dependencies: "clojure -X:notebook" brings this error Execution error (FileNotFoundException) at clojure.run.exec/requiring-resolve' (exec.clj:31). but "clojure -P -X:notebook" works fie. Thishappens only when there is no artefact of the dependency in .m2 cache. Is there a shortcut that works in all circumstances?
you have a stale classpath cache
clj caches the calculated classpath between executions to speed up startup
(goes in ./.cpcache)
you are running the clojure script in an evinronment where the cache exists, and tells it the dep is in ~/.m2, but that isn't the case