This page is not created by, affiliated with, or supported by Slack Technologies, Inc.
2018-08-15
Channels
- # announcements (13)
- # beginners (106)
- # cider (70)
- # cljdoc (1)
- # cljsjs (1)
- # clojure (97)
- # clojure-finland (1)
- # clojure-italy (13)
- # clojure-mexico (16)
- # clojure-russia (1)
- # clojure-spec (53)
- # clojure-uk (146)
- # clojurescript (44)
- # core-async (5)
- # cryogen (1)
- # css (1)
- # cursive (11)
- # datomic (89)
- # duct (10)
- # emacs (4)
- # figwheel-main (58)
- # fulcro (5)
- # hispano (35)
- # hyperfiddle (1)
- # jobs (2)
- # jobs-discuss (1)
- # lambdaisland (1)
- # leiningen (3)
- # off-topic (13)
- # onyx (50)
- # parinfer (3)
- # pedestal (4)
- # reagent (9)
- # ring-swagger (56)
- # rum (3)
- # shadow-cljs (85)
- # spacemacs (4)
- # vim (4)
hello clj community! is there a function like clojure.string/replace-first
for the last match? replace-last?
no, but you can use replace-first with proper regex to do it
user=> (clojure.string/replace-first "HI FOO FOO" #"(?s)FOO(?!.*?FOO)" "BAR")
"HI FOO BAR"
5 minutes ago I could not have told you how to do that, but I googled “java string replace last” and took the top stackoverflow hit - https://stackoverflow.com/questions/2282728/java-replacelast
that page explains the regex in more detail
Java has a large SDK and an enormous user base - lean on it!
@ferdi.kuehne Actually, there is a simpler and more correct way:
user=> (clojure.string/replace-first "aabaabaaab" #"(?s)(.*)(aa)" "$1AA")
"aabaabaAAb"
big thanks @avfonarev
Is there any easy way to get the time, with timezone from a string with clj-time
? for instance "2013-02-12T04:30:00.000-02:00"
clj-time.coerce/to-date-time
seems to get it and convert to UTC, which you could add back with clj-time.core/to-time-zone
but this seems a bit fiddly to me
Is this what you're looking for @torvaney?
(require '[clj-time.core :as t])
(require '[clj-time.format :as f])
(f/unparse-local (f/formatter-local "HH:mm:ss") (t/time-now))
=> "17:12:29"
Hey all, often when I'm working with large nested data strucutres in clj I spend a lot of time trying to find the nested part of the stucture I want and generally just trying to get a mental image of how it's organised. I would love to able to see a tree like representation of the data structure.... Does anyone have any tips or tricks to help with this aspect of clj?
@michael.ford The main thing I do is pretty-print the data, if it is not too large. The line breaks and indentation help a lot.
:thinking_face: honestly the experience in CLJS using cljs-devtools or frisk is quite a bit better than what’s available for Clojure
oh this looks kind of nice: https://github.com/Azel4231/dsui
and I always forget about clojure.inspector: https://clojuredocs.org/clojure.inspector/inspect-tree
https://github.com/eggsyntax/datawalk is another option
reddit or clojureverse - or even here 🙂
#code-reviews has a few people in it
Just found out about Graal and Truffle. Turns out you can compile Clojure using Graal. https://www.innoq.com/en/blog/native-clojure-and-graalvm/
@noisesmith a follow-up to my question yesterday about promises/futures vs. core.async channels: I found an older doc that echoed my exact concern (even mentioning C#'s async/await implementation, which motivated my question, as an example for solving the problem). I'm still reading through it to figure out how it was solved, but it seems the core.async channel implementation is the solution to my concern with promises/delays. I believe the conclusion you and I reached previously was incorrect. Here's the doc I'm referring to: https://dev.clojure.org/display/design/Async+blocks
which part was incorrect?
That derefing a promise/future doesn't busy-wait.
it doesn't busy-wait. busy-wait here means consuming CPU while waiting
it just blocks until something wakes it up by setting the value
you might not want to block a thread for resource or performance reasons, but it's not a CPU issue
Yeah, it's the "you might not want to block a thread for resource or performance reasons" that I'm concerned with. The async.core channels don't exhibit that problem when awaiting values. I think my original question was confusing because I mentioned "OS threads", wording that I copied directly from the async.core documentation.
I'm still not convinced that "dereferencing a promise consumes no CPU while waiting". What I've read so far indicates that clojure promises aren't implemented with any mechanism that allows callback-like execution upon the availability of a value. Which implies CPU consumption at some level during blocking. Have you seen something in the clojure codebase or docs that suggests otherwise?
deref doesn't loop, it sets a monitor so the thread resumes when the data is delivered
in general, if your notions of threads and asynchronous whatever come from a runtime without real concurrency (javascript, any of the interpreted languages with a GIL), your intuition about how things work and what happens when is going to match the reality of a concurrent runtime with real threads
e.g. my reading of that async+blocks page doesn't convey any concern about busy waiting
a jvm thread is pretty cheap, and depending on your resources you can have a whole lot of them (tens of thousands or more) sitting around doing nothing without you noticing
"Busy wait" came into the conversation because in my original questioned I mentioned "OS threads" like the async.core page does. That's my fault. Although as far as I know, blocking a JVM thread would indeed block an OS thread. But that's besides the point. The info I was looking for is that "promises/delays block their thread (resources are tied up) when dereferenced, whereas channels don't (similar to async/await mechanisms in .net, JS, and scala)".
blocking an os thread generally means the thread is removed from the schedulers ready list until some other thread puts it back
Right, and all of that involves pushing data around. That's okay too. The point was that it doesn't make sense to spin up multiple threads (which aren't what I'd call "cheap", although that's relative I guess) and have them all block until ready, when the language has an idiomatic way to handle async programming (via the core.async lib).
Not at all.
core.async does spin up multiple threads, by default the threadpool that services go macro callbacks is 8 threads, and provides the thread macro for tasks dispatched to an unbounded caching threadpool
exactly
It does that in order to implement the async behavior (I'm kind of guessing on this part, haven't gotten that far into that code yet)
Compared to other language implementations where perhaps a state machine is used.
Right?
Fibers are on the way, apparently https://jaxenter.com/project-loom-trend-watch-jvm-ecosystem-147448.html
so the difference between using the go macro, which on parking on a channel suspends the rest of the computation and attaches it to the channel so when another operation on the channel happens it can be re-woken up, and a thread being taken out of the os ready list and waiting somewhere for another thread to re-schedule it is pretty hand wavy
For straightforward parallelism core.async won't increase performance, in fact it usually makes things slower. What core.async is good for is making code that does a lot of asynchronous coordination easier to read, and lowering the overhead of code that does massive amounts of context switching
Agreed fully. I think we're on the same page now.
I doubt that is a jvm limit, more often you hit the os default limits, which are tunable
@john thanks for the link, I had not heard of FIbers. Worth watching.
core.async code is almost certainly going to do more context switching then regular threaded code
the go macro transforms what would be code full of callbacks on channels in to something more easily read
Aye, for millions of concurrent clients, a few thousand threads each handling a few thousand clients via core.async is probably the way to go, right?
Though I guess it's questionable how many threads beyond the number of cores will benefit, when using core.async
Thanks all. Lot of good info here, some of which is reinforcing my initial suspicions. I've written quite a bit of clojure for a year or so, but haven't delved much into the async-specific corners of the language. Hence my "compare this tool to that tool" question.
Also glad to hear that just using plain old promise/deref code is common
So you're saying you'd actually use Thread interop calls rather than running something with Future?
so for example, clj-http doesn't return a promise that has the result of an http call delivered to it, it just does the http call and returns the result
Maybe I'm conflating "future" and "promise" when I shouldn't be.
They certainly seem to be used similarly
not in clojure
a promise is a container that blocks reading until it has a value delivered
it isn't a thread, doesn't create a thread, doesn't manage threads in any way
(aside from blocking)
If I read the write-up correctly, the new java/fibers interface is going to be similar to the java/thread interface. It'll be interesting to see if a Clojure can just choose either as a backing option
I pictured promise and delay being used like this to do something asynchronously:
clj
(defn my-async-func []
(let [p (promise)]
(future (do-something-expensive)
(deliver p "finished!"))
p))
and the caller could deref the result at will (ie. caller wouldn't have to block until they needed to). But it sounds like that's not a common approach in your experience with clojure?in that case it would be more common to just use the return value of future over using a promise
and even more common to just call (do-something-expensive) without a future or a promise
Your first point totally makes sense; I should have seen that. Second point is surprising, so good to know.
if you don't need to run lots of do-something-expensive in parallel or something, there is no reason to spin off another thread to do it
all my comments should have a parenthetical "if you are using a language on the jvm which has real threads, does not apply to a similar language on a different runtime without real threads"
"there is no reason to spin off another thread to do it" is exactly what led me to core.async. Desire to (1) minimize new threads if possible, and (2) don't want to block the calling thread (this is sort of just my default approach for long-running operations).
But if #2 doesn't matter, then yeah I totally get it.
Async/await mechanisms are so common in other code I've written, I wanted to make sure I understood when these different approaches were best used in clojure.