This page is not created by, affiliated with, or supported by Slack Technologies, Inc.
2020-04-28
Channels
- # announcements (11)
- # aws (2)
- # babashka (35)
- # beginners (173)
- # calva (3)
- # chlorine-clover (2)
- # cider (17)
- # clara (2)
- # clj-kondo (28)
- # cljs-dev (11)
- # cljsrn (53)
- # clojure (178)
- # clojure-argentina (1)
- # clojure-europe (12)
- # clojure-germany (5)
- # clojure-italy (4)
- # clojure-nl (5)
- # clojure-spec (25)
- # clojure-uk (88)
- # clojurescript (109)
- # conjure (34)
- # cursive (2)
- # data-science (35)
- # datomic (15)
- # emacs (6)
- # events (1)
- # fulcro (28)
- # graphql (15)
- # helix (21)
- # hoplon (7)
- # jobs (4)
- # jobs-discuss (1)
- # joker (15)
- # lambdaisland (1)
- # lein-figwheel (4)
- # local-first-clojure (1)
- # malli (8)
- # meander (17)
- # off-topic (33)
- # parinfer (2)
- # rdf (16)
- # re-frame (3)
- # reagent (21)
- # reitit (14)
- # remote-jobs (5)
- # ring (8)
- # rum (1)
- # shadow-cljs (184)
- # sql (2)
- # testing (1)
- # tools-deps (23)
Anyone know of a good drop-in replacement for the standard GraphiQL GUI that parses EDN? I'm sure I could toss something together with ClojureScript, but figured I'd ask.
Is there a more concise way to write this function? (filter #(if (some? (second %)) %) {:foo nil :bar 89})
Better to use some?
instead of not nil?
But, yes, better to use val
than second
when dealing with map entries.
@U010Z4Y1J4Q This really feels like a question that is better suited to the #beginners channel where people have opted-in to help with basic questions like this...
Ah, some?
... I didn't remember it. Yes, this would be cleaner:
(filter (comp some? val) ...)
@U051MHSEK The OP mentioned it in their question.
I misread it as some
and that just shows me what happens if I haven't written Clojure in a while ¯\(ツ)/¯
And another reason why questions like this belong in #beginners rather than #clojure ...
@U010Z4Y1J4Q I've added you (back) to the #beginners channel.
Happy to discuss potential renaming in #community-development but we try to rename channels only very occasionally (since channel names are often documented out in the wild and it's confusing if someone comes here and those documented channels no longer exist).
Basically what I want is to return a map that contains only the key value pairs that are non-nil {:bar 89}. It doesn't have to a list of vectors of key-value pairs ([:bar 89]) as in the result of the above example.
I have this following idiom in my code:
(deftest my-test
(run-test-sync
(is (= 1 2)) ;; etc.
)
And it seems like a good idea to create a macro which would replicate this like so:
(deftest-sync my-test
(is (= 1 2))
)
And I have tried this:
(defmacro deftest-sync [name test]
`(deftest ~name ~(run-test-sync ~test))
)
But on doing :
(macroexpand '(deftest-sync some-test (is (= 1 1))))
I simply get the result:
(deftest-sync some-test (is (= 1 1)))
What am I doing wrong?You unquoted twice, you don't want to unquote the entirety of the run-test-sync
. Should probably be
(defmacro deftest-sync [name test]
`(deftest ~name (run-test-sync ~test)))
(note the missing tilde)Are you sure? I just tried this in the repl:
user=> (defmacro deftest-sync [name test]
#_=> `(deftest ~name (run-test-sync ~test)))
#'user/deftest-sync
user=> (macroexpand '(deftest-sync some-test (is (= 1 1))))
(user/deftest some-test (user/run-test-sync (is (= 1 1))))
But (deftest-sync my-test (is (= 1 1)) (is (= 2 1)) ) evaluates to (deftest nil nil)
can someone explain me the reason having definterface and deftype inside a do in the repl won't work? i have to deal with a macro that generates something like (numbers all gensyms)
(do
(def foo)
(do
(definterface G__49771 (invoke [G__49772]))
(deftype foo49770 []
G__49771
(invoke [_ G__49772]
(let [bar G__49772] bar))))
(let
[G__49769 (new foo49770)]
(defn foo {}
([G__49773]
(.invoke G__49769 G__49773)))))
this dies on the repl at deftype saying,
Syntax error compiling deftype* at (/tmp/form-init6201477943960772507.clj:7:3).
Unable to resolve symbol: G__49771 in this context
it works if i compile/run the code. i can also get it to work manually in the repl if i remove the do
s. how could i get this to work in the repl?if you're using some fancy repl that wraps input commands somehow, that would explain it
i was starting a headless lein repl and connect to it from atom with clojure party repl
Hey friends, I've got a plan to tackle a problem but I'd like to have a better plan, if one exists.
I've got a string, and the string represents clojure code. I need to remove all the line endings from this string, without altering the compiled value of it. It will always be a hashmap, starting with {
and ending with }
.
I would just do (str/replace string #"\n" "")
, but that breaks when the map contains ;comments, and alters the value of string literals
So what I'm thinking of doing is making a loop that loops over each char in the string and removes newlines UNLESS they terminate a ;comment, OR if they're inside a string literal. Ofcourse ;comments don't count if they're in a string literal, and string literals can't start inside a comment.
Is this a good plan? It feels like a not-great plan, but I'm stumped for other options. Thanks!!
Yes, unfortunately. I'm doing some code formatting, and I wasn't able to remove newlines with rerwite-clj
Oh, interesting
You may need to match the comments too, I can't remember if the ast distinguished or not, but it'll make it easier for sure.
Ok, cool.
Well, thanks! I'll give this a try. Also, if anyone happens to know that this Should have actually been easy with rewrite-clj, let me know! It seems to skip whitespace, so far as I can tell
There's definitely some way to get rewrite to do this, but I think parcera is more ergonomic.
thanks a bunch, I had a feeling plan-a wasn't going to be the best
if you have a string with clojure forms in it, consider reading the forms, then prn
ing them to a file, then running a source code formatter on the file
Ah, a code formatter is what I'm trying to do!
Out of curiousity I just too a look at parcera, I'm curious about this line: https://github.com/carocad/parcera/blob/master/src/Clojure.g4#L34 Seems like this will parse odd "inputs" without an issue whereas maps should be key-value pairs, am I right? I don't have experience with antlr.
Luckily in my case I'm not responsible for the correctness of inputs... I just need to not break the code 😁
rewrite-clj will object if you attempt to make a hashmap with an odd number of forms though
Yeah, right. I'm asking especially because I took the tools.reader wrapper path in a current side project especially because I needed something like '{' input* '}'
inside maps and neither tools.reader nor rewrite-clj allowed it.
I overlooked antlr as too complex but looking at parcera I feel like stealing the g4 file would work and allow me to remove 80% of my code...
Expected:
"CREATE TABLE test_table (some_column varchar(255), oth
er_column varchar(255) CONSTRAINT constraint_name UNIQUE KEY (`some_column`,`other_column`))"
Actual:
"CREATE TABLE `test_table` (`some_column` VARCHAR(255),
`other_column` VARCHAR(255)) CONSTRAINT `constraint_name` UNIQUE KEY (`some_column`, `other_column`)"
Folks, i'm trying to add the constraint statement inside the parentheses, intead of have ou of it, as have in expected. Do you folks have any insight of how can i do it?(let [base-sql (str "CONSTRAINT " (ddl/escape-identifier ddl name))
cons-sql (clojure.string/join ", " (map #(ddl/escape-identifier ddl % ) columns))]
(str base-sql " " type " (" cons-sql ")"))
That's the current code i did for it.If it's an option, I'd suggest looking at HugSQL https://www.hugsql.org - it has built in ways of passing identifiers etc
We already use another implementation. Once i'm expanding a existent library, probably not going work on it now. But thanks for the suggestion
(defn join-string
[query specs]
(let [count (-> (count query) (- 1))]
(-> (subs query 0 count)
(str " " specs ")"))))
Found a way to do this. Hope it's not a McGayver solutionusing count to bind something called count is a bit odd
perhaps (let [length (dec (count query))] ...)
or (-> query count dec)
or whatever
is there a nice and friendly way in clojure to convert from scientific notation 1.87E+5 to 187000.0 ? i really want the bigint 187000 .. but any longer version will do
both are different representations of the same number
there are ample formatting options for converting from a number to a string in the jdk
i will check java formatter then
full spec is at https://docs.oracle.com/javase/7/docs/api/java/util/Formatter.html and this is supported in the clojure format
function
user> (Float/parseFloat "1.87E+5")
187000.0
user>
you should typically prefer Double/parseDouble over Float/parseFloat
will check out that Double/parseDouble
same answer .. but what is reason to prefer Double ?
Clojure decimals are always doubles - Clojure doesn't support java floats
gotcha .. good to know
single precision floats are pretty bad, really only useful if you want something where you are ok with bad precision and trying to shave heap memory
whao .. that was far too easy. thanks mate 🙂
there is also a function to make a bigint
user=> (bigint 1.87E+5)
187000N
it's unclear to me what the type of either your input or desired output is
gotcha .. yeah .. i need the bigint .. so that one is nice too .. either way .. i have my answer with 2 good ideas
@abrooks re your question about geo
from a while back, happy to answer any questions you have. i just made a new channel called #gis if that’s a useful place to organize conversations — not sure what else is important to do in terms of channel management, or if it’s better to try to encourage discussion on zulip or another platform instead
development on factual/geo
has been pretty limited recently, though i am trying to get it working with cljs now that bundle support is there. i’ve also been working on and off on willcohen/ovid
and willcohen/aurelius
as libraries that build on top of factual/geo
and try to streamline what i do day-to-day with GIS, though as you can see they’re basically still undocumented and haven’t even hit a first release
Excellent series of videos by Uncle Bob Martin:
They don't belong in #clojure but feel free to post them to #news-and-articles (or #off-topic since they aren't Clojure-related, right?)
Hi. What's a more concise way to call (not zero?)
, this feels too verbose:
(filter (every-pred number? #(not (zero? %)) odd? #(< % 7)) [0 1 0 2 5 9 0 3 0 4 -1 -2 :a {} ])
though I am wondering why (complement zero?)
works in the filter as is and (not zero?)
needs to be wrapped in an anon. function..
complement returns a function, not returns a value
@U11BV7MTK (complement zero?)
wins, there are fewer brackets and therefore it's more readable and less thinking 'wtf had I written a year?' ago : }. thanks
sometimes I wish things like partial, complement, comp all had shorter names
eg. complement could be ~
or even !
@U051SS2EU I wished for the shorter names as well, especially to use in (comp) and settled on (def pa partial)
well you can just def that to something more concise
you shouldn't use =
to check for 0, at least one should use ==
, and zero?
exists for a reason
Quick interop/reflection question: If you have a (Java) object and you know it has a .close
method but it does not have a predictable base class or interface you can use as a type hint, is there a way to call the (unique, no-arg) .close
method without triggering a reflection warning from (set! *warn-on-reflection* true)
?
The concrete situation here is that HikariCP and c3p0 both provide connection pooled datasource objects and both have .close
methods but their datasource types have nothing in common that has a .close
method -- c3p0 has its own PooledDataSource
class that implements .close
(and that in turn extends javax.sql.DataSource
) where HikariCP implements
(which has .close
in it).
I'm happy to do actual runtime reflection to find and call the .close
method, as long as it avoids Clojure's reflection warning (but I'm looking for some guidance on the simplest code to achieve that).
in the past I've used a dispatch to ensure there was only one code-path for each type, eg. you could have a multimethod or protocol where the implementations would look the same except the type hint
it might be overly precious to use a macro for this, if it's not a repeating pattern you could even use cond
The set of possible input classes is actually open-ended in this case.
I have some reflection code that works but it's ugly 🙂
in that case you could use a protocol or multimethod and extend it to each thing, clojure won't complain about runtime protocol dispatch
It probably relates to this: https://archive.clojure.org/design-wiki/display/design/Function%2Boverloading.html
Where they mention the current solutions are multi-methods, protocols or instance? checks
yeah, since this is open and not statically knowable, protocol or multimethod actually fit here IMHO
No, this has to be self-contained and require no extension by users.
So far
(defn- attempt-close
"Given an arbitrary object that almost certainly supports a `.close`
method that takes no arguments and returns `void`, try to find it
and call it."
[obj]
(let [^Class clazz (class obj)
^java.lang.reflect.Method close
(->> (.getMethods clazz)
(filter (fn [^java.lang.reflect.Method m]
(and (= "close" (.getName m))
(empty? (.getParameterTypes m))
(= "void" (.getName (.getReturnType m))))))
(first))]
(when close
(.invoke close obj (object-array [])))))
That avoids reflection warnings from the compiler and calls the first 0-arity .close
method it can find that returns void
.
It's so next.jdbc
can support Stuart Sierra's Component library without needing it as a dependency in a nice, generic way:
(defn component
"Takes the same arguments as `->pool` but returns an entity compatible
with Stuart Sierra's Component: when `com.stuartsierra.component/start`
is called on it, it builds a connection pooled datasource, and returns
an entity that can either be invoked as a function with no arguments
to return that datasource, or can have `com.stuartsierra.component/stop`
called on it to shutdown the datasource (and return a new startable
entity)."
[clazz db-spec]
(with-meta {}
{'com.stuartsierra.component/start
(fn [_]
(let [pool (->pool clazz db-spec)]
(with-meta (fn ^DataSource [] pool)
{'com.stuartsierra.component/stop
(fn [_]
(attempt-close pool)
(component clazz db-spec))})))}))
what about an instance? check that special cases c3p0 (grandfathers it in) and demands all other inputs be http://java.io.Closable ?
(def ds (component/start (next.jdbc.connection/component CPDSClass {:dbtype "..." :dbname "..." ...})))
(next.jdbc/execute! (ds) ["select ..."])
(component/stop ds)
I don't know that you can rely on arbitrary connection pooling libraries implementing
and next.jdbc
cannot introduce a direct dependency on a specific one (such as c3p0).
The joys of writing dependency-free libraries that can behave generically... 🙂
There's something about hidden reflection in a library dependency that seems dirty to me.
Horrible usability.
(although I suppose I could default the close-fn
to (fn [^
and force poor old c3p0 users to override it... not that HIkariCP doesn't also have its own weirdness)
or default it to
I was wrong, it does reflect(memfn close)
which silently reflects
I wouldn't be surprised if there are other things that prevented GraalVM binaries to be produced from next.jdbc
programs already -- Borkdude is working on JDBC support in Babashka and, so far, has only managed to get PostgreSQL supported -- both MySQL and SQLite seem somewhat incompatible with Graal...
@U051SS2EU Oh really? Interesting... let me try that...
((memfn close) pool)
produces a reflection warning @U051SS2EU
yeah - sorry I did edit above
What's the big deal? I mean, if you are doing reflection, why not be explicit about it if the user cares to know.
@U0K064KQV for folks who set reflection warnings on for their whole build, why should they have to suffer my code producing a warning? Folks create GitHub issues about that sort of stuff. No, just no.
@U11BV7MTK That certainly does hide the reflection warning but a) that feels like cheating and b) that's still going to trip anyone who uses Graal, right?
gh issue "this code reflects" response "get rid of reflection by providing this arg / extending this multimethod"
I mean I get it, but I'm not a fan of circumventing the warning either. If I set warn-on-reflection it's because I want to know if reflection is happening anywhere in the code, libraries included
Right, and it's important to me that my library is "clean" in that respect.
Well it seems in line with your intention that you are open to reflection. It’s not a warning it’s intentional
Could graal people use this regardless of the warning? The reflection will kill them not the warning
It's probably irrelevant in this case, so it might be the right trade off, but what if I was calling component in a hot loop? I know what doesn't sound realistic, but I'm just trying to explain why I kind of don't like it if my dependencies secretly try to hide important aspects from me.
actually connecting to a db is so much slower than reflecting on a method though
My personal vote would be, leave the warning, but have a mechanism where the user can get rid of it by say providing the close function or a type hint.
If using java.lang.reflect
kills Graal then it's a non-starter too... which is moving me closer to @U0K064KQV’s suggesting of optionally passing in the close function at this point
(and defaulting it to the
version)
that means you get a runtime crash when the hint doesn't match the impl coming in
Actually, you can use java.lang.reflect, but you need to tell Graal which class needs reflecting over
unless you protect it in a conditional branch with an instance? check I guess
I thought they were hints, because if Clojure compiler doesn't actually find the method on the type it defaulted back to Object?
Though I guess there is the weird case of a connection pooling library that wouldn't have a .close method at all?
(ins)user=> (def hinted #(.close ^.Closeable %))
#'user/hinted
(ins)user=> (defprotocol Distance (close [this]) (far [this]))
Distance
(ins)user=> (hinted (reify Distance (close [this] true)))
Execution error (ClassCastException) at user/hinted (REPL:1).
class user$eval202$reify__203 cannot be cast to class .Closeable (user$eval202$reify__203 is in unnamed module of loader clojure.lang.DynamicClassLoader @50a3d0f6; .Closeable is in module java.base of loader 'bootstrap')
once you hint, the method is specialized on the class, and other methods with the same signature but different class with crash
I discovered this the hard way implementing a setUncaughtExceptionHandler
for a kafka stream (that just happened to accept the same types / args as Thread.setUncaughtExceptionHandler without inheriting Thread)
Yeah, that's an interesting usability question @U051SS2EU...
Thinking about this some more, next.jdbc
uses clojure.java.data
for the connection pooling stuff which is full of explicit Java reflection stuff... So I'm worrying too much about this since ->pool
already depends on the java.lang.reflect
stuff!
So I've gone back to this
(if (isa? clazz .Closeable)
(.close ^.Closeable pool)
(attempt-close pool))
where attempt-close
is the java.lang.reflect
-based thing above.Thank you everyone for your input on this. I guess allowing users to pass in their own close-fn
might also be worthwhile just to deal with connection pooling libraries that don't even have a .close
function...
there's also this if you don't otherwise need to extract the class
(instance? java.lang.CharSequence "hi")
(which becomes Closeable/ pool of course)the rest of clojure is so unbelievably consistent, the difference between isa? and instance? arg order sticks out
Yeah, it caught me out when I tried it half an hour ago -- the way next.jdbc.connection/->pool
works is that it already takes a Class
so I'm using that to provide the default close-fn
before creating the pool instance.
Here's the finished code on next.jdbc
master https://github.com/seancorfield/next-jdbc/commit/66fdba4be9a80a85d5fc75df0a2341820b10fa22
extension via metadata to not depend on the component
lib. Cool!
It all started as yak shaving due to Jacob O'Bryant's announcement of his Component alternative which inspired me to remove a record from a Component at work and then I started thinking about next.jdbc
🙂
I suggested that or multimethod in the thread above, I don't think he liked the idea