This page is not created by, affiliated with, or supported by Slack Technologies, Inc.
2019-04-11
Channels
- # announcements (14)
- # beginners (119)
- # boot (9)
- # calva (7)
- # cider (12)
- # cljdoc (2)
- # cljsrn (28)
- # clojure (127)
- # clojure-dev (2)
- # clojure-europe (3)
- # clojure-italy (2)
- # clojure-losangeles (9)
- # clojure-nl (6)
- # clojure-spec (15)
- # clojure-uk (39)
- # clojurescript (35)
- # community-development (4)
- # cursive (9)
- # datascript (8)
- # datomic (5)
- # duct (3)
- # emacs (10)
- # fulcro (45)
- # graphql (3)
- # jobs (1)
- # kaocha (8)
- # luminus (2)
- # off-topic (121)
- # onyx (3)
- # pathom (15)
- # pedestal (31)
- # planck (5)
- # reagent (25)
- # reitit (3)
- # remote-jobs (1)
- # shadow-cljs (48)
- # slack-help (1)
- # sql (142)
- # tools-deps (78)
Is it possible to get ParEdit working in the Clojure REPL (the one invoked with lein repl
)?
@aryyya.xyz Which editor are you using? I can turn on paredit-mode in the REPL in Emacs.
Oh, okay. Without an editor wrapping the terminal/repl, then I don't know the answer.
@rob704 I’ve also got it working in the CIDER REPL with ParEdit in Emacs, but I’m trying to transition away from Emacs in favor of VS Code, which I run a regular terminal inside of with the REPL. I’ve got pretty much everything working for my own workflow as it would be in Emacs with CIDER, but I can’t figure out this one minor thing.
@aryyya.xyz I wanted to try that too (VS Code). Do you have key combos to quickly eval/reload things in the REPL, without having to cut-n-paste? In Emacs, commands like cider-eval-defun-at-point
, cider-eval-sexp-at-point
, cider-load-buffer
.
@aryyya.xyz I think rebel-readline does paredit.
I have a little golfing challenge if anyone's feeling bored on a Thursday afternoon: https://gist.github.com/clarkema/61464cb52ba107047c28cdff0539d030
loop should be fastest
you're ruining it with the boxed constant prob
(time (loop [i 1]
(inc i)
(if (< i 100000000)
(recur (inc i)))))
is like 45ms
alternately, this should have similar effect:
(def ^long ^:const up-to 100000000)
might help the other timings too
and actually the inc i would be even faster if using unchecked math. you can turn that on as the default AND get warnings about boxed usage like this:
user=> (set! *unchecked-math* :warn-on-boxed)
:warn-on-boxed
user=> (time (loop [i 1]
(inc i)
(if (< i up-to)
(recur (inc i)))))
Boxed math warning, NO_SOURCE_PATH:3:13 - call: public static boolean (long,java.lang.Object).
@alexmiller That's really interesting, thanks!
with unchecked math and avoiding boxing, more like 32 ms
should basically be emitted as essentially the same bytecode you'd get from a tight java numeric loop on a long counter (although more natural in Java to use ints)
I'll have a go with that in the real example (up-to in real life is actually the result of .size on a java.util.ArrayList
you can type-hint it or coerce it at point-of-use too - result of .size is an int, and a coercion to primitive long will be required somewhere. best to do it explicitly once, then every time through the loop if possible.
I need to add a content-type/application-json header to a luminus swagger endpoint that looks like
["/json" {:get (constantly (ok (json/write-str {:foo "bar"})))}]
any thoughts?I'm getting
"content-type": "application/octet-stream",
instead.the new luminus/swagger uses reitit so I think things may be different than before.
can you call defmacro within defmacro?
do you mean emit or call?
defmacro-emitting macros are definitely possible and useful. also quite painful to write.
@macrobartfast if you have a content-negotiation middleware in the mw chain, it should do the formatting for you, there is a example here: https://github.com/metosin/reitit/blob/master/examples/ring-spec-swagger/src/example/server.clj#L82
still looking for more experience reports feedback on the Clojure 1.10.1-beta2 changes in error reporting if anyone has the opportunity to live with it for a bit. See https://www.reddit.com/r/Clojure/comments/bc264v/clojure_1101beta2_is_now_available/ekn9qr3/ for an example.
I just updated our code base to use Beta 2 and all tests pass (of course) -- the next failure that I hit will make me appreciate CLJ-2497 being fixed 🙂
Anyone fancy a 4clojure type exercise? A function that takes a vector and an item in that vector and shifts the item right or left by one.
Yep, distinct
(shift :left 1 [1 2 3 4 5])
-> [5 2 3 4 1]
(shift :left 3 [1 2 3 4 5])
-> [1 3 2 4 5]
cycle, drop x, take n handles that (computing x appropriately for right/left)
(defn shift [direction i coll]
(let [[before [_ & after]] (split-with #(not= i %) coll)]
(if (= direction :left)
(if (butlast before)
(vec (concat (butlast before) [i] (take-last 1 before) after))
(vec (concat (take-last 1 before) after [i])))
(if (empty? (rest after))
(vec (flatten (concat [i] before)))
(vec (flatten (concat before [(first after)] [i] [(rest after)])))))))
Pretty ugly but it worksCan tidy it up a bit
if this was 4clojure I would make [[1] [2] [3]] an input (to rule out using flatten)
I think it still works, because i flatten after splitting
it would return the wrong output
Flatten just lets me make everything a seq so that concat doesnt blow up
there are solutions that don't force you to destroy the structure of your input
You're right, it breaks when using flatten
i.e. :right
I'm sure there are, what i have is very inelegant
I'd get rid of :right / :left and use +/- in index
is i an index? or is that a value to match?
I guess value, so nvm. I totally misunderstood (twice now) what this is doing. :)
Yes, bad naming, sorry
x
would be more idiomatic?
well, i
was confusing :)
el
elt
or needle
might be good
I'll have to try again tomorrow, brain is tired. :sleeping_accommodation:
Can I use a bit of java interop?
(defn shift [direction item coll]
(let [f (case direction :left dec :right inc)
pos (.indexOf coll item)]
(when (not (neg-int? pos))
(let [target-pos (mod (f pos) (count coll))
overlay {target-pos item, pos (nth coll target-pos)}]
(reduce (fn [coll [position new-value]] (assoc coll position new-value)) coll overlay)))))
Sure, I asked in the #clojure channel after all. Too bad i'm wanting it for clojurescript, oops :man-facepalming:
Looks like it can translate fairly easily
(.indexOf (make-array coll) item)
🙂
@mattmorten doesn't that when ensure that you return nil if you step past the index the item isn't found?
It does
I wasn't sure what the requirement was for that
¯\(ツ)/¯
:else
is traditional
all keywords are logically true
oh! today I learned
I just kinda assumed :else
was something cond
understood
but … ofcourse not
so you could also just say :catch-all
if you wanted :)
on occasion, I add a bit of whimsy
there are linters that accept :else but not :otherwise
always make code the least surprising right 🙂
user=> (cond-> 1
:please inc
:don't inc
:do inc
:this inc)
5
user=>
(runs away)Even apostrophes in keywords, you madman
:<><
🙂
user=> :<>:<>:<>
:<>:<>:<>
user=>
(I was a bit surprised multiple :
were accepted!)"A symbol can contain one or more non-repeating ':'s" and "Keywords are like symbols"
that said, I wouldn't recommend it :)
Ah, thank you. I'm sometimes not quite sure whether something is intentionally accepted (and documented) or not when it comes to literal keywords 🙂
(and UTF-8 just adds a whole newer layer of fun on top of all this!)
user=> (let [💩 42] (* 💩 💩))
1764
Well that makes more sense in non Latin scripts ^^. I kinda wonder whether there are many people using bindings with non-Latin names
I forgot what the -> does
->
is "thread first" so it threads the value (initially 1
) into each of the expressions for which the test expression is truthy.
So it ends up being (-> 1 inc inc inc inc)
(because all those keywords are truthy) which is (inc (inc (inc (inc 1))))
although that page probably needs some better examples
Yeah, especially around the use of as->
since it doesn't show it nested inside ->
😞
(-> 42 inc (as-> x (* x x)) dec)
is there any way to combine regexes, other than combining strings and then using re-pattern?
I already have regexes and i need to concatenate them to find a larger pattern
@ackerleytng this is the full API - I think making strings, combining, then making a new pattern is the most direct thing https://docs.oracle.com/javase/7/docs/api/java/util/regex/Pattern.html
I have a curious situation where attempting to evaluate any expressions (even something as simple as 1
) inside of a Clojail sandbox on an app running inside a Docker container trips an exception:
Exception in thread "async-dispatch-8" java.security.AccessControlException: access denied ("java.io.FilePermission" "/var/log/yetibot/yetibot.log" "read")
the app is completely crippled after this point (any sort of IO will fail), even outside of the sandbox.
this only happens when running the Docker container on Digital Ocean.
I run the same image on an internal VM at work and it works fine. it also works locally (outside of Docker).
ideas? :thinking_face:code is really basic https://github.com/yetibot/yetibot/blob/b71d354d6868942bb860b3e6772a18601daf39d9/src/yetibot/commands/clojure.clj#L15-L16
I assume it is tripping up trying to write the log file...?
(although it says "read")
i also put a very permissive java policy file inside the docker image. i don't know much about java policy though.
this is what it looks like when attempting to make an http request after it's been crippled:
java.security.AccessControlException: access denied ("java.net.NetPermission" "getProxySelector")
at java.base/java.security.AccessControlContext.checkPermission(AccessControlContext.java:472)
at java.base/java.security.AccessController.checkPermission(AccessController.java:895)
at java.base/java.lang.SecurityManager.checkPermission(SecurityManager.java:322)
at java.base/java.net.ProxySelector.getDefault(ProxySelector.java:96)
at clj_http.core$get_route_planner.invokeStatic(core.clj:227)
the very mysterious part is why the same docker image works on one VM but not on a DigitalOcean VM.
I'd be tempted to follow a Digital Ocean support path at that point I think... ¯\(ツ)/¯