This page is not created by, affiliated with, or supported by Slack Technologies, Inc.
2017-07-27
Channels
- # aleph (3)
- # beginners (89)
- # boot (198)
- # cbus (4)
- # cider (11)
- # clara (2)
- # cljs-dev (27)
- # cljsrn (4)
- # clojure (141)
- # clojure-austin (4)
- # clojure-italy (11)
- # clojure-nl (1)
- # clojure-poland (2)
- # clojure-russia (35)
- # clojure-spec (33)
- # clojure-uk (55)
- # clojurescript (111)
- # core-logic (15)
- # cursive (2)
- # datascript (47)
- # datomic (132)
- # emacs (4)
- # jobs (1)
- # lein-figwheel (13)
- # leiningen (15)
- # lumo (20)
- # off-topic (110)
- # om (8)
- # onyx (20)
- # parinfer (2)
- # protorepl (1)
- # re-frame (36)
- # reagent (5)
- # remote-jobs (1)
- # ring (2)
- # ring-swagger (5)
- # specter (6)
- # uncomplicate (3)
- # unrepl (77)
I know this is a clojure channel but maybe someone will know the answer. I'm trying to ssh into a server, run a shell script, and the disconnect from the server and have the script continue to run
tmux or screen
Hello! I am reading clojure.core’s source cdoe and the beginning confuses me. Could someone explain this out?
;during bootstrap we don't have destructuring let, loop or fn, will redefine later
(def
^{:macro true
:added "1.0"}
let (fn* let [&form &env & decl] (cons 'let* decl)))
fn*
is a compiler internal thing: https://github.com/clojure/clojure/blob/master/src/jvm/clojure/lang/Compiler.java#L47
@U61HA86AG what is the difference with fn
? Also, why is let
defined as a macro? I thought it was a special form
fn
is defined in clojure, and just calls out to fn*
: https://github.com/clojure/clojure/blob/master/src/clj/clojure/core.clj#L42
@U61HA86AG ah, I see. So special forms are always followed by a *
, but for easy of use there is a non-starred version
and the non-starred version is more than just convenience, it also lets you do e.g. (doc let)
@U61HA86AG when I do (doc let)
it says let
is a special form, but in reality it’s a macro which expands to a special form. I assume there is some magic going on here; where is it?
@U61HA86AG why is it defined first here https://github.com/clojure/clojure/blob/master/src/clj/clojure/core.clj#L32 then here https://github.com/clojure/clojure/blob/master/src/clj/clojure/core.clj#L4439 ?
well if you look here https://github.com/clojure/clojure/blob/master/src/clj/clojure/core.clj#L193 it uses let
, but defmacro
hasn't been defined yet
yeah, so the first let only has the functionality needed to bootstrap the rest of clojure, and then later on it gets the rest of its functionality via defmacro
thanks for explaining this out @U61HA86AG 🙂
Is there a std lib function to pick a number of keys out of a map? e.g. Map -> [Key] -> Map
@bronsa thanks! I really miss a Hoogle-like tool for Clojure 😞 https://www.haskell.org/hoogle/
@henrik can it be that you are not on the latest version? it is fixed in v0.22.4 https://github.com/atom/language-clojure/commit/70e83b27444da31d6367a0aa447a216836eafc05
I'm trying to use transducers... The original code:
(->> m
(map :my-key)
(map #(clojure.edn/read-string %)) )
translating to transducers:
(let [xf (comp (map :my-key)
(map #(clojure.edn/read-string %))))]
(transduce xf concat m)
This gives a stackoverflow error...oh wait... it's not the same.
concat gives that stackoverflowerror...
@kurt-o-sys (into [] xf m)
right, thx.
funny... I read that last week. stupid me 😛
well, actually it's (flatten (into [] xf m)
I was after.
@kurt-o-sys or second map
should be mapcat
🙂
nice.
is there something builtin or better for this?
(defn least-common-ancestor [path1 path2]
(let [i (min (count path1) (count path2))]
(reduce
(fn [p idx]
(let [v1 (nth path1 idx)
v2 (nth path2 idx)]
(if (= v1 v2)
(conj p v1)
(reduced p))))
[], (range i))))
(least-common-ancestor
[:a :b :c]
[:a :b :d])
=> [:a :b]
This one has much better runtime performance, mostly stemming from the omission of nth
Well you could avoid one nth
call here if you use reduce-kv
and you can guarantee it's a vec
And if you want to avoid the intermediate sequence: (sequence (comp (map #(when (= %1 %2) %1) ) (take-while some?)) [0 1 2] [0 1 3])
@rauh on such small inputs it is not worth it:
(time (dotimes [n 1000] (take-while some? (map (fn [a b] (when (= a b) a)) [0 1 2] [0 1 3]))))
"Elapsed time: 1.166446 msecs"
(time (dotimes [n 1000] (sequence (comp (map #(when (= %1 %2) %1) ) (take-while some?)) [0 1 2] [0 1 3])))
"Elapsed time: 7.258858 msecs"
if you want to measure calculation time (or run for side effects) and don’t need the result, use dorun instead of doall
also, sequence is not typically more efficient than regular lazy ops in most cases iirc
So this is fun: when using postwalk, map entries are just vectors (so map-entry? returns false), so there is no way to distinguish a map entry from a map value that is a vector… Anyone else run into this?
I suppose a map key could also be a vector, which adds a 3rd case of ambiguity
@cpmcdaniel It's a known issue in JIRA...
@seancorfield say no more, and thank you
(go vote for it!)
ah, prewalk works for my use case
(and I voted)
if I am implementing something that is meant to be used in place of a function, is it enough to implement IFn or should I implement AFn too?
it sort of depends on how you are implementing it, AFn is an abstract class so dealing with it from clojure is kind of a pain, but from java that is where I would start
OK - this is clojure code, so I hope I’m safe ignoring AFn
I often will implement IFn and just particular invoke arity that I expect to be used
I think apply won't work, and you will get some weird brokeness with more than 20 args, and maybe fn? will return false
yeah - this is a macro implementing generally something you recommended earlier (making a record that can be called like a function but unlike a lexical closure you can also look at the data in its keys) - trying to make it a convenient to use replacement for code that uses partials extensively
I just verified I implemented things properly to make apply work for over 20 args
but returning false for fn? is acceptable
instance? clojure.lang.Fn
easy enough to extend that, it has no methods
sweet!
thanks - I think this will be a handy little one macro lib, just need a snappy marketable name
@noisesmith big note: you probably want ifn? if you want to check if something is a function. fn? does something different (and is normally wrong, imo).
@tbaldridge so if I am making something that is a drop in replacement for a function returned from partial, would it be a bad idea to make fn? return true from someone else’s check?
I guess that’s a style issue
nah, just code against IFn, and then ifn?
will return true, which is what most people should be using
:thumbsup:
@tbaldridge on thing though, in my code, checking ifn? would lead to surprising results here
=> (ifn? :hi)
true
that could be a sign of doing other things wrong I guess…
(What @ghadi said)
yeah fn? really means "something that was created with (fn ...)
"
yeah, I guess the answer of (defmulti foo first)
(fn? foo)
can be a guide there
-----------------------------------------------
Sooooooooo who here has played with tools.deps.alpha
and what do they think?
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
but i don't know how to crank it up since it's based on the pom file rather than a project file
it also specifies its own deps in the new edn format. does that make it "self-hosted"?
@dpsutton if you have mvn
installed you can crank it up using the commands in the README. Use of mvn/pom is a one-time thing at setup. (It will probably be handled by the package manager when this stuff filters over there)
yeah i wanted to play with it and do a PR for
;; TODO - choose better
(defn- choose-coord
[coord1 coord2]
(if coord1
(if coord2
(let [v1 (:version coord1)
v2 (:version coord2)]
(if (pos? (compare (str v1) (str v2)))
coord1
coord2))
coord1)
coord2))
once you have it installed, you can use it in a project folder (using $PWD/deps.edn
) or globally (using $HOME/.clojure/deps.edn
)
but let alex and others figure out the hard stuff and I could help out with the easy solved stuff
I would like to write a function (if possible with the stdlib) to check if a map “matches” a pattern. More specifically, I would like to describe a map in terms of another map with the same structure, whose values can either be ints/bools/strings or regexs. If the value are ints/bools/strings they they should be compared for equality with the target map, and if they are regexs they should match
https://maven.apache.org/resolver/apidocs/org/eclipse/aether/util/version/GenericVersionScheme.html
you can't override the broken spec.alpha reference from 0.1.94 to 0.1.123 right now, because the comparator is busted
e.g.
{:first-name "john"
:last-name #".*"}
should match
{:first-name "john"
:last-name "doe"}
you could just take two maps, the first being the shape and the second being the data and recurse through them
@hiredman that’s precisely what I’m wondering how to do. Is there an easy way to express this recursion procss with stdlib functions?
you can take the description map and turn it to into a sequence of paths and predicates and reduce over that with the data
ah, found an example. http://blog.jayfields.com/2010/09/clojure-flatten-keys.html
(defn f [m1 m2]
(letfn [(g [p m]
(if (map? m)
(for [[k v] m
i (g (conj p k) v)]
i)
[[p m]]))]
(reduce
(fn [x [path predicate]]
(and x (predicate (get-in m2 path))))
true
(g [] m1))))
that assumes the description map is a map of keys to predicates, so you will have to change it to do your regex and = compares instead
I was thinking of writing my tests in a descriptive form as EDN, using tags for different types of predicates
Is there a protocol I can implement to get peek/pop/conj to work on a queue like datastructure I'm building?