This page is not created by, affiliated with, or supported by Slack Technologies, Inc.
2018-11-20
Channels
- # announcements (2)
- # architecture (5)
- # beginners (118)
- # cider (5)
- # clara (13)
- # cljdoc (8)
- # cljs-dev (49)
- # cljsjs (2)
- # clojure (107)
- # clojure-dev (9)
- # clojure-europe (3)
- # clojure-italy (58)
- # clojure-japan (2)
- # clojure-nl (6)
- # clojure-spec (89)
- # clojure-uk (27)
- # clojurescript (9)
- # core-async (33)
- # cursive (2)
- # datascript (2)
- # datomic (31)
- # duct (4)
- # emacs (1)
- # events (1)
- # figwheel-main (1)
- # fulcro (69)
- # hoplon (7)
- # hyperfiddle (16)
- # incanter (4)
- # instaparse (4)
- # kaocha (1)
- # mount (2)
- # nrepl (19)
- # off-topic (40)
- # onyx (6)
- # other-languages (3)
- # pedestal (2)
- # re-frame (48)
- # reagent (2)
- # reitit (10)
- # ring-swagger (9)
- # shadow-cljs (63)
- # spacemacs (13)
- # sql (8)
Does Clojure has SimHash algorithm implementation or wrapper on Java libraries? I search clojars, not found. only one cascading-simhash
. And I also did search on Maven, don't know choose which one. Does anyone knows similar library of implementation about text similarity comparision.
@jayzawrotny @noisesmith reitit flattens extra sequences, so instead of concatting programmatically, one could just say [(home-routes) (api-routes)]
. If you want to have a common root definition, you can also say:
["" {:middleware [middleware/wrap-csrf middleware/wrap-formats]}
(home-routes)
(api-routes)]
but in case you want to add common data to all routes, you can also put the under router option :data
. Behind the scenes, router :data
and all intermediate route data is recursively (meta-)merged to the endpoints, the doing effectively the same.
(ring/ring-handler
(ring/router
[(home-routes)
(api-routes)]
{:data {:middleware [middleware/wrap-csrf middleware/wrap-formats]}}))
(there is also #reitit)the automatic flattening of nested sequences is nice, because you can create your routes with things like for
and it just works:
(ring/ring-handler
(ring/router
[["/ping" {:get (constantly {:status 200, :body "pong"})}]
(for [i (range 10)]
[(str "/item-" i) {:get (constantly {:status 200, :body (str "item-" i)})}])]))
(I feel like I am asking many questions, if it is bothering please say!) I have a record from a library for which I want to implement a own-defined protocol. So I created a namespace that calls extend_type
with that record and a custom implementation of that protocol. What I donât quite understand is where to require this namespace. The library is the instantiator of those records and when they reach my code I want to treat them like my protocol dictates. Is there some documentation on this?
As in everywhere-everywhere, or only on the spot where that record enters my code
I mean, technically, it is just that you need to have evaluated extend-type once after the record was defined.
Hmm, that sounds reasonable
It doesnât work yet, but probably my bug
(do
(ns first)
(defrecord Animal [name])
(ns second)
(defprotocol PAnimal
[get-name [this]])
(extend-type first.Animal
PAnimal
(get-name [this] (:name this)))
(ns third)
(require '[first :as f])
(require '[second :as s])
(s/get-name (f/->Animal "dog")))
Yeah it works like I expect it in my repl, but not in my app
so its probably something I am doing stupidly
:â)
When using EDN as config files, is there a way to express DAGs or better yet (arbitrary fully connected graphs) in EDN?
I guess đ
How do I make rebel-readline
execute (use 'clojure.repl)
on startup?
This doesn't work:
clojure -A:rebel -e"(use 'clojure.repl)"
Here's deps.edn
:
{:deps {org.clojure/clojure {:mvn/version "1.10.0-beta7"}}
:aliases {:rebel {:extra-deps {com.bhauman/rebel-readline {:mvn/version "0.1.4"}}
:main-opts ["-m", "rebel-readline.main"]}}}
can you add the -e to the :main-opts?
oh -it's an init-opt not a main-opt
@dpsutton it shows function arglists as you type, indents code, rainbow parens by default, and some other comfy features.
I'm getting: Error building classpath. Unknown alias key: :init-opts
{:deps {org.clojure/clojure {:mvn/version "1.10.0-beta7"}}
:aliases {:rebel {:extra-deps {com.bhauman/rebel-readline {:mvn/version "0.1.4"}}
:init-opts ["-e", "(use 'clojure.repl)"]
:main-opts ["-m", "rebel-readline.main"]}}}
Yes I know that. I'm wondering what it is missing that is promoting you to include clojure.repl
doc
and source
Also pprint
for which I need to do (use 'clojure.pprint)
yeah - clojure.repl is pretty important (though rebel-readline does do its own version of those in a pretty way)
true that
This causes an exception:
:main-opts ["-e" "(use 'clojure.repl)" "-m", "rebel-readline.main"]
You need a comma ,
instead of space in the use
.
I'm sorry I don't follow.
Because clj
writes options to a file and reads them back in via the shell, spaces do not work. But since Clojure accepts comma as whitespace, you can use ,
instead.
Wow, that worked
See https://github.com/seancorfield/dot-clojure/blob/master/deps.edn for heavier uses of comma-as-whitespace (and as possible inspiration for other deps.edn
stuff).
@seancorfield you just made my day sir!
It is a bit weird though that commas have to be used.
Is this fixable somehow by escaping stuff?
I would say that most escaping tricks are at least a bit weird, if not more so.
especially when you start dealing with 2 independent levels of escaping at different steps, for the same set of characters.
I don't know enough about deps implementation and shell escaping to say for sure, but one would hope at least that it would be possible to preserve the whitespace without resorting to commas
I believe itâs possible to fix but itâs something thatâs going to a) suck and b) take a while
yeah - I know escaping around sh isn't straightforward
itâs going in and out of bash vars, Java, and files
Iâm sure itâs possible to do, I just have had better things to do so far :)
I happen to be going back and forth between bash and clj at the moment in a side project, and Iâll wholeheartedly second the suckiness đ
Or maybe implement *print-readably*
for bash? đ
With regards to the earlier problem I encountered, I was wondering what the reasoning was about the output of the above below program. I expected the latter valid call to return true, as I had (at that point) implemented SomeProtocol for the SomeRecord, but that is not the case. Does this have to do with how that protocol is captured by the closure produced by satisfies-protocol?
?
Hum, I can think of two things maybe. First, s/def is a macro, and so I'm not sure how it resolves the call to your satisfies-protocol? function. So it might just be that your spec isn't working and everything is always false for it.
Nah the problem is the closure on line 12 that captures the protocol definition at that point in time
The protocol definition is updated on line 17, but not in the variables that the closure on line 12 has captured
Are you sure? How did you validate that hypothesis? I'd be surprised if the closure makes a clone of the protocol. It would seem to me this would just copy over the reference to it
well that is what I am getting from the discussion below ^^
not an expert obviously, this bit me yday :â)
Hum, okay, hadn't read all the convo that follows. Wow, if extend uses alter-var-root, that's pretty weird.
yeah, couldnât figure it out either yday, only when I started making that minimal example it started to click slowly
I just always assumed protocols were defined in a global map, but it seems that they each get a Var which is mutated when the protocol is extended with the new version of the protocol. That's kind of weird. The implementation also doesn't seem to take a lock, I wonder if extending a protocol can have race conditions
Oh, forgot that alter-var-root is atomic, so its fine. I guess it actually makes sense. When you defprotocol, like all other def, you're creating a var and assigning it to something. And the protocol hold a map from Type to method implementation. But the protocol is immutable itself. So extending is really creating a new protocol with more implementations set on its map, and updating the Var to point to the new protocol. Cool, learned something today.
cool right, I also learned something today ^^
It feels like that SomeProtocol
is secretly being mutated, but not in the closure created by satisfies-protocol?
.
I tried plenty of things, like instead ânormalâ def
ing the result of the partial application so to say, but as soon as I have a closure that captures that protocol it seems to regard later-defined implementations to not satisfy the captured protocol. Whereas if I would do the capture after, it works fine
If that makes any sense đ
this can happen when you reload the file that defines the protocol - now there's two protocols with the same name, and existing objects likely don't implement the new one
I wonder what's going on without a reload though
@lennart.buit if it helps, putting the extend-type before the s/def makes it return true
That I know, I just canât in my particular usecase
use
(defn satisfies-protocol?
[prot]
(fn [val] (satisfies? @prot val)))
and
(s/def ::some-protocol (satisfies-protocol? #'SomeProtocol))
Had to look at the impl. It kinda feels like Protocols are one of those things that would have been better of made mutable.
ahh - because the protocol was caputured but later mutated?
your definition grabs the value of the var instead of dereferenging the var at every invocation
thanks!
I suspected something like that to happen
I spent the better part of my work day on that :â)
Sorry - satisfied?
, did you mean satisfies?
or � I am not sure I am following
ahhh var in that sense, right you mean that if satisfied?
would deref itself
Thank you at least, I now know that my hunch was correct and I learned something about the internals ^^
yeah - my mind was blown when I first looked at the metadata on a protocol - given enough time I like to think I might have put (+ 2 2) together and realized what was happening here with the scope capture
Love "I might have put (+ 2 2)
together" â¤ď¸ Slightly nerdier: "I might have eval'd (+ 2 2)
", but gets harder to understand then.
Yeah, I think Iâll make my satisfies-protocol?
a macro that does the ref/deref ceremony so that i can keep my call sites the same, but have an actual working function
or â a function that works in all cases
Shouldnât just be (s/def ::some-protocol #(satisfies? SomeProtocol %))
? It seems to work for me
Yeah, but this is so common in my codebase that I like to not have anonymous functions floating about
well yeah, inlining the protocol name gets away with the root cause of the bug, as the protocol is dereferenced inline everytime
I solved it by making a macro called satisfies-protocol?
that has the exact same way of being called, but instead generates that anonymous function
So like this:
(defmacro satisfies-protocol?
[proto]
`(fn [val#] (satisfies? ~proto val#)))
And it can then be used exactly the same: (s/def ::some-protocol (satisfies-protocol? SomeProtocol))
If debugging is the issue, would still prefer (s/def ::some-protocol (fn satisfies-protocol? [o] (satisfies? SomeProtocol o)))
to a macro
Nothing really except for taste. I just have a lot of these specs and I prefer not to change all uses to such an anonymous function.
Keep the âworkaroundâ local instead of littered around the codebase
oh - yeah the function should do a fresh lookup of the var by symbol when called