Fork me on GitHub
#clojure
<
2019-05-08
>
jeroenvandijk12:05:20

Is there a common trick to have clojure.walk/postwalk stop walking a data structure similar to how reduced can be used to stop reduce in walking a list?

dominicm12:05:39

Not that I recall from the source

Alex Miller (Clojure team)12:05:47

Nope, unless you check something stateful like an atom

jeroenvandijk12:05:17

I have a hacky solution that walks a structure twice, but I'll try to come up with something better

bronsa12:05:47

here's an implementation of walk/`prewalk`/`postwalk` over an AST that can be terminated via reduced

😄 4
bronsa12:05:59

should be easy to extract general versions a la clojure.walk

jeroenvandijk12:05:56

I just came up with this

(defn postwalk-reduced [f form]
  (clojure.walk/walk
   (fn [x]
     (if (reduced? x)
       (unreduced x)
       (postwalk-reduced f x)))
   f
   form))


(defn postwalk-reduced-demo [form]
  (postwalk-reduced (fn [x] (print "Walked: ") (prn x) x) form))

(comment

  (postwalk-reduced-demo {:a (reduced {:b 1})})
  (postwalk-reduced-demo {:a {:b 1}})

  )

jeroenvandijk12:05:13

Very basic, but seems to do what I want so far

jeroenvandijk12:05:18

(i probably have it wrong. I'll experiment a bit more and report later)

jeroenvandijk13:05:15

actually postwalk seems more complicated, but with prewalk I get what i want - stop changing nested datastructures)

