This page is not created by, affiliated with, or supported by Slack Technologies, Inc.
2018-01-19
Channels
- # adventofcode (4)
- # beginners (80)
- # boot (4)
- # cbus (2)
- # cider (62)
- # clara (18)
- # cljs-dev (8)
- # cljsrn (10)
- # clojure (139)
- # clojure-brasil (3)
- # clojure-dev (27)
- # clojure-italy (1)
- # clojure-russia (3)
- # clojure-spec (4)
- # clojure-uk (47)
- # clojurescript (102)
- # core-async (10)
- # cursive (7)
- # datomic (71)
- # emacs (32)
- # fulcro (99)
- # funcool (1)
- # hoplon (3)
- # jobs (1)
- # jobs-discuss (6)
- # jobs_rus (2)
- # leiningen (3)
- # luminus (2)
- # lumo (14)
- # mount (7)
- # off-topic (19)
- # re-frame (25)
- # ring-swagger (4)
- # rum (3)
- # shadow-cljs (142)
- # specter (2)
- # sql (16)
- # timbre (1)
- # vim (3)
Are there performance implications (other than startup time) for running applications with the cli as opposed to an uberjar? Is the cli a reasonable way to run a program in production?
how to do deploy a jar? let me count the ways
running in cli as uberjar from shell script. running in tomcat as a war. applogic. hell, could be anything
running as lein run. sky's the limit
Sorry I was unclear. By cli I mean the recently released clojure
and clj
programs and the tools.deps
library https://clojure.org/guides/deps_and_cli
@noonian Yes, we run a number of processes in production by just running clojure.main
and specifying the entry point with all the dependencies available.
We're mostly moving to uberjars these days, primarily for ease of managing the build/deploy process, but we've done source deploys for years,
clj
and clojure
(other than the building of the classpath) nothing more than running java -cp $COMPUTED_CLASSPATH clojure.main my.main
(and works with both source deploys and with uberjars)
if it’s an uber jar then you don’t need clj at all as the classpath is … the jar
clj -Spath
can be used to just print the classpath, suitable for echoing into a file and using directly too
so there are many ways to assemble these pieces
We were using Leiningen to run stuff at first, then we switched to Boot. If clojure
/ clj
had been available, we'd likely have used that.
(now we just use java -jar ...
🙂 )
Yeah, thats how I do it 🙂 I’ve been playing with deps.edn and I’d like to avoid bringing in lein or boot just to build an uberjar. I haven’t found a focused tool that will explode+combine jars to create an uberjar though
clj
is not a build tool -- that's what lein
and boot
are for. Why try to reinvent that?
I’m just experimenting. I’ve been enjoying https://github.com/juxt/mach and I’m exploring using it as the primary build tool for some projects. It makes it very easy to leverage shell commands as well as cljs via lumo/node and supports building incrementally. I am happy to leverage existing tooling but I’d prefer to avoid another file in my project just to specify the jar build. Boot may be the answer here since it has pretty good command-line support (therefore easily invoked from mach) but I haven’t used it enough to know how that will work
someone can help me?
I want filter my arraymap based on your key-value
like this:
I want check if in anyone position had :key
with value "test"
if my input are it
[{:key ["test" "123"]} {:key ["test2" "123"]}]
they will return true
and if my input are
[{:key ["tesasdasdat" "123"]} {:key ["teasdasst2" "123"]}]
my function will return false
how can I do it with filter
?
here's how i approached it: https://gist.github.com/anonymous/c32a2a95101d257728189bafb4bdd86a
@victtorferreiralima with specter it's (selected-any? [ALL :key ALL (pred= "test")] data)
@victtorferreiralima you might checkout the #beginners channel. Here’s one way you could implement that function:
(defn has-key?
"Check if the vector returned by (:key m) has key as an element."
[key m]
(seq
(filter (partial = key) (:key m))))
(seq
(filter (partial has-key? "test")
[{:key ["tesasdasdat" "123"]} {:key ["teasdasst2" "123"]} {:key ["test" "123"]}]))
clj
is not a build tool -- that's what lein
and boot
are for. Why try to reinvent that?
I have a function, which maps a list, then applies a function to it. It is defined as:
(fn [mf af]
(fn [lst]
(apply af (map mf lst))))
now, the arg order can be eithe mf af
or af mf
I'm trying to figure out if I should name the function fam
or fma
argument for fam
-- shows the order of (apply af (map mf lst))
argument for fma
-- we are mappuing first, then we are applying
I realize this sounds pedantic -- but anyone have advice on this ?
[ one point of confusion is that people say "map reduce" all the time, but in clojure, it'd definitel be (reduce rf init (map mf lst)) ]surely you could call that a sequence function, and so it can follow the argument order of every other sequence function, including map
, which it is built upon (collection last)
I don't know what a 'sequence function' is, but my inspiration is: https://en.wikipedia.org/wiki/Function-level_programming so I'm trying to build functions that: * take functions as arguments * returns other functions as arguments
also, under 'sequence function' standards, which order would thsi be? f-apply-map or f-map-apply ?
here is Rich's explanation of the argument order: https://groups.google.com/d/msg/clojure/iyyNyWs53dc/Q_8BtjRthqgJ
that's aside the point but : surely af should take a collection since its parameters are regular enough to be mapped over ? It's very rare that we encounter such a function that makes sense (like the + function)
@sundarj: I think I misunderstood your comment. Is your comment:
"I'm not saying whether it should be f-apply-map or f-map-apply, but I'm saying that instead of (apply af (map mf lst))
it should be (af (map-mf lst))
" ?
There's an abstraction here I want to write. I have no idea what the right way to write it is -- so if you're noticed a flaw that I did not even think of, I'd greatly appreciate you pointing it out.
in Clojure, every sequence function follows a consistent argument order: collection last
i was merely suggesting you keep with that convention, so that it integrates well with the existing standard library
Ah, so instead of
(fn [af mf] (fn [lst ...))
you are suggesting:
(fn [af mf lst] ..)
?
Is your argument:
"instead of a 2-arg function which returns a function that takes an arg, it should be a 3-arg function with list as the third arg" ?
well if you don't want/need it to return a function, that would be my suggestion - if you do, i think it's fine to leave it as-is
it is worth noting that you could easily turn the [af mf lst]
version into the function-returning version by using partial
(fam af mf lst)
-> ((fam af mf) lst)
I think the "extra char used" is shorter than partial
🙂
i find that i get quickly mired in conversions between apply and collections when i start using variadic functions
@carkh @sundarj: if you don't mind, can either of you write the function in the way you consider most 'clojure idiomatic' ? I think I'd learn more from seeing it as how you would write it rather than as a 'patch' vs what I wrote
if you need it to return a function then i would say what you've written is plenty idiomatic
> (defn afunc [mf af lst] (apply af (map mf lst)))
#'ping.cards.sqlite/afunc
> ((partial afunc inc +) [1 2 3])
I think there is no added value to your closure, you're not closing over anything worth closing over
What's the clojure equivalent of
GenericAvroSerde.class
, maybe (class GenericAvroSerde)
?@sundarj Yes, I tried this before and again now... it works, the problem was with some dependency and it's solved now. Thanks!
Say, what's the distinction between (io/file "f")
and (io/as-file "f")
?
@timgilbert as-file is the low-level protocol function for coercing something into a file
scanned through https://funcool.github.io/cuerdas/latest/ but couldn’t find it
@timgilbert io/file is a higher-level op that takes N parts, coerces them all to files, and makes a file out of the result
generally you want io/file
Thanks @alexmiller!
io/file
rocks, it also adds platform specific delimiters to a filename: (io/file “foo” “bar” “baz”) ;;=> “foo/bar/baz”
on linux, “foo\bar\baz”
on windows
well it returns a File, so technically there are no delimiters till you convert the File to a string path
but when you do that, it uses the platform delimiter
Gotcha
really that + the auto coercion so that you can munge together Strings and Files are the two things that make it really useful
nothing to share atm. 1.10.0-alpha2 was actually released today, but really just some initial dev work, nothing worth being interested in yet.
what would be the idiomtic way of this function: (defn bundle [n s] (when (seq s) (cons (apply str (take n s) (bundle n (drop n s)))))
something like this?
(defn bundle [n s]
(->> (partition-all n s)
(map #(apply str %))))
Is the reason 'take' returns a lazy-seq because you might want to lazily take again from 'take'?
is it the case that you can’t :refer-clojure :exclude
set!
and redefine it in your namespace because it’s a special form?
ok, thanks!
any good synonyms? 😄
for reference, it’s possible to find this out programmatically
=> (special-symbol? 'set!)
true
thanks that’s useful!
@U050AACJB perhaps assign!
?
it’s actually wrapping some interop, the previous name is set-field!
but I think it’s a bit too lengthy
perhaps fset!
?
yeah, maybe it’s not too bad
mutate!
I’m going for fset!
, thanks 🙂
Hi, I am looking for a idiomatic solution for retry and reset. Something like com.grammarly/perseverance
or robert/bruce
or listora/again
with an extra kick. I have an I/O depending on a connection maintained in atom
which might fail and needs to be reestablished. However non of those libraries with awesome semantics otherwise does not let me have an extra "callback" to make it happen ... I wonder if a solution for my problem already exists ...
@happy.lisper is there any state in the connection? eg. when you read are you assuming a position in the input? or is the connection something stateless that’s always usable if it’s open?
@happy.lisper often it makes sense to isolate code that deals with the connection and its IO semantics from the code that is determining what to read and write. This is easiest to do via a pair of queues (for input and output) - then you have one thread which uses the queues and manages the connection and reads/writes, and the other code can ignore all that stuff
In my case, it is a DB connection I perform a mutable operations. It sometimes goes bad and I do not know until I do perform I/O on it. Then retry has to happen including reestablishing connection itself.
OK, if you isolate the IO from the rest of your code, it’s just a question of tracking pending / attempted / completed messages, and if some problem happens it should just be a question of separating completed from attempted and redoing the attempted, then starting on pending - by using a queue you only need this restart logic in one place, instead of needing it in everything that provides data
yes, and I was wondering if somebody captured that pattern in a library, similar to com.grammarly/perseverance
or robert/bruce
or listora/again
...
it’s not an error, as long as you use clojure.main to launch your code
if you want java to find a main class other than clojure.main, you need to establish something to be aot compiled
@happy.lisper that sounds pretty much exactly what people use connection pool libraries for
https://commons.apache.org/proper/commons-pool/ is a more generic kind of interface
it is not really a pool, as I deal only have one connection which occasionally goes bad. I think I will redirect my inquiry to aforementioned lib owners ... thx for taking a look
a pool isn't just about managing multiple of thing, it is also about reusing that something
one way to deal with your issue would be to create a new connection every time you do something, so you put open and close logic around every use
but creating a new connection each time can have downsides as well, so you keep the open/close logic around each use and replace it with taking and returning the connection from a pool, and each time you take the object from the pool, you can check if it is still good
but they do not deal with an automatic reconnect and retry on a specific failed operation
cool! I was thinking mapv, but https://clojuredocs.org/clojure.core/run%21 is definitely better
I added run! as a "See also" for map on clojuredocs. It wasn't already there.