This page is not created by, affiliated with, or supported by Slack Technologies, Inc.
2020-02-11
Channels
- # announcements (16)
- # aws (4)
- # babashka (30)
- # beginners (58)
- # bristol-clojurians (4)
- # cider (9)
- # clj-kondo (2)
- # clojure (229)
- # clojure-europe (25)
- # clojure-gamedev (1)
- # clojure-italy (4)
- # clojure-nl (13)
- # clojure-sanfrancisco (1)
- # clojure-uk (97)
- # clojured (7)
- # clojurescript (27)
- # code-reviews (2)
- # cursive (30)
- # data-science (39)
- # datomic (14)
- # emacs (12)
- # events (2)
- # fulcro (6)
- # graalvm (8)
- # graphql (14)
- # jackdaw (10)
- # jobs (2)
- # lambdaisland (5)
- # malli (4)
- # off-topic (28)
- # protorepl (13)
- # quil (7)
- # re-frame (2)
- # reagent (1)
- # reitit (3)
- # remote-jobs (5)
- # ring-swagger (1)
- # shadow-cljs (72)
- # sql (4)
- # tools-deps (182)
- # uncomplicate (4)
- # vim (9)
- # xtdb (19)
Morning
Mornin'!
Did you survive the storms OK?
I always find the UK's reaction to "storms" fairly comical š We had a fence pop out, but managed to get it back into place quite easily thankfully. Trampoline did nearly blow away 2 days ago though! How are you doing Sean?
We had high winds too this weekend. Several trees down in our town and road closures and a big chunk of the town was without power for a day or so.
Most of the schools were closed because of loss of power.
Sounds like you had it a bit worse than us then
Lights only did a little bit of flickering
We had several "brown outs" -- lights flickering and our router rebooting... which played havoc with us binge-watching Ragnarok (the Netflix show from Norway).
It was awesome! We got through all six episodes last night, despite the storm š
We binge-watched October Faction before that. Also awesome.
Don't mess with the internet! I think that would have been rather annoying š
We got through about 4 episodes of October Faction. I was enjoying it. I think the OH wasn't convinced
We've been binge watching Van Helsing.
Onto the final season that's just come out
Sean, I have a question for you. It's about remote repl in production. Not about the merits/demerits, etc., just this. When you run your code (in a docker image? natively, as a jar?), do you always run it with a socket server listening (with appropriate firewall/security rules to prevent those without appropriate permissions to access), or do you have to redploy the image with the socket server listening, or do you have a magic toggle somewhere (db?) that the application polls frequently to determine whether to fire up a socket server?
We run everything on the base O/S using java -jar
now (we used to use java -cp ... clojure.main -m entry.point
) and our "service" script looks for a .jvm_opts
file next to the JAR file and uses the contents of that, if present, in that java
command.
Some processes have .jvm_opts
files, some don't. Some only have them when we first put them in production, to aid with debugging, some get to keep them all the time. Some don't have one, but we'll add one temporarily (and just service <whatever> restart
to pick it up), if we need to debug something unexpected.
All of them are set to bind to 127.0.0.1 only, I believe, and we use an ssh tunnel over the VPN to get access from local systems (I can just connect Atom/Chlorine to a remote process that way and evaluate code in Rich Comment Forms for debugging -- and occasionally eval an updated function directly into production if I need additional debugging or a patched version for a quick bug fix).
In the later case, we'll also fast-track a fix through CI/QA to production to make it permanent.
right right, so they aren't enabled by default, only if the opts file is there, and if it needs to be, then the file is dropped into place and the service restarted. kk. understood š
For me, I run inside a docker container, so if I need a repl I redploy the docker container with the JVM_OPTS magic incantation to enable a socket listener then expose the port on the container - this port is only accessible to the local dev network
I just checked on one of our production servers, and two of our seven processes have those files in place. So they're "permanent" in that respect.
I was toying with the idea of having a feature toggle that the application would poll every minute or so and if enabled, it would start the socket server, give this a more dynamic ability - I'll ponder.
We used to have something like that but moved away from it because we just didn't find we needed to dynamically start REPLs -- and didn't want the extra code (and polling) in production.
Morning.
can you bind the repl to localhost and shell in to your running container to access it @dharrigan ?
morning. CO2 count back to 444ppm at the moment, probably a bit lower today as uesterday we had a fullhouse with 10 people in the office.
the very-new-and-expensive firth-of-forth roadbridge is close due to risk of ice falling from the suspension cables
which is a bit embarassing
given that the risk to the other one was catastrophic failure, there did need to be something
didn't ice accumulation figure in the original design? that's what I dont understand
just been a bit windy
the ice/snow hasn't been spectacular
I would have thought so. I wonder if this is one of the less likely cases for accumulation (right temp, right humidity, right wind)
yeah maybe; freak conditions are always possible of course
it does sound a bit strange though
Oh! ill-fated Bridge of the Silv'ry Tay / I must now conclude my lay / By telling the world fearlessly without the least dismay / That your central girders would not have given way / At least many sensible men do say / Had they been supported on each side with buttresses / At least many sensible men confesses / For the stronger we our houses do build / The less chance we have of being killed
yes exactly
@conor that poem is engraved in the pavement here looking at where that bridge was and where its replacement stands
or rather @conor.p.farrell
do fragments of steam engine appear at low time?
long ago swept into the North Sea I suppose
The dark counterpoint to > There's another train, there always is is > The train you are currently on may crash at any moment
@ben.hammond I'll still hoping a gamma ray burster gets me instead. It might be on its way right now!
dispatched 10e9 years ago, solely for the purpose of frying you
oh, not just to get me. I'm just collateral damage in a thoughtless and uncaring universe. It helps keep my megalomania down.
meglomania is one of life's guilty pleasures why deny it? why keep it down?
RCFOTD:
clojure.test/join-fixtures
([fixtures])
Composes a collection of fixtures, in order. Always returns a valid
fixture function, even if the collection is empty.
morning
If you're in or around Bristol tomorrow, we're running a meetup with the topic of async in Clojure: https://www.meetup.com/Bristol-Clojurians/events/hdzjnrybcdbqb/ should be good, come along
re: #queensferrycrossing, here's a civil engineer's blog article on the topic of icy bridges... https://www.newcivilengineer.com/archive/bridge-brilliance-falling-ice-10-08-2016/
Apparently it's rare enough that mitigation is the most pragmatic solution at the moment. Can't design a way out of it without using up too much energy.
I'd also read today that over the last 2 years the old bridge would have been closed 34 more times, so the new bridge is an improvement.
I'd also read today that over the last 2 years the old bridge would have been closed 34 more times, so the new bridge is an improvement.
So, I'm trying to express predicates on maps as maps / vectors, similar to enlive's implementation - but no nesting on the subject, :. no automatons - This doesn't feel like a very idiomatic way to get the job done:
(defn or-map-pred
"Give map `m' (record), and map `p' (pred|pred|...) return any: p_n is true for m.
returns true/false on the k/v being present in the record, OR
returns true if `p' is nil/empty. "
[m p]
(boolean
(or (not p) ; permit nil/{} blank preds as `true'
(empty? p) ; covering ^
(some #{true}
(map (fn [k]
(= (get m k) (get p k)))
(keys p))))))
(clojure.core.test/is
(true?
(or-map-pred {:title "Test Data Yas" :favourite? true}
{:favourite? true})))
This function can be mapped and/or filtered, even composed as and
:
(defn and-map-pred
"Give a map (record), and a vec (pred&pred&...)"
[m p]
(every? (fn [pred] (or-map-pred m pred)) p))
(
(true? (and-map-pred {:title "Test Data Yas" :favourite? true}
[{:favourite? true}])))
Filtering:
(defn dec-filter
[coll pred]
(filter #(and-map-pred % pred) coll))
(dec-filter [{:title "blah 1" :attr "goose"}]
[{:attr "goose"}])
;; => [{:title "blah 1" :attr "goose"}]
Before I go down the rabbit hole here, can I get some thoughts from the room? Feel free to roast this implementation
Edit: I realise I haven't really asked a question here, so:
ā¢ Would you advise against the use of closures to pass pred
s down in each of these functions?
ā¢ This implementation is mapping everywhere, and will scale poorly as the size of the predicates grow; are there any strategies you use to sense-check the placement of ISeq
functions (map / filter / every?)er so it sounds like you are describing
(defn cmp-maps
"return true if any mapentry in m1 equals a mapentry in m2"
[m1 m2]
(reduce-kv (fn [acc k v]
(when (= v (get m2 k))
(reduced true)))
nil
m1))
similiarly
(defn cmp-maps2
[m1 m2]
(some
(fn [[k v]] (= v (get m2 k)))
m1))
general scaling advice is to prefer reduce
unless you've got something funky (like a string append) where apply
may scale better
hmm it seems related to knowing if a map is included in another, so these could provide some hints: https://stackoverflow.com/questions/20421405/how-to-check-if-a-map-is-a-subset-of-another-in-clojure https://stackoverflow.com/questions/22562325/how-to-subset-a-map-in-clojure/22562457
However it sounds like you are trying to do some querying logic, so why not trying to use a logic engine (clara rules, core.logic), or even datascript
In my free days, I've just been exploring declarative query interfaces, and I was really captured by enlive's implementation. The logic above is just a thought process around a UI component that allows users to filter a grid on a bunch of tokens for arbitrary attributes from the data in the grid
This is all in efforts to show co-workers (primarily the Csharp devs) that it doesn't take much to write expressive code in Clojure -- I feel like I can't go too deep on core.logic from the jump
KISS makes sense indeed. Also metabase, which is open source and written in clojure, may provide some inspiration with respects to declarative querying interfaces: https://www.metabase.com/docs/latest/users-guide/04-asking-questions.html
@ben.hammond Thanks for taking the time! Those cmp-maps
functions are direct subsitutions for or-map-pred
(aside from nil/empty considerations), and a much cleaner way to go
i had a bad experience with reduce-kv, and haven't gone back for a while haha (shield your eyes for the below)
(defn nsmap
"Namespace all unqualified keys in `m` with `n'.
[m]: Takes a map of maps, flattens & namespaces inner keys with outer keys.
e.g
(ns-map {:links {:artist \"/Nas/\" :title \"/Nas/Halftime\"}
:text {:artist \"Nas\" :title \"Halftime\"}})
;; => {:links/artist \"/Nas/\" :links/title \"/Nas/Halftime\"
:text/artist \"Nas\" :text/title \"Halftime\"}
"
([m]
(into {} (map #(nsmap (% m) (name %)) (keys m))))
([m n]
(reduce-kv
(fn [acc k v]
(let [new-kw (if (and (keyword? k)
(not (qualified-keyword? k)))
(keyword (str n) (name k))
k)]
(assoc acc new-kw v)))
{} m)))
just for fun, I think I'd write that as
(defn flatten-maps
"depthfirst traversal of nested map, creating flat map keyed by vector paths "
([m]
(into {} (flatten-maps [] m)))
([prev m]
(if (map? m)
(eduction
(mapcat (fn [[k v]] (flatten-maps (conj prev k) v)))
m)
[(clojure.lang.MapEntry. prev m)])))
(flatten-maps {:links {:artist "/Nas/" :title "/Nas/Halftime"}
:text {:artist "Nas" :title "Halftime"}})
=>
{[:links :artist] "/Nas/",
[:links :title] "/Nas/Halftime",
[:text :artist] "Nas",
[:text :title] "Halftime"}
(flatten-maps {:a {:b 2 :c {:d 3 :e {:f {:g 4 :h 5} :i 6 :j {:k 7 :l {:m 8}}} :n 9}} :10})
=>
{[:a :c :e :i] 6,
[:a :c :e :j :l :m] 8,
[:a :c :e :f :h] 5,
[:a :c :e :f :g] 4,
[:a :b] 2,
[:o] 10,
[:a :c :n] 9,
[:a :c :e :j :k] 7,
[:a :c :d] 3}
I had to solve this in a previous life... but this time round I think I have a nicer solution
actually that eduction
does not really add anything and can be removed
going the other way is alot easier
(reduce-kv assoc-in {} {[:a :c :e :i] 6,
[:a :c :e :j :l :m] 8,
[:a :c :e :f :h] 5,
[:a :c :e :f :g] 4,
[:a :b] 2,
[:o] 10,
[:a :c :n] 9,
[:a :c :e :j :k] 7,
[:a :c :d] 3})
=>
{:a {:c {:e {:i 6, :j {:l {:m 8}, :k 7}, :f {:h 5, :g 4}}, :n 9, :d 3}, :b 2},
:10}
We have 25 students signed up for ClojureBridge London on 21/22nd February at Signal. If you are able to coach, please sign up and help us support the students as they learn. https://clojurebridgelondon.github.io/
We have confirmed 12 of the coaches that signed up for ClojureBridge London are coming still. So, ideally we need another 10 coaches confirmed.
We have confirmed 12 of the coaches that signed up for ClojureBridge London are coming still. So, ideally we need another 10 coaches confirmed.