This page is not created by, affiliated with, or supported by Slack Technologies, Inc.
2017-11-30
Channels
- # beginners (126)
- # boot (2)
- # cider (6)
- # cljs-dev (46)
- # cljsjs (8)
- # clojure (122)
- # clojure-greece (57)
- # clojure-italy (6)
- # clojure-poland (3)
- # clojure-russia (2)
- # clojure-serbia (5)
- # clojure-spec (26)
- # clojure-uk (99)
- # clojurescript (39)
- # cursive (15)
- # datascript (7)
- # datomic (21)
- # dirac (7)
- # duct (1)
- # emacs (19)
- # fulcro (58)
- # garden (4)
- # graphql (15)
- # hoplon (2)
- # immutant (1)
- # instaparse (3)
- # jobs (5)
- # juxt (15)
- # klipse (4)
- # leiningen (2)
- # lumo (52)
- # off-topic (8)
- # om (27)
- # onyx (22)
- # other-languages (3)
- # portkey (2)
- # protorepl (2)
- # re-frame (7)
- # reagent (7)
- # ring (11)
- # rum (7)
- # shadow-cljs (114)
- # spacemacs (20)
- # specter (16)
- # test-check (5)
- # timbre (1)
- # unrepl (43)
- # yada (17)
agreed, @noisesmith is one of the most helpful people here; we should start tipping him in micro bitcoins or something 🙂
Does anybody have any Emacs configs to expand upon this? http://fgiasson.com/blog/index.php/2016/06/14/my-optimal-gnu-emacs-settings-for-developing-clojure-revised/ I adopted this config when I started just under a year ago and I never thought about it since
I’ve switched to the zenburn
theme because I find it easier on my eyes than monokai
. I configured erc-mode
because the leiningen developers hang out on IRC, and I have a pull request pending there. I’ve recently adopted eshell
and added some config tweaks I needed, including a custom prompt for virtualenvwrapper
. Up until very recently I used exclusively melpa-stable, but then I released a (silly) elisp package called adafruit-wisdom
to melpa… As a result, I needed to figure out how to pin packages to a specific repository, that’s the stuff at the very top of my init.el
. Take a look, maybe some of this will appeal to you too. https://github.com/gonewest818/.emacs.d
@radomski you may take a look at my emacs config that I’ve been using for 5 years: https://github.com/igrishaev/dotfiles/blob/master/.emacs
1. I'm not using datomic. 2. I need to inspect a large eav store (about 10,000 items). 3. Anyone knows of a good tool for analyzing this?
if I restructure the ::delay to (s/def ::delay (s/and int? (s/or :val pos? :val zero?)))
(s/def ::delay (s/and (s/or :val pos? :val zero?) int?)) (s/valid? ::delay 0) => false (s/def ::delay (s/and int? (s/or :val pos? :val zero?))) (s/valid? ::delay 0) => true
you can use s/explain
in place of s/valid?
to get more information
I tried it here and it seems like the first option passes [:val 0]
to the int?
pred
so this is probably what's causing it to fail
Seems that's the case as (spec/def ::delay (spec/and (spec/or :val pos? :val zero?) #(int? (second %))))
works
https://clojuredocs.org/clojure.spec/or "Returns a destructuring spec that returns a map entry containing the key of the first matching pred and the corresponding value."
and that I don't know enough to say
I thought that the above would only be true when conforming, didn't realize it would have this kind of implication
btw @h.elmougy you can use pos-int?
as well
I think it makes sense. This way, you can check only specific keys in the following specs.
@p-himik that is true
I have something like this (reduce + (map #(* (first %) (last %)) …) that runs at 1500msecs. Then I tried it in a loop and it drops to 20msecs. Why does Rich hickey hate me so ?
In CLJS and items
being a vector, reduce
works about 8% faster than loop
:
(def items (mapv #(vector % %) (range 10000)))
(simple-benchmark [] (reduce + (map #(* (first %) (last %)) items)) 1000)
[], (reduce + (map (fn* [p1__115369#] (* (first p1__115369#) (last p1__115369#))) items)), 1000 runs, 4812 msecs
(simple-benchmark [] (loop [acc 0, items items] (if (seq items) (recur (let [i (first items)] (+ acc (* (first i) (last i)))) (rest items)) acc)) 1000)
[], (loop [acc 0 items items] (if (seq items) (recur (let [i (first items)] (+ acc (* (first i) (last i)))) (rest items)) acc)), 1000 runs, 5219 msecs
(simple-benchmark [] (reduce + (map #(* (first %) (peek %)) items)) 1000)
[], (reduce + (map (fn* [p1__118806#] (* (first p1__118806#) (peek p1__118806#))) items)), 1000 runs, 2304 msecs
Just a suggestion. Is it because map creates a new list, before reducing on it? I wonder how this would perform: (reduce #(+ (* (first %2) (last %2)) %1) 0 ....) Skipping the creation of the intermediate list.
@p-himik Use destructing instead of first/last. Last isn't all that fast and will create another intermediate sequence actually.
items are a two element vector so you can in this instance but certainly not in the general sense of last
@laujensen also make sure your first reduce isn't actually realizing the lazy seq vs your loop using the already realized one
there's just way too much you haven't said about this to make a guess, but there's absolutaly no way that a 1:1 translation from reduce to loop results in 2 factors of magnitude perf increase
hello everyone, im coding a scheduler which receives a function as a parameter, if the function execution raises an exception, id like to log the function name is there a standart way of getting a function name in clojure?
;; get name of the created class for foo
((fn [f]
(-> f
.getClass
.getName)) clojure.string/replace) => clojure.string$replace
It's a bit hacky.
And expensive I believe, because you do a reflection.
user> (bench ((fn [f]
(-> f
.getClass
.getName)) clojure.string/replace))
Evaluation count : 10640280 in 60 samples of 177338 calls.
Execution time mean : 5.649725 µs
Execution time std-deviation : 123.414594 ns
Execution time lower quantile : 5.453163 µs ( 2.5%)
Execution time upper quantile : 5.886103 µs (97.5%)
Overhead used : 8.291648 ns
Found 1 outliers in 60 samples (1.6667 %)
low-severe 1 (1.6667 %)
Variance from outliers : 9.4543 % Variance is slightly inflated by outliers
nil
5µs, depending on the use case, can be a long time, i agree
well, there's 2 instances of reflection in this code, one is avoidable and it's the slow reflection, the other is .getClass
itself which is fast
I'll do.
user> (bench ((fn [^Object f]
(-> f
.getClass
.getName)) clojure.string/replace))
Evaluation count : 5075442000 in 60 samples of 84590700 calls.
Execution time mean : 4.068115 ns
Execution time std-deviation : 0.410098 ns
Execution time lower quantile : 3.483281 ns ( 2.5%)
Execution time upper quantile : 4.942832 ns (97.5%)
Overhead used : 8.291648 ns
Found 2 outliers in 60 samples (3.3333 %)
low-severe 2 (3.3333 %)
Variance from outliers : 70.3505 % Variance is severely inflated by outliers
4ns? What happened? 😳
I have to read about this reflection thing. Thank you!
this is what in clojure we refer as reflection, but generally speaking my point was that in java lang, Object.getClass is technically reflection too
but when we talk about reflection in clojure, it's in the context of reflective calls at runtime which is a very narrow and specific instance of reflection
Do you have an example where you cannot avoid reflection?
Reflection in the wider sense.
if you want to do stuff like (deftype Foo [x]) (deftype Bar [x]) (defn foo [a] (.-x a))
then that needs to be reflective
@U060FKQPN this means i should typehint my parameteres when possible? only functions? is there a way in which I can clojure.spec
stuff and get type hints for free?
my suggestion is to (set! *warn-on-reflection* true)
in your project at dev time and just type hints the warnings away
there's no way to get type hints from clojure.spec, type hints are compile time and spec is runtime
addendum about warn-on-reflection - if you use lein, lein check
will show all your reflection warnings
(-> func var meta :name)
What do you use for data validation? Clojure spec looks great to generate and check data validation, but on the other hand it is totally not human readable. So using clojure spec i would have to validate twice, once with clojure spec and once for users with usability messages. It sound like something is wrong in this pattern. How do you do this? I would like to use clojure spec but something deep inside me saying i need complete solution to generate, validate, human readable information and spec doesn’t fit into this at that moment.
@kwladyka there are libraries for mapping from the spec errors to human readable messages, the intention for spec is to be easy to integrate with tooling for readability
@kwladyka We use just spec -- and then explain-data
for failures, and we map the data structure to our own custom error messages.
No, sorry. It's code at work.
has anyone written a let
style macro that puts the bindings at the end? I do like the haskell where
syntax whereby the local definitions can follow after usage
just for clarity of reading. For example you define a function and have a bunch of stuff in the let bindings and there's a lot of details immediately and then the implementation. The where
style let's you put some clear logic and then define the local bindings after their usage. A macro could simple rewrite this into a traditional let but i do like the usage first
https://github.com/hiredman/raft/blob/master/src/com/manigfeald/raft/rules.clj#L131-L145
@laujensen and example is the following:
levelorder :: (Ord a) => Tree a -> [a]
levelorder t = step [t]
where
step [] = []
step ts = concatMap elements ts ++ step (concatMap subtrees ts)
elements Nil = []
elements (Node left x right) = [x]
subtrees Nil = []
subtrees (Node left x right) = [left,right]
with good naming it can make the logic really clear and push the details down below but still close if you are interested
it has these things I called "rules" that have three parts, a true/false expression that determines if the body should be applied, a body that updates the passed in state, and then bindings (usually a big destructuring) that establish any bindings for the first two parts
in clojure, the let puts all of the stuff above. i can see both having their benefits but sometimes just want to see a nice clear logic
@dpsutton I think Ive done too much Clojure and too little Haskell to find that order help. Looks upside down to me 🙂
one thing with the let ordering is that it's the same dependency order as defn/def ordering, so there's some consistency here. also with imperative language statement ordering
yeah i'm thinking some syntax like
(with-delayed-context
(-> (sanitize-data data)
(filter incomplete?)
(map complete-names))
(with-bindings [sanitize-data (fn [data] ...)
incomplete? (fn [item] (and ...))
complete-names (fn [item] (or ...))]))
but you lose the implicit do i believe. that's why i was thinking a keyword to signal the end of the body
so keep taking forms as the body until you see the with-bindings
or where
and then invert
(defmacro where
[& body-and-bindings]
`(let ~(last body-and-bindings)
~@(butlast body-and-bindings)))
user=> (where (+ x y) [y 1 x (inc y)])
3
?could anyone shed some light on why this doesn't work?
(mapcat :id
[[{:id 1} {:id 2}]
[{:id 3} {:id 4}]])
@tmountain [{:a 0}]
doesn’t have an :a key
it’s a vector containing an item with an :a key
mapcat unfolds after, not before, the input list
you could do (map :id (apply concat coll))
instead
or (into [] (comp cat (map :id)) coll)