This page is not created by, affiliated with, or supported by Slack Technologies, Inc.
2020-03-05
Channels
- # announcements (17)
- # aws (1)
- # babashka (68)
- # beginners (88)
- # calva (85)
- # chlorine-clover (10)
- # cider (5)
- # cljsrn (4)
- # clojure (99)
- # clojure-android (1)
- # clojure-denmark (1)
- # clojure-europe (15)
- # clojure-italy (5)
- # clojure-nl (3)
- # clojure-spec (1)
- # clojure-uk (67)
- # clojurescript (44)
- # core-async (44)
- # cryogen (4)
- # cursive (22)
- # data-science (2)
- # datascript (10)
- # datomic (29)
- # duct (11)
- # editors (2)
- # emacs (2)
- # events (1)
- # fulcro (28)
- # ghostwheel (7)
- # graalvm (8)
- # instaparse (6)
- # java (34)
- # jobs (9)
- # jobs-discuss (71)
- # juxt (12)
- # luminus (3)
- # malli (15)
- # meander (9)
- # nrepl (4)
- # off-topic (44)
- # pathom (13)
- # reagent (22)
- # schema (1)
- # shadow-cljs (39)
- # spacemacs (2)
- # test-check (1)
- # tree-sitter (5)
- # xtdb (5)
- # yada (1)
> Default reader tags are defined in > clojure.core/default-data-readers but may be overridden in > data_readers.clj, data_readers.cljc, or by rebinding this Var.
(binding [*data-readers* {'foo/bar `int}]
#foo/bar 3)
Syntax error reading source at (REPL:74:13).
No reader function for tag foo/bar
from the docstring of data-readers i expect i can dynamically add a namespaced data reader and use it in this fashion but i seem to be missing something
like so?
(binding [*data-readers* {'foo/bar `int}]
(clojure.edn/read-string "#foo/bar 3"))
and using read:
(binding [*data-readers* {'foo/bar `int}]
(read-string "#foo/bar 3"))
Execution error at find.main/eval8981 (REPL:104).
No dispatch macro for: f
Map from reader tag symbols to data reader Vars.
When Clojure starts, it searches for files named 'data_readers.clj'
and 'data_readers.cljc' at the root of the classpath. Each such file
must contain a literal map of symbols, like this:
{foo/bar my.project.foo/bar
foo/baz my.project/baz}
That’s where I got confused. Map of symbols so I assumed it needed namespaces qualified symbols
Hi all! A question about https://github.com/l3nz/cli-matic:
Do I have to use a sub-command? Does it support no command style?
Something like: my_app --some_param=1 some_argument
I had the exact same question today. The docs on cli-matic are a bit vague on this point, and I couldn’t find the author on Clojurians. But a little bit of local testing suggests that, yes, cli-matic requires subcommands.
Was surprised to find that my ETL pipeline spends a considerable amount in SSL processing (JDK 8, for now). I don’t control the code that handles the connections (MongoDB and JDBC Postgres) - is there a way to speed things up other than throwing hardware at the problem?
With ScheduledThreadPoolExecutor available, is there any Clojure job scheduler (at-at, overtone, tea-time) that gives any added value?
How easy is it to test code using ScheduledThreadPoolExecutor?
tea-time has a virtual clock that makes it very easy to test schedules.
https://github.com/aphyr/tea-time#testing-with-virtual-time
tea-time also has defer!
task, which I don't think ScheduledThreadPoolExecutor has directly. This feature "feels" very natural and common sense to me.
fwiw I've written* a library recurring-cup
that let's you work with and schedule (lazy) sequences of java.time.ZonedDateTime
. This library makes it easy to run a function at (for example) a fixed time of the day. It's built on top of tea-time
.
* Not released, not well documented.
https://github.com/ivarref/recurring-cup
ScheduledThreadPoolExecutor has always worked for me when using a single vm, I have never run into complications or extra problems from not using a wrapper over it
it can use clojure functions directly since they are Runnable / Callable
(on the other hand, if your scheduling has to work across redeploys or across multiple instances, you need bigger guns and the clojure wrappers really help a lot)
I like ScheduledThreadPoolExecutor but it does not make many decisions for you and by default you may do the wrong thing (e.g long running jobs blocking the pool)
I am not too familiar with clojure schedulers, as I am pretty comfortable ScheduledThreadPoolExecutor but perhaps they provide an easier api with sane defaults
Hi there! 👋
I try to solve a special problem and I am looking for a function/lib, that could help me.
Let’s say, I got a function and a list of items. Now I want to call the function on parallel with each item of the list and just want the result of the fastest thread (and dump all other threads without waiting for them).
Something like wanted-fun
in here:
(def l [100 200 300])
(defn fun [x] (Thread/sleep x) x)
(wanted-fun fun l) ; >> 100 (after ~100 miliseconds)
Does this already exists or do I have to build it by my own?@soeren.gutzeit isn't fun
already that function? or do you mean something like (defn wanted-fun [f x] (f x))
?
if you want the first succeeding result from multiple threads, you can use something like core.async or promises:
(def prom (promise))
(future (Thread/sleep 100) (deliver prom 1))
(future (deliver prom 2))
@prom ;;=> 2
I’m not sure I’ve really got the hang of core.async yet, but here’s what I came up with:
(require '[clojure.core.async :refer [go chan >!! <!! alts!!]])
=> nil
(def l [100 200 300])
=> #'user/l
(defn fun [x] (Thread/sleep x) x)
=> #'user/fun
(defn wanted-fun [f coll]
(let [ports (map (fn [l]
(let [ch (chan 1)]
(>!! ch (f l))
ch))
coll)]
(first (alts!! ports))))
=> #'user/wanted-fun
(wanted-fun fun l)
=> 100
@manutter51 slight variation, where the sleeping happens not on the main thread:
(require '[clojure.core.async :refer [go alts!!]])
(def l [100 200 300])
(defn fun [x] (Thread/sleep x) x)
(defn wanted-fun [f coll]
(let [ports (map (fn [l]
(go (f l)))
coll)]
(first (alts!! ports))))
(prn (wanted-fun fun l))
Nice, the go
automatically creates the chans for you? I never realized that but then again I did know that go
returns a chan so I guess I shoulda known.
go
and async/thread
both return channels that contain the result of that async computation. in this case async/thread
might be a better choice than go since sleeping in a go block might not make sense.
Would that work with alts!!
though? If you just want to get whichever one comes back first, and ignore the others, I’m not sure how to do that with async/thread
(due to my lack of experience with the async stuff)
Rather frequently, I have some data that contains object literals referencing some java class but if I try to copy-paste this into repl it fails:
{:id 308, :time-now "2020-03-04T16:48:39.000Z" :created-at #object[org.joda.time.DateTime 0x799dfbe "2020-03-04T16:48:39.000Z"], :updated-at #object[org.joda.time.DateTime 0x9cae937 "2020-03-04T16:48:42.000Z"], :status :failure}
...
No reader function for tag object
Is there an easy way how to make it work?@jumar you can transform this stuff using edn/read-string with :reader
or :default
and a good default could be tagged-literal
user=> (edn/read-string {:default tagged-literal} "{:id 308, :time-now \"2020-03-04T16:48:39.000Z\" :created-at #object[org.joda.time.DateTime 0x799dfbe \"2020-03-04T16:48:39.000Z\"]}")
{:id 308, :time-now "2020-03-04T16:48:39.000Z", :created-at #object [org.joda.time.DateTime 127524798 "2020-03-04T16:48:39.000Z"]}
Thanks; is there any way how to make this a default behavior so I don't need to wrap it every time I need this?
don't know, maybe by setting it in data_readers.clj but I'm not sure if that's a good idea
Say one wants to pass a server port as an arg to main. Is there a way to pass opts or an opts map to be read/coerced to edn? currently everything is interpreted as a string, so port
becomes "port"
, :port
":port"
and 8080
"8080"
while the goal is {:port 8080}
clj -m my.server port 8080
https://github.com/clojure/tools.cli can help with this
perfect thank you @alexmiller
hi all! today im taking my first steps to learning Clojure. i was mainly convinced by the positive response to this tweet 🙂 https://twitter.com/tangjeff0/status/1234688533367050244?s=20 hope to keep in touch with everyone for the next 10+ years! haha
I started learning Clojure a few months ago 🙌 I definitely recommend reading “Clojure for the Brave and True” and doing Clojure Koans and 4Clojure exercises Have fun!
haha im part-way through ch 3, i absolutely love Clojure for the Brave so far. will check out Koans 4Clojure too. thanks!
welcome! #beginners is a great place to ask questions...
or https://ask.clojure.org for searching or creating a record of good q&a
I'm in need of a bit of code to take an accept-lang
header and turn it into an iso 639-1 language code. I'm poking around to see if I can find something pre-existing to do that - does anyone know of anything in clojure-land (or optionally java land) to do that?
https://docs.oracle.com/javase/7/docs/api/java/util/Locale.html#forLanguageTag(java.lang.String) and #getISO3Language ?
it's close - I need to end up with the 2 letter code, but I suspect I can find what I need here
(defn inject-$val [val form]
`(let [~'$val ~val]
~form))
(eval (inject-$val (StringBuilder.) '(pr-str $val)))
=>
Syntax error compiling fn*.
Can't embed object in code, maybe print-dup not defined:
How can I inject an arbitrary value into local scope for eval?Figured it out: transform form to a function that is then called with arbitrary value:
(defn ->$val-fn [form]
`(fn [~'$val]
~form))
((eval (->$val-fn '(pr-str $val))) (StringBuilder.))
=> "#object[java.lang.StringBuilder 0x3909a854 \"\"]"
(eval (inject-$val '(StringBuilder.) '(pr-str $val)))
=> "#object[java.lang.StringBuilder 0x6380a835 \"\"]"
I'm processing messages coming over a core.async
channel, and I'd like to pipe them to another channel with a weird caveat. The messages that represent success I want to pipe unconditionally and immediately, but the messages that represent failure I want to delay sending them for some grace period, and forgo sending them if a success message arrives before the grace period elapses. My first thought is to use some kind of stateful transducer but I'm having a hard time finding examples of transducers that do delayed delivery of the result, or that make behavior for the nth item conditional based on the n+1th item. Am I trying to use transducers for something they weren't designed for?
There are plenty of options for doing it in a go-loop. I am hoping to find something that is a bit more constrained and concise than that.
channel transducers run within the context of the channel mutex; interactions with other channels are verboten
channel transducers also run in band, they can only pass or not pass through (possibly transformed) data, they can't sit on data and wait
the reason you can't find examples of transducers that do delayed delivery is it isn't something they can do
Yeah I think the delayed aspect is what's going to stop me here. I can imagine storing some internal state in a transducer that only gets returned when some other new input arrives, but that would have to happen synchronously with the new input arriving, and can't happen at an arbitrary time between inputs.
This is essentially a low-pass filter, so the idea is conceptually somewhat simple and I'm struggling to find the correspondingly simple implementation.
(fn [in out] (async/go-loop [t nil] (let [[a-val a-ch] (async/alts! (some->> t (conj [in]))] (cond (and (= ch in) (success? val)) (do (async/>! out a-val) (recur t)) (= ch in) (recur (asnc/go (async/<! (async/timeout 1000)) a-val)) (= ch t) (do (async/>! out a-val) (recur nil))))))
Putting the pending failures each in their own delayed channel helps a lot
There's another wrinkle here where there may be several failure messages that are pending before the timeout elapses or a success arrives, but it's relatively simple to extend this to a queue of pending failures
the thing to watch out for if you are managing multiple timeout channels is avoid using them directly as keys for maps or members of sets
because timeout can return the same channel more than once, so not a good key or set member, but if you create a go block that takes from the timeout and returns something useful that is less likely to bite you
Are you talking about the equality gotcha related to optimizing multiple timeouts that happen close to each other?
right
When creating a function that is an intermediate processing step in a core.async process, is it more idiomatic to have the function take the in-chan
as an argument and return an out-chan
that was created internally, or take the out-chan
as an argument and return an in-chan
that was created internally, or take both as arguments, or take neither?
I like to take both an in and out, and then the function returns the channel from the go block it starts, which another process can wait on if they want to wait for that process to stop
I had the exact same question today. The docs on cli-matic are a bit vague on this point, and I couldn’t find the author on Clojurians. But a little bit of local testing suggests that, yes, cli-matic requires subcommands.