This page is not created by, affiliated with, or supported by Slack Technologies, Inc.
2020-04-09
Channels
- # announcements (1)
- # architecture (20)
- # aws (22)
- # babashka (41)
- # beginners (191)
- # chlorine-clover (66)
- # cider (19)
- # clj-kondo (54)
- # cljs-dev (15)
- # cljsrn (78)
- # clojars (1)
- # clojure (148)
- # clojure-android (4)
- # clojure-europe (7)
- # clojure-gamedev (15)
- # clojure-germany (6)
- # clojure-losangeles (46)
- # clojure-nl (23)
- # clojure-survey (3)
- # clojure-uk (46)
- # clojurescript (24)
- # conjure (21)
- # cursive (21)
- # data-science (11)
- # datomic (5)
- # events (2)
- # fulcro (28)
- # garden (32)
- # joker (2)
- # kaocha (6)
- # lambdaisland (4)
- # mount (2)
- # off-topic (11)
- # pathom (10)
- # pedestal (13)
- # re-frame (7)
- # shadow-cljs (15)
- # spacemacs (21)
- # specmonstah (1)
- # wasm (1)
- # windows (1)
- # xtdb (37)
What do you guys think of this macro:
(defmacro until->
[pred & [expr & forms]]
(let [g (gensym)
steps (map (fn [step]
`(if (or (~pred ~g) (instance? Throwable ~g))
~g
(try
(-> ~g ~step)
(catch Throwable t#
t#))))
forms)]
`(let [~g (try ~expr (catch Throwable t# t#))
~@(interleave (repeat g) (butlast steps))]
~(if (empty? steps)
g
(last steps)))))
It'll keep threading until pred is true, at which point it'll short-circuit and return the last value
I also made it so it captures thrown exceptions, and short-circuit on them and return them as a value instead
(defn might-error-or-throw [e]
(case (rand-nth [:a :b :c])
:a :error
:b (throw (ex-info "Failed!" {e e}))
:c e))
(until-> #{:error} (might-error-or-throw 10) inc might-error-or-throw inc)
Until you showed the usage I couldn't imagine how it worked... Hmm... I'm still thinking about it...
It's sort of take-while
but complemented and threaded...?
Ah, right. Of course.
(defn might-be-nil [e]
(case (rand-nth [:a :b])
:a nil
:b e))
(until-> nil? (might-be-nil 10) inc might-be-nil inc)
a more generic way might be a threading macro that takes a predicate to decide when to short circuit?
I can't remember ever needing this sort of computation but it's interesting.
ohh right missed that arg
Thought it be a good way for people who like to treat error as values. They could easily build their own value representation of an error, make a pred for it, and then use until-> to guard for those
you might be able to similarly reduce across a list of functions
Are there any neat libraries for test coverage (preferably that are still actively maintained)? In my brief time with Eclipse and Java, I always appreciated being told which branches in code weren't being executed; of course it led to more robust code (or exceedingly painful headaches).
I haven't used cloverage myself, but have heard of people using it
@UN3A4KE13 If you are using Kaocha as the test runner, there is a Cloverage plugin. Really easy to use.
Is it a Leinengen plugin only? I'm having issues with the project I'm working on which is vanilla clj.
The README for Cloverage gives brief instructions for running it without using Leiningen.
Hi folks! Is there any good remote pair programming tool that is neither Emacs nor terminal-based?
i haven't used it myself, but i've heard people use party-repl (i think there may have been a conj talk too?) -- there was mention of it recently in some channel
Thanks a lot! So Far I found VS Code Live Share and https://floobits.com (cross-editor, low price), which both look good. I'll have a look at party REPL.
i presume it would have been easy to find, but fwiw, here's a link to a party-repl talk: https://www.youtube.com/watch?v=AJING0Vigpg
There is also https://www.saros-project.org/documentation/getting-started.html?tab=intellij#restrictions, a mature Eclipse OSS solution for Eclipse with alpha for IntelliJ
https://screen.so/ is from the original Screenhero people. I think Tuple is more mature at the moment, but OTOH Screen is multiplayer and costs a grand total of $0 during the crisis.
Hi everyone. I'm doing a quick spike today on using the Github API (which I gather is GraphQL) to find repos inside a particular organisation and with particular tags. Is there a good GraphQL client library for Clojure, or does anyone know of a project that does something similar already that I could study? A quick Google search is finding mostly ClojureScript, so maybe I should do that instead...
You can ask in #graphql But underneath it is just a POST? And creating a transformation from Clojure data to a GraphQL query string should be simple I guess...
Not really a GraphQL client but I wrote this library to generate GraphQL queries. I think for a very similar use case: https://github.com/avichalp/hql
Hey folks, I have a overloaded function with different arity like
(defn overload
([a]
(println a))
([a b]
(println a b))
([a b c]
(println a b c)))
So we have seen this argument list growing continuously with more people adding more arguments and so on
This is causing the method to grow large. Are there any generic patterns to refactor this method?clojure.core has a few functions with many different arities but I think that's more for performance than anything else (I seem to recall a discussion about it a few days ago in fact). You could perhaps use optional parameters (defn overload [& args])
and then use apply
something like (apply println args)
. But then bear in mind https://stuartsierra.com/2015/06/01/clojure-donts-optional-arguments-with-varargs
Here's the related discussion from the other day: https://clojurians.slack.com/archives/C03S1KBA2/p1585934953056300
I guess a map of optional arguments is a common solution. Though you might want to look at the bigger picture first - why is this happening? Is something wrong / missing in your design? Can you change it somehow to make the need to add arguments go away?
Does it do many things? Can you take it apart to functions that do fewer things, and compose them?
Feel I must be missing something, but here it goes: I wan't a lein
/`clj` based docker image with all dependencies baked it. What would one RUN
in the build expressing "Just download all deps lein
/`clj`" ?
e.g. https://github.com/seancorfield/depstar can build the uberjar for you
@potetm Thought about using an uberjar. Wonder how come there is no "clean" way to say "Just download the deps clj
." The functionality is all there already. :thinking_face: Same with lein
.
You can, e.g., run clj --eval '(println "downloaded!")'
from the base directory in the project

It’s possible that something like clj -Spath
would work as well. You might wanna check that.
(But, again, I recommend against that. I see zero upside to doing that vs building a single binary.)
@ghadi @potetm I want a docker image that starts fast. Preferrably based on clojure:tools-deps
and just using clj
for simplicity. ADD foo.clj
RUN clj -S deps ... --eval '(println "bla")'
and thats it.
Should be as simple as possible. Guess the uberjar won't matter much compared to the situation where everything is downloaded before the container is instantiated.
Possible, but you will still incur overhead for calling clj
as opposed to java
directly
Option 1: Ensure certain commands have been previously executed in an environment (i.e. temporal complection) Option 2: Ship the artifact (i.e. data).
running clj -Sdeps as the CMD
portion of your container will probably never use cached classpath -> thus will not startup quickly
Are there any good libraries / guidelines for managing threads over a load balancer? e.g. if you wanted to split up work, had a redis connection between servers and wanted to split the thread load between nodes. e.g. like what the actor model does in erlang ?
On a server. Let’s say i had 30k stock symbols i wanted to watch and I had 300 servers. I want to have a thread per stock symbol and have on average 100 threads on each server and a monitor to make sure every thread is still alive.
How does one insert a newline char into a str concatenation?
; map destructuring
(defn my-location
[{lat :lat lng :lng}]
(str "The latitude is: " lat ", and "
(newline)
"the longitude is: " lng "."))
(my-location {:lat 22 :lng 81})
; Result I want:
; The latitude is: 22, and
; the longitude is: 81.
;
; Result I get:
; The latitude is: 22, and the longitude is: 81.
(newline)
prints a newline, \newline
is the newline character, and "\n"
is a string with the newline character in it
(defn my-location
[{lat :lat lng :lng}]
(str "The latitude is: " lat ", and "
(newline)
\newline
"\n"
"the longitude is: " lng "."))
(my-location {:lat 22 :lng 81})
produces a value of:
“The latitude is: 22, and \nnthe longitude is: 81.”Instead of a value of:
The latitude is: 22, and
the longitude is: 81.
It's correct as a value, if you want to see the linebreaks you need to println
the result
@johnmi using both \newline
and "\n"
is an odd choice
I was just testing all three at the same time.
Two problems with using println. 1. println produces a side effect instead of a return value.
your complaint was about a behavior - what you saw
the string is correct
clojure doesn't expand newlines in string literals ever, it escapes them
unless you are using a display procedure for side effects
2. only the second println gets returned a a value.
what does that even mean?
So
(defn my-location
[{lat :lat lng :lng}]
(str (println "The latitude is: " lat ", and "
"the longitude is: " lng ".")))
returns a single line:
“The latitude is: 22, and \nthe longitude is: 81.”that returns the string nil
@johnmi perhaps newline
doesn't do what you think it does? It prints out and doesn't add anything to your str
(it returns null that is skipped by str)
I think this conversation belongs in #beginners and there's a misunderstanding of printing to *out*
vs. returning values
thanks, I will move it there, if i need to, after learning about “out” vs returning values.
this might be a useful template for investigation:
(import ( StringWriter))
(let [o (StringWriter.)]
(binding [*out* o]
(println "hi!"))
(str o))
this replaces the *out*
with a temporary io object, then you can separately manipulate your data and the contents of the io objectanything inside the binding block will use the string writer, instead of printing to the terminal
and the str
of a string writer is everything that has been written to it
see in that example, the newline from println becomes a \n
inside a string, in clojure's preferred data representation
@U051SS2EU Thank you. I dont understand all of that but will come back to it.
so, Im writing a block of code that follows this patterns
(let [f' (f)
x' (x f')
; lots of other function calls
y' (y)]
(do-stuff f'
x'
; other stuff
y'))
the problem is that I need to insert log statements
which version is more idiomatic ?
(let [...
users (get-lots-of-users)
_ (log/info "Found " (count users) " users ")
; expect lots of _ (log/...) inside the same let block
] ...)
or
(let [...
users (let [users* (get-lots-of-users)]
(log/info "Found " (count users*) "users ")
users*)
; expect lots of those nested lets inside the same let block
] ...)
I personally use the _ (..)
approach, and feel it is more readable than nested lets. Also, if you're writing a large imperative block of code with multiple exit-points / side-effects / etc., you may be interested in the better-cond
macro: https://github.com/Engelberg/better-cond
log/spy++
I'm a lot more likely to write the first version than the second, but usually only if I'm debugging. If it were code I wanted to keep, I'd probably move (log/info "Found " (count users) " users ")
inside the get-lots-of-users
fn itself.
I would usually do the former for expediency, or often try to move the calculation out into a function, which does the logging there
the latter is much more satisfying as a long-term solution
Aside: using clojure.tools.logging.readable
will likely yield better output when logging a mix of literal text and programmatic values.
thanks everybody for the input, I think Ill move the logging to the inner functions called inside the let block 🙂
Has anyone come up with a poc/bare bones kubernetes operator one can borrow? Asking for a friend. 😉
Are you looking for something usable with Clojure? There are a few (mostly Go) frameworks out there for building k8s operators. Among others: https://github.com/kubernetes-sigs/kubebuilder, https://github.com/operator-framework.
Hunted for a moment and found https://github.com/brosenan/lambda-kube. This is also relatively new and related: https://github.com/nubank/clj-kubernetes-api
Appears this is green field. Colleague will be trying to show off doing it in go. Wondering whether I should dare and try doing the same in Clojure. Appears the fabric8 kubernetes client (used by quarkus) is where one should start.
There's a newer k8s client by nubank that follows a similar pattern to the cognitect aws-api. https://github.com/nubank/k8s-api
(get {(Integer/parseInt "0") :found} (long 0))
is confusing me the more i think about it. But I think I'm really glad it works the way it does
because int vs. long?
((ins)user=> ((juxt (partial apply =) (partial map hash) (partial map type)) [(byte 42) (short 42) (int 42) (long 42) (bigint 42)])
[true 1871679806 1871679806 1871679806 1871679806) (java.lang.Byte java.lang.Short java.lang.Integer java.lang.Long clojure.lang.BigInt)]
• more informative comparisonclojure ensures that things that are = hash to the same value
Yeah, Clojure does not use Java's default hashCode and equals methods for comparing integer/long/byte/short/biginteger types to each other, instead using clojure.core/= and clojure.core/hash, which do extra work to enable those to behave more like math does.
This has a run-time cost over Java's methods, but I don't know off hand of existing benchmark results to quantify that precisely.
If you are interested in the 'what they do' for = and hash, this long-ish article summarizes the behavior at the beginning, before diving into more details: https://clojure.org/guides/equality
If you are interested in how, well I can point you at Clojure and Java implementation code that does it, but not sure whether that interests you.
thanks @U0CMVHBL2 and @U051SS2EU