This page is not created by, affiliated with, or supported by Slack Technologies, Inc.
2019-01-05
Channels
- # announcements (2)
- # beginners (44)
- # calva (7)
- # cider (8)
- # cljs-dev (2)
- # clojure (131)
- # clojure-serbia (2)
- # clojure-spec (3)
- # clojure-uk (56)
- # clojurescript (27)
- # cursive (7)
- # datomic (6)
- # fulcro (25)
- # jobs (3)
- # klipse (3)
- # leiningen (2)
- # off-topic (8)
- # overtone (2)
- # pathom (2)
- # portkey (2)
- # re-frame (2)
- # reagent (10)
- # shadow-cljs (44)
- # spacemacs (1)
- # tools-deps (6)
- # uncomplicate (2)
@trailcapital @hiredman case is different in Clojure and ClojureScript. Clojure case does not evaluate the stanza handles. CLJS does.
case is like the millionth place where clojure and cljs diverge, and if you complain about someone will popup and say "oh, its just an edge case"
"As discussed in that thread we're not re-breaking a thing we broke 2 years ago. It's simply not that important and far too late."
clojure's case behaves the way it does because it has to. case provides constant time dispatch, in order to compute the jump table it has to have the values on hand, which in the general case means they have to be unevaluated constants
hilariously the non-constant time cases are the cases where its semantics match clojure's, if I recall
the cond fallback the clojurescript macro uses treats symbols differently then the constant time dispatch part
Yeah, there’s also the unfortunate handling of const vars http://blog.fikesfarm.com/posts/2015-06-15-clojurescript-case-constants.html
basically clojurescript's case was implemented by someone who didn't entirely understand case, and now it is enshrined forever as an asterisk on any discussion of clojurescript / clojure portability
Right. A similar thing happened with binding
(the parallel aspect) but that was fixed.
It feels like we are down to this hastening only once or twice a year now (where a mistaken difference is discovered and a decision needs to be taken on whether to fix it).
Another recent one sitting there is the handling of empty regex s, but those differ anyway
I just remember arguing with dnolen on irc way back because he insisted that clojurescript just be referred to as clojure, and clearly there are differences enough that the distinction must be made
Hah, yeah. The same concept arises with self-hosted ClojureScript. Ideally you could just pretend it is the same language, but perhaps it is another (albeit close) dialect
CLR is the most compatible with the JVM version
David Miller
if CLR wasn't a microsoft project and there was a tool like lein for clojure-clr, I bet Clojure-CLR would see a lot more use
I thought I read somewhere that, back in the day, you would upgrade from one version of Lisp to another by running your source through some Lisp designed to translate :)
@dpsutton from what I gather the similarities between CLR / JVM and C# / Java mean it's not as bad as you might think
i like everything about C# except how tied to windows it was when i used it. winforms, etc, visual studio, etc
mono is usable, but I think MS' reputation still holds CLR back
because it is very easy to confuse the source and the target language when you are using the same language and are generating an in memory image to dump to disk
Well we could have a spec for Clojure, confirm the code, and then unform it to a spec for Clojure2
doesn't elm kinda do this when they do compiler upgrades? you can run something over your code to get the mechanical stuff
https://pdfs.semanticscholar.org/98bf/0466dcb0712d2082a7b02d8773bb744ea626.pdf "SBCL: a Sanely-Bootstrappable Common Lisp"
I mean, porting Clojure to other platforms is tricky both because Clojure leaves some semantics up to Java, adopts some weirdnesses because of Java, and also lacks a formal spec or a cross target test suite.
Maybe it is a bit like Unix / C, with just the right amount of looseness at the bottom to let it spread easily.
and google how the hell to run autotools and then run them before running configure
that paper describes kinda self hosted cljs right? it grabs a js environment, feeds it enough info to become a cljs environment and then compiles the cljs compiler?
Can anyone here point me to any documentation on the meaning of ::keys for destructuring?
@pauld that is called a “namespaced keyword”: https://clojure.org/reference/reader#_literals
Ok, I know the difference now via some experimentation. I just thought it weird I could not find any documentation. I did find this: https://clojureverse.org/t/poll-destructuring-namespaced-keywords/1388/5
official docs on it are here: https://clojure.org/guides/destructuring#_namespaced_keywords
so (pop [])
errors, but (peek [])
and (pop nil)
just work… what’s the reasoning behind that?
hello friends,
Question about concurrency: if i have two http requests (ring) coming in, in quick succession, I want to make sure that the first one can do some work, and block the second request for a little bit, and after the first request is done, the other can continue (it’s ok if the 2nd one takes a few milliseconds longer to succeed)
How should I go about this? I started out with a global atom
, for simplicity let’s say it’s a boolean busy?
which is true
when it’s busy, and false
otherwise
but how to ‘wait’ for the atom? I could of course make a spinning loop but that feels very dirty.
Which construct from clojure would be suitable?
more context: I am integrating with an oauth2 API, which requires me to refresh access tokens
but if two calls to this api follow each other up quite quickly (which could happen) for the same user
and the first one is busy refreshing the token via a HTTP POST call to the external API
then the second one will fail because the external api says: ‘you are using an outdated token’
it would be better to make it idempotent. so a second refresh just gets you the same token as the first refresh
you could make a local atom keeping the tokens and return the same token if it’s still valid
Yea, basically, catch the "invalid token" message at the clojurescript, do the dance to refresh it with the refresh token, then continue with whatever it was the client was actually requesting.
one idea i also have, come to think of it, is to just retry. catch the refresh token outdated exception server-side, re-look in the database (which has a new token in a very short while) and retry
thanks, i hoped there was some construct that did this for me, so that I came to check here.
I'm assuming you know about https://github.com/funcool/buddy ?
but i just realize the simple solution is staring me in the face: - catch the ‘outdated token’ refresh action, and just proceed; there must ’ve been a previous request which done that
@kah0ona I have a similar construct with futures. I’m getting some data from a future and keep those futures in an atom. It doesn’t matter if the future is already realized or still running. If there is already a future, I just wait for that one. If there isn’t one, I create one.
Decided to ‘keep it simple’. If the refresh failed due to outdated token (ie. race condition), wait 200ms, assume by now the new tokens are stored in the database by the previous request, re-fetch those (they should be valid anyway, since validity is 10minutes), and proceed the handler.
the only thing is the thread/sleep… but at least it’s very clear what’s happening. Not sure if this gives lots of problem when i have a gazillion concurrent users doing things like this, but I’ll come back here when that happens 😉
as an aside: again realizing the middleware pattern is awesome. the business logic ring handlers are now simplified so much.
here’s a non-blocking way to do it: a function called is-about-to-expire
and an atom is-updating
, then in your request have something like this:
(if (and (is-about-to-expire token) (compare-and-set! is-updating false true))
(try
(swap! token-atom (get-new-token)))
(finally
(reset! is-updating false)))
that means the first thread that sees that the token is about to expire will fetch a new one, but since the old one hasn’t expired yet everyone can keep making requests
What does a la carte mean? Im having trouble trying to find a good definition on google.
it’s a restaurant term, it means that you can pick and choose what dishes you want instead of getting a pre-composed menu
How do deftest and spec differ?
Does anybody know if there are performance improvements or other good or bad side effects in moving from openjdk 8 to 11?
Hi! I'm doing a library that provides optional functionality that depends on clojure.core.cache
. But since this is optional functionality, I don't want to introduce dependency on core.cache
, and thinking how can I make this dependency a "soft" one. Initially I tried using own protocol similar to core.cache
and extend it to core.cache
's one if it exists like that:
(when (try
(require 'clojure.core.cache)
true
(catch Exception _
false))
(extend-protocol Cache
(:on-interface clojure.core.cache/CacheProtocol)
(lookup [this k]
(clojure.core.cache/lookup this k))
(has? [this k]
(clojure.core.cache/has? this k))
(hit [this k]
(clojure.core.cache/hit this k))
(miss [this k v]
(clojure.core.cache/miss this k v))
(evict [this k]
(clojure.core.cache/evict this k))))
But I think this solution sucks, because I can't extend protocol to another protocol, only to interfaces
I just realized I can check if supplied cache satisfies clojure.core.cache/CacheProtocol
and wrap it with my cache
@vlaaad https://github.com/clojure/spec.alpha/blob/master/src/main/clojure/clojure/spec/gen/alpha.clj#L17
You can optionally run some code, depending on whether you’re able to load clojure.core.cache
Yeah, I decided to do it like that:
(def core-cache-protocol
(try
@(requiring-resolve 'clojure.core.cache/CacheProtocol)
(catch Exception _
nil)))
(defn ->cache [x]
(if (and core-cache-protocol (satisfies? core-cache-protocol x))
(let [core-cache-lookup @(resolve 'clojure.core.cache/lookup)
core-cache-has? (resolve 'clojure.core.cache/has?)
core-cache-hit (resolve 'clojure.core.cache/hit)
core-cache-miss (resolve 'clojure.core.cache/miss)
core-cache-evict (resolve 'clojure.core.cache/evict)]
(reify Cache
(lookup [_ k] (core-cache-lookup x k))
(has? [_ k] (core-cache-has? x k))
(hit [_ k] (core-cache-hit x k))
(miss [_ k v] (core-cache-miss x k v))
(evict [_ k] (core-cache-evict x k))))
x))
I want do serve files from the file system, like with python -m SimpleHTTPServer
, but from inside a clojure process. I think saw a tweet the other day about a(n old, "done") library for this, but I can't seem to find it. Does anyone know which library I'm talking about?
How to run sh
in Clojure to run wkhtmltopdf
with input stream and output stream if possible? I want to do in from in-memory data instead of files.
ok I think the only one way is to use -
instead of file name for output. Then I will have output in :out
.
so I have to figure out how to make input from memory. Probably with :in
but this will be long input string.
(sh "wkhtmltopdf" "-B" "0" "-L" "0" "-R" "0" "-T" "0" "--page-height" "58mm" "--page-width" "43mm" "--disable-smart-shrinking" "-" "foo.pdf"
:in (slurp "resources/index.html"))
@madstap Maybe this will help: https://github.com/ring-clojure/ring/wiki/Static-Resources
Thanks, I think it was https://github.com/tailrecursion/lein-simpleton that I saw. As it turns out it's not exactly what I wanted, but it looks easy enough to just use ring directly.
https://github.com/cognitect-labs/test-runner - this library for tests is be default included to clj
template for new project. Does it have option to watch and test again after each change? Or should I use something else?