This page is not created by, affiliated with, or supported by Slack Technologies, Inc.
2018-12-14
Channels
- # adventofcode (107)
- # aleph (1)
- # announcements (8)
- # beginners (57)
- # boot (3)
- # braveandtrue (18)
- # calva (374)
- # cider (6)
- # cljdoc (8)
- # cljs-dev (140)
- # clojure (199)
- # clojure-berlin (5)
- # clojure-europe (3)
- # clojure-finland (1)
- # clojure-hamburg (4)
- # clojure-italy (17)
- # clojure-nl (16)
- # clojure-spec (2)
- # clojure-uk (70)
- # clojurescript (29)
- # component (2)
- # cursive (10)
- # datomic (44)
- # docker (1)
- # figwheel (3)
- # fulcro (13)
- # immutant (2)
- # juxt (5)
- # leiningen (53)
- # nrepl (3)
- # off-topic (7)
- # pedestal (3)
- # re-frame (7)
- # ring (3)
- # ring-swagger (5)
- # rum (5)
- # shadow-cljs (14)
- # spacemacs (6)
- # specter (12)
- # tools-deps (11)
- # unrepl (11)
- # vim (7)
I have a big non-specific question/topic for which I apologize in advance... I am trying to get my project off my laptop into the cloud, and I'm finding the whole thing daunting... there's kubernetes and all its providers, AWS EC2 and Elastic Beanstalk, just renting a VPS... so many possibilities. Does anyone have suggestions for a workflow for how to develop locally and then deploy into a persistence backed situation without scp'ing jars around (although that's on the table, absolutely, too)... thoughts, suggestions, counseling?
a little late on the ball ... but I think one of the easiest ways to get something online (with postgres) is to use heroku + terraform. Heroku let's you deploy with just a git push, but it's also really easy to the integrate with your CI/CD. Terraform is nice because it's super easy for you to set up a different environment or change to a different provider later. Heroku only really makes sense for smallish projects. It's also completely free to get going (both vm and database)
here's a redacted http://main.tf
I store my terraform state on Amazon S3 (the backend bit), but you don't need that and can store it locally too. All you need to do is set the environment variables and then run terraform apply and you'll have an account created in heroku that you can push a rails + react app too. Just add the heroku git as a remote and off you go.
Deploying to ECS with https://github.com/jpignata/fargate was effortless for me so you could start there. Just add a Dockerfile containing your uberjar and deployment becomes a one-liner.
Depending on your persistence requirements, you can go a long way with localstack, plus perhaps postgres and redis containers in a docker composition to create some parity with your AWS deployment.
yes, postgres currently.
that makes things a bit more complicated, definitely.
that's the direction I've been going in... I was a bit dismayed at how quickly the costs can add up for a hobby project... RDS can be stopped for 7 days and then it automatically wakes up and starts running up a bill.
AWS kills you on traffic, a digitalocean VPS with backups enabled and an attached volume for the database (with some rsync cron jobs) may be good enough (and way cheaper) depending on your case, if you don't mind setting up postgresql yourself and doing some little ops
oh wow, I was already having sticker shock and I hadn't even thought about the traffic.
I'll look at DigitalOcean... great idea.
and they have a new kubernetes thing, which means I could run postgres from a docker container, theoretically. but the whole K8 thing could be a rabbit hole.
sounds good... I'll look at DigitalOcean... the postgres setup will be a learning thing there, but sounds like a solid plan. š
Is there a Clojure core function that splits a list into two lists: 1. items that pass a predicate 2. items that fail the predicate?
has anyone run into a lein repl
error out with Exception in thread "main" java.lang.AssertionError: Assert failed: transport-fn
? It seems to be a result of the latest macos mojave point update
happened to me right after I did the update to macos 10.14.2 today. I've tried java 8 and 11
@langmartin https://github.com/technomancy/leiningen/issues/2497 if youāre in a project you can add the nrepl dep to your profiles.clj, downgrade to lein 2.8.1 via lein upgrade 2.8.1
or git clone master branch and run lein bootstrap
@jayzawrotny thank you! that's it
I noticed that all of the channels here only go back about five days. Are older messages archived somewhere?
@jayzawrotny split-with
(defn separate-dirs-from-files
[files-list]
(reduce (fn [[dirs files] file]
(let [name (.getName file)]
(if (directory? file)
[(conj dirs name) files]
[dirs (conj files name)])))
[]
files-list))
Is there a better way to write that?Haven't run it but...
(defn separate-dirs-from-files
[nodes]
(let [g (group-by directory? nodes)]
[(get g true []) (get g false [])]))
Also, @jayzawrotny split-with
gets you a vector of stuff that succeeds until first failure, and stuff that fails until first success.
It is equivalent to #(vector (take-while % %2) (drop-while % %2))
.
Code was more concise and readable that my description of it š
Thanks for the explanation. That makes sense but the tricky part is getting the name of each node, thatās why I went with reduce, otherwise I would have to map over them again.
Totally mis-read your code. My bad š¶
@UBU6QCSJH all good š thatās why I was hoping to find a better solution as reduce often means having to really study the body to understand it.
Probably wouldnāt be too difficult to write a function that reads each line of an env file, splits it by =
VAR_NAME=VALUE, then populates a map. Then you can design a general function for retrieving data from that map or System/getenv but at this point you probably just reinvented the wheel. This solution may suit your needs though https://stackoverflow.com/questions/32323572/is-there-a-way-to-set-system-properties-in-leinegen
It can be better to use EDN syntax directly in your file and then just use clojure.edn/read-string
can you guys tell me here difference between lein-2.7.1-alpine-onbuild
and lein-2.7.1-alpine
please?
(first
(filter #(do (println %) (even? %))
[1 2 3]))
Due to batching this prints all three entries of the vector ā what's the best way to achieve the same outcome but only print 1 & 2?(reduce #(when (even? %2) (reduced %2))
[]
[1 2 3])
This worksNot sure I fully understand what you mean by not using a lazy-seq, the vector isn't lazy but filter makes it lazy, no?
if you have more complex stuff going on per iteration you can also think about using tranduce + halt-when
interesting, didn't know about halt-when
I forgot that filterv
exists in the stdlib š Are you suggesting that this should work?
(first
(filterv #(do (println %) (even? %))
[1 2 3]))
yeah ok, that's what I'm seeing too
then you need to feed it to something if you use it more than once otherwise you'd get bad surprises
hm, I can't get the eduction to return the value for which the predicate fn returns true
But thanks, I'll take a closer look at that š
halt-when takes an optional second arg fn
That retfn gets both the halt-on val and the pred result
which kind of make sense given the ret value of an eduction, it's not the same purpose
Anyone have a ātransducers for dumb peopleā or similar? Iāve tried a couple times to get it and itās not stuck
I know what you mean and here's some resources that I found really helpful...
Arne Brasseur has some good content at https://lambdaisland.com. It's paid content but in my opinion, well-worth it. Specifically, episodes 38, 42, 43, and 44
There's also some good content from Timothy Baldridge at https://tbaldridge.pivotshare.com/home on transducers; also paid but worth it
Thanks! Iāll check those out!
Good luck!
Also, this article is great for a practical real-world usage https://tech.grammarly.com/blog/building-etl-pipelines-with-clojure
and also Ghadi Shayban's lightning talk at the conj two conjes ago also helped things click for me https://www.youtube.com/watch?v=FjKnlzQfAPc
I watched Rich Hickey's talk at strange loop and got it. Had to then watch Inside Transducers a couple of times to get stateful transducers.
hi I am trying such interesting dynamic dispatch but I have got some interesting compile errors.
(def backend
(case database-backend-keyword
:mysql 'importer.persistence.mysql
'importer.persistence.dummy))
(def insert! backend/insert!)
(def delete! backend/delete!)
'importer.persistence.mysql
and 'importer.persistence.dummy
are namespaces.
Please advise on why does not this work.what do you mean? In a project you can change your Clojure dependency to be a 1.10 version
https://clojure.org/community/downloads The latest dev release is "1.10.0-RC5"
@seancorfield just saw your article on datafy/nav, very helpful and thanks! one thing wasnāt very clear though: how can you tell whether an id in a row or a result set is a foreign key to another table?
please ignore me, Iām reading the source of src/main/clojure/clojure/java/jdbc/datafy.clj
and itās obvious what your plan is š
follow up question: would you recommend this functionality for DB traversal in prod, or is this just a dev tool for now?
REBL is a dev tool and that example of datafy
and nav
is intended for dev -- there's an overhead of datafication and the "dual navigation" of navigation that doesn't, to me, sit well with a production context.
That said, I can sort of imagine datafy
and nav
being used at a different abstraction level to do data traversal. Imagine datafying a PreparedStatement
, for example, and getting back a representation of the SQL data, and then nav
on that could produce a PreparedStatement
to query for related data... Not sure that I'd want to work with data that way but...
thanks, I get your point about cost. I think there are some legitimate use cases that fit well with that kind of traversal, but some well-written sql join would most likely be preferable in most cases
@gganley Leiningen consults a :repl
profile if you define one, and yes you can do it in ~/.lein/profiles.clj
(for reference: https://github.com/technomancy/leiningen/blob/3aad5ec7eb7eb91e9c5beb41aecf097c5d819472/src/leiningen/repl.clj#L363)
this is a bug in lein 2.8.2 that was just released
downgrade to 2.8.1 for the moment
I made an example showing (well, hinting at) the power of bespoke datafy/nav https://github.com/stuarthalloway/reflector
Very nice! A truly small amount of code for something so useful!
@jayzawrotny I think you want group-by and not partition-by
Is it possible for lein's project.clj to look at a config file for certain values, like :version?
Whatās wrong with this macro?
(defmacro uninterrupted [h & tail]
(when h
`(when-not (Thread/interrupted)
~h
~(uninterrupted tail))))
the main thing is that you just can't use a macro in the "runtime" part of the macro definition
this should do it:
(defmacro uninterrupted [h & tail]
(when h
`(when-not (Thread/interrupted)
~h
~(when tail `(uninterrupted ~@tail)))))
Very nice! A truly small amount of code for something so useful!
a bit hacky to fix the return value:
(defmacro uninterrupted [h & tail]
(when h
`(when-not (Thread/interrupted)
~h
~@(when tail [`(uninterrupted ~@tail)]))))
you might want to consider how to handle InterruptedException too - if one of the expressions is blocked on something interruptible, it will throw InterruptedException as well
maybe itās fine to just let that throw, but you could also catch/ignore. generally, you might think about how/whether to give feedback for if interruption occurred
Iām currently only cancelling futures in this piece of code and handling java.util.concurrent.CancellationException
when reading them
Glad to see another Vulfpeck fan in Clojureland, Alex. :the_horns::skin-tone-3:
huh. I never noticed...
user> (:foo (sorted-map "foo" "bar"))
Execution error (ClassCastException) at user/eval36355 (REPL:83).
java.lang.String cannot be cast to clojure.lang.Keyword
user> (contains? (sorted-map "foo" "bar") :foo)
Execution error (ClassCastException) at user/eval36357 (REPL:86).
java.lang.String cannot be cast to clojure.lang.Keyword
@tomjack "foo" and :foo are not the same
oh - it's because sorted-map needs to do sorting! you can't sort :foo into "foo" "bar"
now I get it
That is certainly a bit surprising on the face of it -- but kinda obvious when you think about sorting. I guess you can always use sorted-map-by
with a custom comparator that lets you compare strings and keywords (however you want)...
weāve had a couple tickets on this and behavior has changed in some cases over the last couple releases
the behavior in the example above I looked at in context of 1242 (was originally in there I think, but that ticket was narrowed) - I ultimately decided the get/contains behavior matched Javaās behavior on sorted sets (throws) and thus was correct as is, but I think itās pretty gray
So i've create a hello world project with lein new ___
and then ran lein jar
. After unpacking the jar I see that the testing files are not included. Would anybody know why this is?
test files are usually not included in artifacts
Sorry in advance for the vague-ish question, but if a library has to manage an external connection, is it a general good rule that the library probably needs some sort of logging mechanism (tools.logging as a decent clojure default?) included to allow users of the library to log things relating to errors and such involving that connection? I'm about to release a very small library and not sure if I can get away with skipping a tool.logging dependency. The alternative is probably to add an error handling function to be passed as an argument in the library's connection api right?
is there any sugar for making keywords namespaced in the current ns followed by a suffix, then the key name? E.g., sitting in the foo.accounting
namespace, and want to make a foo.accounting.user/age
keyword?
I need to encode a logic of trying number of times wrapped into catch block. i.e. sending a request that may cause java.net.SocketTimeoutException and trying for 5 times until thereās no exception. Possible without storing results of the request in a atom?
doing something like this, doesnāt look pretty:
(let [resp (atom nil)]
(loop [tries 5]
(try
(reset! resp (http-get url options debug? description))
(catch java.net.SocketTimeoutException ex
(reset! resp nil)))
(when (nil? @resp)
(recur (dec tries)))))
without pulling in a library you can do something like (trampoline (fn f [] (try whatever (catch Exception e f ))))
@alexmiller @hiredman thanks.
when-not
OTOH emits what Iād expect
(macroexpand
'(when-not foo
bar
baz))
;; =>
(if foo nil (do bar baz))
this has to do with where there are do
forms i believe. your swapping of the if and else forms is not equivalent
ah i was thinking clojure had the do block around the else branch. that's other lisps
that test case is not sufficient to disprove what i was thinking but you are correct
Unless thereās some logical property Iām missing here I canāt see how the macroexpansion Iām proposing is incorrect.
i was thinking of in a lisp where there's a do block on the else branch they would not be the same, right?
(if nil
(message "it was true")
(message "it was false")
(message "second block of it was false"))
that's what i was confused about and what your test case there would not highlight i thought
Iām saying if-not
does not need to expand literally into (if (not ,,,) ,,,)
it can just expand into if
with the then and else arms swapped.
(defmacro if-not*
([test then]
`(if ~test
nil
~then))
([test then else]
`(if ~test
~else
~then)))
(require '[clojure.test.check.generators :as tc.gen])
(require '[clojure.test.check.properties :as tc.prop])
(every?
:result
(tc.gen/sample
(tc.prop/for-all [falsey (tc.gen/elements [nil false true])]
(= (if-not falsey :a :b)
(if-not* falsey :a :b)))
1000))
;; => true
i thought more lisps had an implicit do body on the else branch. that was my confusion. it seems to just be emacs lisp
Your alternate macro-expansion of if-not looks correct to me, and would save a call to clojure.core/not.
Although code like that can I think be potentially in-lined if it gets hot in the JVM, depending on a bunch of JVM- and code-specific factors.
Anyway to test that? Iād like to submit a patch but only if itās worthwhile to do so.
criterium is a good tool to force code to be executed enough times to cause it to be JITed, as long as you do not have JIT disabled in the JVM, and then only start measuring the run-time of provided Clojure expressions after that warmup time is complete.
I do not know which expressions would be convincing to do benchmarking on, but maybe you could find some used inside of Clojure's implementation itself, or some widely used Clojure library using https://crossclj.info
Link to criterium project: https://github.com/hugoduncan/criterium
Thanks a ton @U0CMVHBL2! Iāll start my investigation. š
Iām fairly certain this has been filed before and was declined, but I donāt recall the details
I looked, and didnāt find anything. There was a ticket requesting unless that was basically same as when-not and perhaps that is what I was remembering, not sure
I doubt there is a perf difference - the jvm is pretty smart at optimizing these kinds of things.
I donāt really think this is worth doing tbh (not against it, just donāt think itās important)
Hereās what I found: https://gist.github.com/noprompt/9f373fef5b070ee977f28b9daf2fc6ef
Seems like itās marginally faster for the nil
and true
cases. If the patch would be rejected all the same though I wonāt waste anyoneās time submitting a patch. š