This page is not created by, affiliated with, or supported by Slack Technologies, Inc.
2020-08-04
Channels
- # announcements (6)
- # beginners (207)
- # calva (39)
- # cestmeetup (35)
- # chlorine-clover (36)
- # clj-kondo (15)
- # clj-together (1)
- # cljsrn (2)
- # clojure (110)
- # clojure-europe (8)
- # clojure-italy (9)
- # clojure-nl (2)
- # clojure-uk (5)
- # clojurescript (61)
- # conjure (4)
- # cursive (1)
- # datalog (3)
- # datomic (22)
- # emacs (8)
- # events (2)
- # figwheel-main (11)
- # fulcro (23)
- # graalvm (16)
- # graphql (1)
- # helix (4)
- # jobs (5)
- # jobs-discuss (4)
- # malli (3)
- # mid-cities-meetup (13)
- # off-topic (58)
- # pathom (12)
- # re-frame (30)
- # reagent (45)
- # reitit (1)
- # reveal (7)
- # sci (2)
- # shadow-cljs (173)
- # spacemacs (1)
- # sql (1)
- # test-check (5)
- # xtdb (13)
Hello all, Does anyone have experience with Criterium
benchmark-round-robin*
I am trying to construct the exprs map with generated macro but can't get the data structure without calling the expr itself.
it calls run-benchmarks-round-robin
which describes the input it needs pretty clearly https://github.com/hugoduncan/criterium/blob/67a5eabca18ef6aec6225aa64fcbedc0fde8c4ce/src/criterium/core.clj#L502
also it looks like benchmark-round-robin*
is an implementation detail of benchmark-round-robin
(this naming is common, adding a *
for an internal detail which is exposed) - that takes a series of forms and constructs the hash-maps that run-benchmarks-round-robin
uses
I wonder if the folks who steward the Persistent Vector in the standard library (looks like mostly @alexmiller, Stuart Halloway, Rich Hickey) have taken notice of the rewrite that happened to Scala’s Vectors (which were originally pretty much copied from clojure) that was merged in March, and results in many operations being order(s)-of-magnitude faster? Definitely at least worth a look to see if any of the improvements can be ported https://github.com/scala/scala/pull/8534
were those changes related to the CHAMP stuff?
I had not seen this, so thanks for the link, will look when I get a chance
at a glance, a few of the array opts seem like they are things already being done but need to read it more closely
can give a brief explanation of mono/megamorphism? I've seen it brought up before in similar contexts but never came across an explanation and how it affects jvm optimizations
if the JVM can see the same class at a particular callsite, it assumes that the class will show up and avoids doing method dispatch
there is only one commonly used persistent vector class in clojure, and 2 commonly used maps (PersistentArrayMap, and PersistentHashMap)
class at call site -> the class whose method is invoked? Also, how does the jvm dispatch? hash table?
if IBar is an interface, and class Foo implements IBar, I'm talking about x.bar() where some x is a Foo
if the JVM knows there's only one implementation of IBar in the whole class hierarchy, it can just ignore the dispatch and turn it into a static method essentially
(IMHO) one thing worth exploring is the map merge operation. Scala's maps exploit the structure of the HAMT while merging
btw, this whole convo is prob best in #clojure-dev in the future
I'm writing a regression test suite that compares entity map result sets against expected entity maps. The entity maps can contain doubles or floats and I only care if the results of those numbers match to a particular precision. I vaguely remember something in the clojure.test library that provides control over the precision of equality. Am I making that up?
https://github.com/microsoft/same-ish works if you want it to be actually quite close in terms of precision, more recently i just have been using https://github.com/clojure-expectations/expectations/blob/f12f710d49cfd1db5af6cba5fcbc8f798cadaa2c/src/cljc/expectations.cljc#L732. Since expectations is only clj, you may have to copy the function itself if you need it in cljs too.
Sorry — this is the clojure.test compatible version: https://github.com/clojure-expectations/clojure-test/blob/b30fefd97d9eb7d1f47e06956521f354cb926b03/src/expectations/clojure/test.clj#L380
or if not, I have learned something new
Alright. Thanks 🙂
There may exist a matcher for that in matcher-combinators.
I am personally pretty fond of that lib, but the usual ‘don’t add libraries randomly’ disclaimers apply
@markaddleman Math/nextAfter might help - finds the next double closest in the direction of a second arg
org.noisesmith.hammurabi-test=> (Math/nextAfter 1.0 -1.0)
0.9999999999999999
org.noisesmith.hammurabi-test=> (Math/nextAfter 1.0 2.0)
1.0000000000000002
of course, you might just want to make your own testing function based on -
if the precision of doubles themselves isn't your limitationCool. I didn't know that function existed
@dpsutton haha - the project name comes from the fact that his code was famously brutal to offenders (the project domain is contiguous / off heap low level data, with no reified java objects)
which means you can literally have pointer math errors that make you read from the wrong "thing", since the data is just a big pile of bytes
Sounds interesting. Not sure if you ever write or blog but I would definitely read it
also, fun fact, doing some background reading I found out that the brutal punishments only applied to "freedmen" AKA not nobles and not slaves nobles just paid fines, slaves were executed, it was the freedmen who go the eye-for-an-eye treatment
@dpsutton I would blog if I had more self discipline, I really think I should haha
but this project in particular would be a great blog topic
well, with off-heap there's no such thing as boxes, so that's a great start
there's also no such thing as methods...
long term plan is to also combine this with ASM.java, and this is all being done in parallel with learning arm64 assembly
domain task is doing as much DSP calculation within a given timespan as you can, with a fun language
as someone who came to a project using the assert-expr multimethod, I'd say that the annoyance factor of a reader knowing what the hell they are reading outweighs the convenience factor of extending the syntax of is
I see code like (is (foo x y))
, so I'm like "OK I guess I'll go look up foo" - no such thing
it does very little that foo wouldn't do as a function, and has the detriment that you need to remember a special case that doesn't follow any of clojure's idiomatic scoping rules
the amazing thing is that other people somehow survive using languages where this is commonplace
the sudden absence of sane scoping / clarity about where definitions come from really makes me realize how lucky we have it the rest of the time :D
you can pass a formatted string to is, including runtime data like actual values
> You can extend the behavior of the "is" macro by defining new methods for the "assert-expr" multimethod. These methods are called during expansion of the "is" macro, so they should return quoted forms to be evaluated.
(defn about-equal "Tests if the actual and expected values are equal in the given error margin." ([actual expected] (about-equal actual expected 0.0001)) ([actual expected error-margin] (<= (abs (- actual expected)) error-margin)))
@dpsutton that's my solution
=> (conj [1 2 3] (conj [1 2 3] [[1 2 3]])) [1 2 3 [1 2 3 [[1 2 3]]]] => (cons [1 2 3] (cons [1 2 3] [[1 2 3]])) ([1 2 3] [1 2 3] [1 2 3])
I'd suggest (- actual (Math/nextAfter actual expected))
is a better default than 0.0001
why is the behaviour of conj different than that of cons regarding the collection nesting?
because the collection and item args are reversed
cons takes item first, conj takes coll first
Depends on how much computation is involved. If many steps each computation is a chance for loss of precision
and depends on the precision of the values to compare against.
right, which is my motivation in using nextAfter to calculate a default
not the precision as much as the magnitude
I use my function to compare calculated values against text book values given with just 3-4 digits after the point.
the calculations give more fractional digits of course. But if all you have is a few fractional digits to compare against, you have to work in that precision (or magnitude).
ahh, that makes sense
Proposal: Implement IFn on clojure.lang.Atom, and it would just reset!
them. I.e.,
(def foo (atom nil))
(foo :bar)
@foo ; => :bar
Am I wrong?refs and vars (also mutable containers) implement IFn, and delegate to the function they contain
=> ((ref +) 1 2 3)
6
additionally, you really want mutation to stand out. making mutation look like any other function call would obscure the mutation
and swap! is preferable to reset!
because swap! is a function of the old value.
I mean, if what you want is to unconditionally set a value, and you don't care about the existing value, reset! is for exactly that, and better than a swap! / constantly combo
but yeah, if your primary action is on atoms is reset!, maybe they aren't the construct you actually want? a var would do fine for that