This page is not created by, affiliated with, or supported by Slack Technologies, Inc.
2018-03-22
Channels
- # beginners (240)
- # boot (23)
- # bristol-clojurians (3)
- # cider (101)
- # cljs-dev (52)
- # cljsrn (17)
- # clojure (212)
- # clojure-dusseldorf (2)
- # clojure-greece (2)
- # clojure-italy (9)
- # clojure-russia (1)
- # clojure-spec (91)
- # clojure-uk (33)
- # clojurescript (164)
- # community-development (23)
- # core-async (24)
- # core-logic (9)
- # cursive (18)
- # datavis (1)
- # datomic (119)
- # emacs (13)
- # events (1)
- # figwheel (2)
- # fulcro (86)
- # graphql (1)
- # immutant (5)
- # jobs-discuss (6)
- # leiningen (19)
- # lumo (46)
- # nyc (7)
- # off-topic (23)
- # parinfer (15)
- # pedestal (3)
- # planck (32)
- # re-frame (48)
- # reagent (75)
- # ring-swagger (13)
- # rum (32)
- # shadow-cljs (402)
- # spacemacs (5)
- # specter (3)
- # tools-deps (11)
- # unrepl (20)
- # vim (135)
- # yada (3)
@rickmoynihan it does indeed
they definitely share some goals
@devicesfor -O
is for aliases in your deps.edn
. You want the -J
option to pass JVM options on the command line.
clj -J"--add-modules java.xml.bind"
is probably what you wantHmm, no... spaces are problematic...
clj -J--add-modules --Jjava.xml.bind
might work (I don't have Java 9 locally so I can't test that)@seancorfield so -O is to activate jvm options that are in deps.edn ?
clj --help
is your friend š-O
is an alias selector, so if you have {:aliases {:foo {:jvm-opts [...]}}}
then -O:foo
will bring in those JVM options...
you know how do I see the complete stack trace at the repl ? I'm doing (.printStackTrace *e) but I get '... 43 more' at the end
Just *e
should show the whole thing as data?
Or maybe look at the clojure.stacktrace
namespace?
do *.cljc files have file size limits? I'm doing something of the form (def my-static-data (read-at-compile-time "some-file")) where read-at-compile-time is a macro that reads at compile time
I am trying to design an API wrapper for a Java library . There are many functions like draw-rectangle, draw-circle in the Java lib with different parameters for my clojure library to wrap around. Should I use multimethods with :type
and take in a large map or make separate functions like draw-circle, draw-rectangle and so on? Is there a guide or any other repos I can look for API design inspiration like Python requests?
@xtreak29 Another solution would be to use a protocol like IRender.. (render [shape] ā¦) and have a render function that is full filled by different implementations for rectangle & circles. But then it depends on what you want to do with you API wrapper. Be true to the Java lib and not introduce indirections to the lib user or present a ācleanā API for the Clojure developer with more things behind the curtain. Not sure I have a suggestion of a reference implementation.
Thanks. I am wrapping around https://github.com/kennycason/kumo and my initial implementation is at https://github.com/tirkarthi/clj-wordcloud/blob/master/src/clj_wordcloud/core.clj#L28
Iām trying to build a web app in vase/pedestal, getting a little stuck on user authentication/authorization. Is there an example of a pedestal app that handles user auth? If not, whatās the best currently library for user auth in web apps?
There is an example in the friend-sample branch but it's around 5 years old : https://github.com/pedestal/samples/blob/friend-sample/friend-auth/src/friend_auth/service.clj Friend and buddy are the recommended ways to do auth in Clojure Friend : https://github.com/cemerick/friend, https://github.com/cemerick/friend-demo Buddy : https://github.com/funcool/buddy-auth
Got this from this issue : https://github.com/pedestal/samples/issues/27
do I have to release all my Clojure code under the Eclipse Public License? can't I do it under, let's say, MIT?
You can choose any license AFAIK. I have my projects released under MIT and know many popular ones that use MIT
https://www.reddit.com/r/Clojure/comments/3rlxlp/clojure_and_clojurescript_licenses/ I don't know, I'm confused :(
https://softwareengineering.stackexchange.com/questions/210043/is-clojure-development-required-to-be-open-source this helped. thanks
TIL, Thanks for the links :thumbsup: . Ring is a very popular library and it's MIT licensed : https://github.com/ring-clojure/ring/blob/master/LICENSE
https://www.reddit.com/r/Clojure/comments/3rlxlp/clojure_and_clojurescript_licenses/ I don't know, I'm confused :(
is there a way to turn off all the output that is sent to nrepl? Every message i get over a websocket is going there, and I wonder if all that logging is creating some big latency I'm seeing. I'd like to turn off what nrepl prints
Is there any way to get the depth of the tree when using clojure.walk/postwalk?
or a similar tree walking function
depth inside a zipper would also work
Doesn't recommend Zippers. Might be helpful : https://stackoverflow.com/questions/31265409/calculating-the-depth-of-a-tree-data-structure-clojure
The implementation of postwalk is pretty short, you could copy 'n paste that and add the depth as a argument to the walker fn: https://github.com/clojure/clojure/blob/master/src/clj/clojure/walk.clj#L58
(defn depth
"Calculate how far we are inside the zipper, by ascending straight up
until we can't get any higher."
;; There is probably a smarter way to do
;; this than checking for nil, but I'm not sure what it is.
[loc]
(loop [loc loc
depth -1]
(if (nil? loc)
depth
(recur (z/up loc) (inc depth)))))
zippers are ideally what I'd work with, but I like your idea too @pesterhazy
@pesterhazy might be a lack of imagination on my part, but how would you get hold of the depth there?
@danielcompton hm not sure. The clojurew.walk code is very compact...
clojure.spec.test.alpha/check sometimes very slow, 30 tests take almost forever while 10 tests run very fast. I bind recursion-limit to 1 while still not helping.
@renewdoit can you share an example?
@danielcompton it contains lots of multi-spec and has recursive structure
@danielcompton it is slow when in cider, and runs fine in console, maybe I should check the cider environment.
I googled for this error message clojure.lang.ExceptionInfo [m: reader-error does not exist [m
but I canāt find anything useful.
If I create a file resources/jetty-logging.properties
in my project directory, and ensure that project.clj
has this line: :resource-paths ["resources"]
(I also tried with the trailing slash, :resource-paths ["resources/"]
), then when I restart the repl/CIDER, that properties file should be read by JVM, right?
Where does the "lazy" in LazilyPersistentVector come from? It always returns an instance of PersistentVector, and I was under the impression vectors were non-lazy.
hi, is this some config stuff or it is not possible to lein uberjar
code that has (defn b [] (a)) (defn a [] 1)
defined in this order?
you need to (declare a)
before using it
nothing to do with uberjar ā same in the repl
right, that's a common gotcha
I like that about clojure actually. Also makes the compiler fast
@pesterhazy do you then use something like jslint or whatever to at least let the editor catch these kind of things?
@tomaas, you could try https://github.com/candid82/joker
This is a fantastic reading: https://gist.github.com/jumarko/d672dbe746b3c10ee2690b2e17624de3 There are probably many things that I don't understand, but to mention one: > protocols support direct implementation composition, which, in my opinion, is far preferable to inheritance I'm not sure what exactly "protocols support directly implementation composition" really means here. Can anyone elaborate on that a bit more?
Wow, it *is* a fantastic reading š®
Looks like a good thing to add to this repository: https://github.com/matthiasn/talk-transcripts -- I can do that if you do not mind (happy to attribute who ever typed in the transcript, if you know who that was)
@U0CMVHBL2 that would be great. I don't really know who did that. I've found the original gist on Google: https://gist.github.com/harfangk/f98e627f7567b7b5741fe0c239b57d6c
@jumar it means that given a protocol IFoo you can extend it to any type, new or previously existing. Unlike interfaces which require you to inherit from the interface at compile time. So assume I have ICounted as a protocol, I can just easily add it to a new type as I can to go and do this
(extend-protocol ICounted
String
(count [this]
(.getLength this)))
String is a built-in type that I can't modify, but protocols allow me to extend the protocol to this type. This really helps with things like the "expression problem"
Good overview of that here: https://eli.thegreenplace.net/2016/the-expression-problem-and-its-solutions
Ah, okay, so the "composition" here means adding new capability to the existing data type. I was thinking about extend-protocol
as related to the first Rich's claim, that is "Protocols support direct connections of datatypes to protocols, without any inheritance" and was somewhat puzzled by the "implementation composition" words.
@tomaas Rich Hickey gives a nice explanation here, regarding single pass compilation and the nature of compilation units: https://news.ycombinator.com/item?id=2467809
(my thing is also blocked by https://dev.clojure.org/jira/browse/CLJ-2284, but thats neither here nor there)
@devicesfor The log display site is/was broken and not showing anything past November last year -- the logbot is working so messages are still being archived, and there's a new website coming to display those archives.
@seancorfield what log display site are you referring to?
@devicesfor The one Matt Grimm linked you to.
Ah, looks like Arne has already got the updated app up and running there now!
I wish there was a way to make this work without macros
(def expected-keys [:title :content
:id :icon :widget-class :init-collapsed?
:configuration :dropdown :controls :tabs :collapse-opts
:help])
(let [{:keys expected-keys opts] ...)
so have the keys in a tangible data structure that you can pass around and being able to destructure on it
@devicesfor Only channels where @logbot has been invited in get logged -- and the latest messages are from earlier today, as far as I can see.
@borkdude You can do the reverse tho' -- given a keys
spec, you can call s/form
on it and parse out the keys.
That way the spec is the "system of record" and you can derive all sorts of things from it.
It's what we do at work -- we have specs for several entities (that relate to tables in our database) and we derive the set of keys from those specs so that we can ensure we don't try to insert columns that don't exist.
https://clojure.github.io/spec.alpha/clojure.spec.alpha-api.html#clojure.spec.alpha/form
user=> (s/def ::table (s/keys :req [::id ::name ::description]))
:user/table
user=> (s/form ::table)
(clojure.spec.alpha/keys :req [:user/id :user/name :user/description])
user=> (let [[_ & {:keys [req]}] (s/form ::table)] req)
[:user/id :user/name :user/description]
user=>
Ah, and then you want to use that list of keys in a destructuring expression?
@borkdude Some macro magic:
user=> (s/def ::table (s/keys :req [::id ::name ::description]))
:user/table
user=> (s/form ::table)
(clojure.spec.alpha/keys :req [:user/id :user/name :user/description])
user=> (let [[_ & {:keys [req]}] (s/form ::table)] `(let [{:keys ~req} {::id 1 ::name "borkdude" ::description "Someone who wants to destructure spec keys"}] (println ~'id ~'name ~'description)))
(clojure.core/let [{:keys [:user/id :user/name :user/description]} #:user{:description "Someone who wants to destructure spec keys", :name "borkdude", :id 1}] (clojure.core/println id name description))
user=> (eval *1)
1 borkdude Someone who wants to destructure spec keys
nil
user=>
refactor that into a macro and you should be good to go! š
so, the lazy-seq
docstring says
> Takes a body of expressions that returns an ISeq or nil
but it seems like it is working with any collection-producing code Iām throwing at it--what am I missing here? Reading the code was not super illuminating, it looks like maybe itās wrapping the passed-in forms up in an anonymous function call, although Iām a bit fuzzy on how to parse it with all the syntax quoting:
https://github.com/clojure/clojure/blob/841fa60b41bc74367fb16ec65d025ea5bde7a617/src/clj/clojure/core.clj#L675
you can give it anything that you can call seq
on, like a vector. Internally LazySeq will call seq
.
okay, so the docstring is wrong, or am I misunderstanding what the docstring is saying?
if you give it (blah)
, it will take your (blah)
and wrap it in a "thunk" (fn [] (blah))
then call the LazySeq constructor on it (LazySeq. (fn [] (blah)))
Now the first time something calls seq
on this lazy-seq (usually indirectly, like map
), internally LazySeq will invoke the thunk, then call RT.seq() on the result of that
okay, that much makes sense, and is roughly what I was assuming
but itās not explaining the bit of the docstring I highlighted
okay, thatās not super satisfying, but Iām probably not explaining my confusion well enough. Let me try a repl code example:
user=> (doc seq?)
-------------------------
clojure.core/seq?
([x])
Return true if x implements ISeq
nil
user=> (seq? (reduce #(conj %1 %2) [] [1,2,3]))
false
user=> (lazy-seq (reduce #(conj %1 %2) [] [1,2,3]))
(1 2 3)
user=>
again, that chunk of docstring that is confusing me: > Takes a body of expressions that returns an ISeq or nil
what am I thinking about incorrectly here?
https://clojurians.slack.com/archives/C03S1KBA2/p1521749732000297
a vector is not a seq?
but you can call seq on it
okay, so, the docstring is wrong?
in what sense am I returning an ISeq in my reduce example?
or even, āa body of expressions that returns an ISeq?ā if that distinction matters
Iām not sure, because all I am now is thoroughly confused--Iām not sure what youāre trying to say, and Iām not sure what the docstring is telling me either. I suspect--I hope!--there is something wrong with my understanding, but nothing youāve stated so far is pointing out what it is exactly that Iām confused or wrong about, as far as I have been able to tell.
I appreciate you trying, donāt get me wrong.
a vector is just data, how does it produce a seq?
and all of that aside, why does my reduce
example work?
I donāt see how seq
is involved there, in terms of the code Iām passing in
A sequence is an abstraction which many of our functions call into. Many collections implement the seq interface. You can implement a function that works on a seq and if it is given a collection that implements that interface, it'll be able to operate over it.
wow, this is a lot of talking past each other
Iām not sure how I could be more clear than the code example I posted above, but let me know if thereās something else I could provide to make it clear what Iām confused by. Thanks everyone for trying to help, I appreciate it nonetheless
which example @ddellacosta?
a seqable collection can sort of be turned into a seq, by calling seq on it, such that afterward, calling seq?
on it becomes true.
SO the docstring is in fact--letās be gentle here--imprecise
@dpsutton thank you
i don't think this was an attack on the docstring. everyone knows words are hard and the seq sequence stuff gets complicated. this was just "is there more here?"
and for the record, per https://clojurians.slack.com/archives/C03S1KBA2/p1521750114000771
I think it could be easily improved by defining the exact types it takes and returns
(now that I know what the problem is)
huh, canāt find that function
> "Takes a body of expressions that can produce a seq or nil" You're not going to want to enumerate all the specific types
I mean, I would, I guess Iām in the minority here though
maybe using a specific interface then is inappropriate if we can't enumerate them all?
whoops, just realized I read this backwards, sorry if my response didnāt make sense
that would be nice. Something likeā¦`ISeq` š
I dunno, this is my usual Clojure experience frankly so Iāll stop thereā¦I recognize Iāve got a different perspective than most Clojure devs
anyways, thanks again for the help, sorry for any confusion I caused
"Lazy sequences can be created with the lazy-seq macro, which takes a body that yields a seq, nil, or anything seqable."
although a vector doesn't implement ISeq itself, it is still "seqable" because you can call seq on it and get back a seq
@ddellacosta I find the point you're bringing up to be quite interesting actually
@john do tell
Well, a lot of us have a bias. And when someone comes in with new-comer complaints, some are valid and some aren't. Like @ghadi said, we may have stockholm syndrome. I just find it interesting what kinds of improvements might be shadowed by our biases, etc.
FWIW Iāve been writing Clojure professionally since, I think it was 2013 when I got my first Clojure job? I forget
but your frustration was one that we've all felt at a certain point, when dealing with seqs
I mean, thatās beside the point I think
Generally in the core library, anything that can take a seq can also take things that you can coerce to a seq
yeah I mean, to be clear I was trying to dig into what exactly the docstring was trying to tell me. It gave a pretty precise definition but it was not one that seemed consistent with how the function was behaving
thatās all I was getting at
sorry, joining this late and didnāt read all the backchat. I would actually say that sequence functions in the core library generally take seqables (and seqs are a degenerate seqable)
I think @markwās comment above was helpful
@alexmiller thanks, yeah, makes sense
generally the sequence functions should also be considered to also return something seqable (not a seq)
itās obscure why this is, but effectively there are some cases where we can avoid forcing a seq that way which actually makes a difference from a performance perspective
also note that seqable?
was just added in Clojure 1.9
ah, yeah, my current repl is 1.8
that sounds like an important and useful function to have
also, @alexmiller it doesnāt seem like seqable
is defined precisely anywhere on the main doc site--is this deliberate?
I donāt think so, more likely just reflects evolving thinking about the nuances of this stuff over time and docs not keeping up
gotcha. Thatās also helpful, thanks
it was added to make specāing sequence functions practical :)
Hey all,
is this behaviour expected for clojure.test
? I would have expected thrown?
to realise lazy results
(testing (is (thrown? AssertionError (assert (= 1 0)))))
;; 0 failures, 0 errors.
(testing (is (thrown? AssertionError (map #(assert (= % 0)) [1]))))
;; FAIL
;; expected: (thrown? AssertionError (assert (map (fn* [p1__21975#] (= p1__21975# 0)) [1])))
;; actual: nil
(testing (is (thrown? AssertionError (doall (map #(assert (= % 0)) [1])))))
;; 0 failures, 0 errors.
(testing (is (thrown? AssertionError (mapv #(assert (= % 0)) [1]))))
;; 0 failures, 0 errors.
Looking at the source for thrown?
is it because the body is evaluated and so if the result itself is lazy, nothing will realise it?
right, evaluating a lazy form doesn't force any of its elements, you need to do something that actually accesses things inside it
I like that I can post an article from 3 years ago, and the author shows up 3 min later to clear everything up
when a library specifies a dependency in its project.clj/deps.edn etc.. , does that implies the library must use that exact version or implies it is the minimum version required?
it implies that it was tested against that version, and doesn't imply anything about other versions
@hiredman but what if you need to use a newer version of that transitive dependency? is this the famous jar hell problem?
You can also use "LATEST" I figured out recently, though I'm just a Maven newbie
Does anyone know what :forms
means in the context of var metadata? It looks like it serves the same purpose as :arglists
, but I think there must be something else as well
https://github.com/clojure/clojure/blob/master/src/clj/clojure/core.clj?utf8=ā#L4494-L4502
https://github.com/clojure/clojure/blob/master/src/clj/clojure/core.clj?utf8=ā#L285-L292
defn
uses :arglists
but fn
uses :forms