(do
  (defn prewalk-reduced [f form]
    (clojure.walk/walk
     (fn [x]
       (if (reduced? x)
         x
         (prewalk-reduced f x)))
     unreduced
     (f form)))

  (prewalk-reduced (fn [x]
                      (if (and (seq? x) (contains? #{'fact 'facts} (first x)))
                        (reduced x)
                        (if (= '=> x)
                          '=?>
                          x)))
                    '(5 => 5
                        1 => 1
                        (fact
                         2 => 2
                         (fact => 1)))))

dominicm14:05:54

is there a predicate for knowing the state of a future? e.g. failed

Olical14:05:14

future-done?? - ah, failed... hmm

dominicm14:05:36

Looks like deref-to-map (private in clojure) does this:

(let [[ex val]
        (when-not pending
          (try [false (deref o)]
               (catch Throwable e
                 [true e])))])

vemv16:05:13

Anyone experienced in solving leaked sockets stuck in CLOSE_WAIT status? as reported in https://github.com/http-kit/http-kit/issues/326 Seems relatively common in JVM servers. http://www.serverframework.com/asynchronousevents/2011/01/time-wait-and-its-design-implications-for-protocols-and-scalable-servers.html has some some promising advice which seems to apply to my case: > Don't design a protocol whereby a client connects to the server every minute and does so by opening a new connection. Instead use a persistent connection design and only reconnect when the connection fails But still, our usage of http-kit is pretty vanilla so maybe there's a hard-and-fast fix

hmaurer16:05:53

Has anyone here experimented semi-extensively (aka more than just a hello world) with GraalVM’s native images for Clojure? I am curious as to whether it works well enough to use in production on a medium-sized project.

hiredman16:05:16

pushing such an experimental thing to production, when normal jvms exist and run java bytecode great seems like such a bad decision

hiredman16:05:11

like, all my experience with clojure professionally has been writing backend systems with it, and the jvm works great there, so it is just so hard to see any upside

hiredman16:05:29

that being said #graalvm is a channel that exists and you might try asking there

lilactown16:05:00

I think @hmaurer’s use case is AWS Lambda

lilactown16:05:10

we were speaking in #clojurescript about it

ghadi16:05:21

there is no good, only good for...

ghadi16:05:53

I'm pretty down on native-image and my personal opinion is that we spend a disproportionate amount of time fetishizing fast startup

ghadi16:05:07

rather than attacking bloat in dependencies

ghadi16:05:53

I see a lot of projects and when I run lein deps :tree or clj -Stree i'm always astonished

hiredman16:05:18

it isn't surprising though

hiredman16:05:41

a feature of targeting the jvm is getting access to all the libraries, so people go nuts with them

ghadi16:05:58

people also like fast food

hmaurer16:05:02

indeed; thanks @lilactown for specifying 😛

ghadi16:05:12

Ring still depends on clj-time and Joda, for example

ghadi16:05:37

for one tiny little use case

ghadi16:05:08

lots of projects pull in jaxb to do date parsing

ghadi16:05:17

an xml binding library, for date parsing

ghadi16:05:26

put that in your pipe

ghadi16:05:50

all of this slows down startup

hmaurer16:05:16

As @lilactown said my use case is to run the application in a serverless setting; multi-seconds startup times of the JVM are unacceptable there unfortunately 😞

ghadi16:05:18

anyways you're going to sink a lot of time into just getting native-image to compile on anything but the most trivial projects

dpsutton16:05:06

@borkdude has gone through this recently with clj-kondo

ghadi16:05:51

many people have spent time getting graalVM native image to play... you won't be able to take a random jar or dependency and compile it blindly. Look into jaotc @hmaurer, it doesn't have any of the restrictions that native-image has

ghadi16:05:53

if Java is ice cream, graal native-image is "frozen dairy treat" jaotc is still ice cream

hmaurer16:05:43

@ghadi I see; and does jaotc work with most hjars then? and does it speed up startups a lot?

ghadi16:05:57

yes it should

ghadi16:05:07

it is a bug if there is code that jaotc cannot handle

ghadi16:05:22

it does reflection, invokedynamic, etc

ghadi16:05:28

all the stuff native-image barfs upon

ghadi16:05:42

it comes with the jvm

ghadi16:05:54

Also based on Graal, totally different strategy though

hmaurer17:05:18

Alright I’ll try it out; thank you!

vemv18:05:54

The following doesn't appear to work - I see no meta changes: (alter-var-root #'something vary-meta assoc :deprecated true) Any ideas?

dpsutton18:05:20

you want alter-meta! right?

vemv18:05:07

right! thanks, had forgotten about that one 🙂 I would have expected the alter-var-root to work though

dpsutton18:05:41

the doc implies it works on the binding not the var

dpsutton18:05:47

but don't ¯\(ツ)/¯

vemv18:05:24

good one, root binding != value mutation

dominicm19:05:46

I'm trying to create vars to mimic the mathml structure, and there's a tag named true, which I obviously can't def. Is there a good suffix I should use? I'm reserving * for the function versions (unless I go for true** I guess?)

dominicm19:05:01

I like that, my only hesitation is that completion for tr wouldn't pick it up I guess :thinking_face:

dominicm19:05:14

Hmm, I'm trying to write a macro which writes a macro, and I'm getting a bit stuck with doing the unquote splicing in the nested defmacro. Any wizardry?

dominicm19:05:45

Oh, I can literally do a backtick inside a backtick!

borkdude20:05:56

How fast is the startup of a hello world program with jaotc compared to Graal native?

yuhan22:05:28

why doesn't clojure core have a div function that truncates toward negative infinity?

yuhan22:05:53

seems odd to have both mod and rem but no counterpart to quot

andy.fingerhut22:05:09

Probably because it is an uncommon use case? I don't recall anyone ever asking for one before.

andy.fingerhut22:05:49

What languages have such a thing?

yuhan22:05:21

Haskell, under the exact same names

yuhan22:05:00

I need it for some basic modulo arithmetic, it's easy enough to define on my own but it seemed like an odd omission

ivana22:05:57

it seems, that the roots of many decisions in Clojure came from the Java. maybe this case is the same?

yuhan23:05:11

I suppose so, couldn't find anything about the matter though

noisesmith23:05:55

I'm not sure, but would Math/floorDiv be related to what you want?

noisesmith23:05:33

returns largest int smaller than the or equal to the quotient

yuhan23:05:14

yes, that's it! Thanks 🙂

noisesmith23:05:54

for performance reasons clojure only goes far from the java Math stuff for opt-in accuracy reasons

noisesmith23:05:21

so if what I'm looking for mathematically isn't a correctness / precision improvement, I usually check the java.lang.Math API

yuhan23:05:37

I see, so the difference is that clojure.core functions take in all sorts of polymorphic types like BigInts and Ratios at the expense of some performance?

noisesmith23:05:50

more importantly they have contexts where they auto-promote to preserve accuracy, if you opt in

noisesmith23:05:05

eg. use +' instead of +, inc' instead of inc

noisesmith23:05:21

or use / instead of quot or java interop (?)

yuhan23:05:05

hmm I'll keep that in mind, thanks!