This page is not created by, affiliated with, or supported by Slack Technologies, Inc.
2019-02-01
Channels
- # aleph (1)
- # announcements (2)
- # aws (3)
- # bangalore-clj (1)
- # beginners (136)
- # boot (3)
- # calva (89)
- # cider (44)
- # cljdoc (1)
- # cljs-dev (31)
- # clojure (101)
- # clojure-europe (3)
- # clojure-italy (52)
- # clojure-nl (7)
- # clojure-spec (12)
- # clojure-uk (34)
- # clojurescript (62)
- # community-development (46)
- # cursive (25)
- # datomic (6)
- # duct (26)
- # events (6)
- # figwheel-main (4)
- # fulcro (25)
- # graphql (2)
- # jackdaw (4)
- # jukebox (3)
- # kaocha (57)
- # leiningen (31)
- # off-topic (3)
- # onyx (4)
- # other-languages (22)
- # pathom (18)
- # re-frame (9)
- # reitit (3)
- # shadow-cljs (60)
- # spacemacs (9)
- # speculative (22)
- # sql (39)
- # tools-deps (45)
- # vim (37)
Does anyone know of any places in the DC area that use clojure? I'm enjoying learning the language but am not sure if there are really career prospects for someone who has never had a dev job before.
#jobs or #remote-jobs may have leads but my previous and current employers were and are based in DC and use clojure. I am dimly aware of a couple of consultancies in the area that do a good bit of clojure as well. It’s probably not as easy to find an entry-level clojure job as other langs, but it is possible.
Yeah, we're a full clojure shop in Baltimore and I know some other shops that dabble in it. They're around.
Just nice to know it exists. Thanks! I'm going to keep plodding away and set the goal to get there someday.
😞 just wasted half an hour to figure out that pre-conditions have to come before the docstring
A linter like eastwood can be helpful catching that kind of thing (it is a super common thing to do)
There have even been a function or two inside of Clojure's implementation itself that had the doc string in the wrong place (now fixed, I believe)
hey folks, i trying to understand the code below which is a part of clojure fn
implementation. But till now no success. can anyone help please.
body (if post
`((let [~'% ~(if (< 1 (count body)) ===> ~'% resolve to %. so % is a local var name? ~(if (< 1 (count body)) = (if (< 1 (~count ~body)) ?
`(do ~@body) ===> (do (list body) ?
(first body))]
~@(map (fn* [c] `(assert ~c)) post) ===> (list map (fn* [c] (assert ~c)) post) ? what is being done here?
~'%)) ===> % ?
body)
Fns have a more complicated syntax then is usually used, and that is a complicated hand rolled parser for it
post conditions have access to the result of the function bound to '%' which is what is being setup there, ~'% doesn't resolve to %, but it splices the symbol % into the syntax quote surrounding it (if you don't splice a symbol in like that syntax quote will namespace qualify it, and namespace qualified symbols cannot be used for locals)
you seem to have a hard time keeping quotations straight, so I would suggest investing time in that
~@(map (fn* [c] `(assert ~c)) post)
can you tell me what this line is for? cause actually what is being return is ~'%
the map results in a seq like ((assert ...) (assert ...)) where ... is filled in by one item from post
in macros, you are constructing a form in some meta language to be interpreted in a language, in this case both the meta language and the language are clojure
a syntax quote is a templated version of a quote, meaning a mostly literal bit of the language, but you can fill bits in from the meta language
Is it poor etiquette to bump this? I’m still fighting with this a bit and starting to feel like I’m going around in circles
I went with https://github.com/cognitect-labs/aws-api for my SQS work. It works very well.
Beyond even this, I would suggest that actually working with the basic Java AWS library is relatively straightforward with interop. I mostly just do that these days. The Java library is well maintained, complete and consistent. Wrapping Java interop calls in simple clojure functions works really nicely and also doesn't isolate you from the details too much.
Thanks both - this is really useful. When I looked at the Java library, it didn’t have anything for mocking (or something similar) out of the box. Did I miss something? I’m currently looking at https://github.com/localstack/localstack for manual testing
I'm learning by solving Project Euler problems. For the Problem 2 I've come up with smth like:
(defn sum-even-fibs-upto [n]
(let [fib-seq (lazy-cat [0 1] (map + (rest fib-seq) fib-seq))]
(apply + (filter even? (take-while #(< % n) fib-seq)))))
It probably is not the most efficient, but my question is - can somebody show me an example how it can be re-written with a transducer?@sy_borg I would probably do it like this.
(defn fib
([] (fib 1 1))
([a b] (lazy-seq (cons a (fib b (+ a b))))))
(defn fib-even-sum-up-to [n]
(transduce (comp (take-while #(< % n)) (filter even?)) + (fib)))
Transduce is essentially transform and reduce, your transformation is (->> fib-seq (take-while #(< % n)) (filter even?))
and your reduce is +
I'm trying to wrap my head around this example
(reduce (fn [new-map [key val]]
(assoc new-map key (inc val)))
{}
{:max 30 :min 10})
; => {:max 31, :min 11}
I think it's the destructuring part in the anonymous function that gets me. So it seems we are feeding it one map but the variables are calling for new-map
and then destructuring that same map into key
and value
?when the map gets passed into the reduce function, entries are passed as MapEntry which looks like this [:key val]
oops sorry @christian.gonzalez
haha no problem xP
yup, and the reason you don’t destructure new-map is because the init value is {}
and every subsequent new-map is an entire map, where the [key val] is just a chunk of the {:max 30 :min 10} you are passing in
it probably helps to print out in the anonymous function
you can just add a println inside the fn
(before the assoc, so you don't change the return value)
(reduce (fn [new-map map-entry]
(let [[key val] map-entry]
(println new-map)
(println map-entry)
(println key val)
(assoc new-map key (inc val))))
{}
{:max 30 :min 10})
you could also destructure in a let binding to see the map entry before it gets changed
i have a bunch of misunderstandings about exceptions and logging: i set the default uncaught exception handler as per https://stuartsierra.com/2015/05/27/clojure-uncaught-exceptionsf
user> (Thread/setDefaultUncaughtExceptionHandler
(reify Thread$UncaughtExceptionHandler
(uncaughtException [_ thread ex]
(println "dummy text"))))
nil
user> (/ 1 0)
java.lang.ArithmeticException: Divide by zero ;; plus i get the whole stacktrace
;; i incorrectly expected it to print "dummy text"
- i would think "uncaught exceptions" are any exceptions not (try ... (catch)
'd . but it looks like the above is actually Thread/setDefaultUncaughtExceptionHandlerThatsOffTheMainThread
.
- i'm trying to understand this because i actually want extra information whenever i get an exception in production. i'd like to log the bindings in the lexical environment. i found taoensso.timbre/get-env, which does what i want, but i can't get main-thread exceptions to show up there without an explicit (log/error stuff).
- i want what i consider uncaught exceptions to go to timbre, but i don't know what i don't knowoften the most succinct thing is to pprint a hash-map (clojure.pprint/pprint {:new-map new-map :map-entry map-entry :key key :val val})
@mfm by the time the exception is thrown, the lexical environment is ready to be garbage collected - in fact much of it can be collected before it even exits (and clojure does so, it's called locals clearing)- you can throw ex-info
in a catch clause in order to provide a hash-map with extra data, and test for that in your handler, but it's a fundamental problem
very interesting. thank you. dumb question: how do you know this? that is, where can i look up more info?
I've frequently ended up in slightly awkward nesting of code (or using a delay defined in one let block, then forced inside a try, so that the value if any can be used in a catch) - these things are awkward, they conflict with the semantic model of bindings that clojure is trying to create
I've picked it up by following discussions around bugs and debugging tools, I don't know a good reference outside the clojure code itself
clojure's jira and changelog would also likely be enlightening
yeah - often when running a proper debugger you need to increase resource usage by turning off locals clearing
and it can fundamentally break some code (eg. using a very long lazy-seq and now you are holding the head...)
depends, how much ram can you afford
this is highly variable, it really depends on how much of your code is implicitly relying on locals clearing - you could try locally and see what happens to resource usage?
but it might be more straightforward to rearrange things so that local events and values that matter enough are logged or made available in an ex-info object
small question: what is the main thread exception handler? and how to i modify it? for use in timbre
there's a defaultExceptionHandler on java.lang.Thread - that's used if the current thread doesn't have a default set - I might be misremembering that name, it's long and awkward
there's also a property on each thread that holds a handler
ok cool i'll look at that. the answer might be: "by default timbre does capture the main-thread-exceptions" and i have misconfigured something
you can access the current thread in order to set it's handler with (Thread/currentThread)
I don''t think this has anything to do with Timbre, I'd be mad if Timbre was going and changing my uncaught exception handlers without me explicitly making it do so
for example in my app we want to hit a rest api to make a pagerduty alert -that's not Timbre's job, we also log in the same handler, but that's separate
in an app that's critical enough, you might even ask the whole vm to shut down if certain unexpected conditions are hit (that's safer than running in unknown bad state)
I’ve wonder if that’s something that a component/system framework could help with (similar in vein to integrant/etc.)
like if you have this thing starting and defining your internal deps/resources, I wonder if that’s the correct point in the system to take control of things like exceptions and recovery as well
@lilactown the difference for my usage is that the default uncaught exception handler and recovery logic aren't stateful - they are an idempotent setting that I can safely do each time -main is invoked
I guess they do rely on config (loading up proper logging settings and knowing which endpoint to hit with info about emergency states), but that's similarly not a stateful thing per se, they are loaded up on startup and idempotent
(by idempotent I of course mean that loading my configs twice gives me the same result as loading once, so it's safe to just do every time -main is launched)
as opposed to what integrant and friends are for, where you don't want N db connection pools sitting around, and you can't own the same port with two server instances
in my first app using component, the configs were a component
in retrospect that just increased complexity
I think it's becuase integrant and friends are for a specific task, and that task isn't "startup", it's "managing stateful resources"
e.g. I could imagine a framework that would allow you to “load” a system, and subsequent “loads” would only restart resources that needed to change
e.g. I updated my route handler so I need to restart my webserver, but no need to restart my db pool.
maybe I just need to create an example framework 😄 I think the comparison with component/integrant is bad, you’re right
I'm not saying it's a bad comparison, but my experiences structuring an app with component led me to differentiating things that are idempotent (safe to simply run on every restart) vs. things that use or define fragile state (that requires careful startup order, and specific shutdown steps)
FWIW I don’t appreciate component or integrant as much as others due to the way it warps your app like you’re saying 😛
Good morning gentlemen! I have a query (str "SELECT " fields " FROM interviews WHERE _id IN (" interview-ids ")")
. I have a list of interviews ids and I want to select certain fields from those interviews. Is this the best way I can do it?
I wouldn't use str to create a query
if you use the ?
syntax in the string, and provide the substitutions via extra args in the query vector, you get a much safer parameterized query, which prevents injection
if you just use str, anything in the fields
or interview-ids
strings could be an unintended sql command, or even an exploit if you use any user provided data
"select a_field from foo where val > ?"
then you provide an actual number, rather than putting a number into the string
@mario.cordova.862 what library are you using to do your sql query?
that looks like just clojure.java.jdbc
http://clojure-doc.org/articles/ecosystem/java_jdbc/home.html#querying-the-database - examples of parameterized queries here
Perfect! But aside from the parameterized query is the query itself fine? Is there a better way to structure this query?
if you do need to use string concatenation for some things (where the query can't be parameterized in the way you need), at least separate the parameters from the query construction, and if possible have query construction be static and verifiable
that looks like reasonable sql, but I don't know your db and schema of course :D
and these questions about query construction vs. parameterization is why people end up using higher level libs that abstract over clojure.java.jdbc (eg. hugsql, honeysql which is provided by the clojure.java.jdbc devs, etc.)
After refactoring I have
["SELECT ? FROM interviews WHERE _id IN (?)" fields interview-ids]
but this is not return anything. Using the same values for fields and interview-ids when I run (str "SELECT " fields " FROM interviews WHERE _id IN (" interview-ids ")")
using (sql/query url [query])
it works.
JDBC requires a separate ?
placeholder for each value -- it doesn't automatically expand collections.
So you'd need SELECT ?,?,?,... FROM interviews WHERE _id IN (?,?)
for however many fields
and interview-ids
you have.
(and I'm not sure that JDBC accepts ?
for column names anyway?)
(str/join "," (repeat (count interview-ids) "?")))
So you end up with something like (into [(str "SELECT " fields " FROM interviews WHERE _id IN (" (str/join "," (repeat (count interview-ids))) ")"] interview-ids)
(assuming interview-ids
is a collection of IDs, not a comma-delimited string!)
You're still creating a parameterized query.
The above would produce (for interview-ids
being [123 456]
) ["SELECT ... IN (?,?)" 123 456]
This is why a lot of people use things like HoneySQL since it handles this for you.
Okay got it. And yea we probably should have used that. Maybe we can refactor and integrate into our project.
Anyone know a good clojure image->text library?
I bet @gigasquid knows