This page is not created by, affiliated with, or supported by Slack Technologies, Inc.
2021-09-27
Channels
- # announcements (2)
- # asami (25)
- # babashka (124)
- # beginners (46)
- # calva (55)
- # cljdoc (70)
- # clojure (68)
- # clojure-australia (2)
- # clojure-dev (63)
- # clojure-europe (38)
- # clojure-nl (1)
- # clojure-spec (1)
- # clojure-uk (8)
- # clojurescript (56)
- # community-development (4)
- # conjure (1)
- # copenhagen-clojurians (1)
- # core-async (1)
- # cursive (3)
- # datahike (5)
- # datomic (183)
- # depstar (2)
- # figwheel-main (10)
- # fulcro (20)
- # honeysql (2)
- # hyperfiddle (1)
- # integrant (68)
- # jobs (6)
- # jobs-discuss (5)
- # juxt (1)
- # malli (13)
- # off-topic (8)
- # pathom (2)
- # rdf (10)
- # reagent (11)
- # remote-jobs (1)
- # rum (1)
- # shadow-cljs (69)
- # spacemacs (1)
- # sql (5)
- # tools-build (51)
- # tools-deps (6)
- # xtdb (24)
Other topic, I just realized its a bit annoying how if an exception is wrapped, you can no longer catch on the type of the original exception. It means that you can't attach more information to an existing exception and have the callers catch on those. I've noticed this, because sometimes I wrap something in ex-info to add more details, but then you need to catch the clojure.lang.ExceptionInfo instead. I don't know if anyone has a trick for that too?
We came with a way to deal with this at work https://github.com/exoscale/ex we basically use ex-data.type to specify what the ex represents and use an internal hierarchy to allow doing try/catch on it that s aware of that hierarchy.
And since you have a hierarchy representing your error "types" you can use it in other contexts than try/catch, ex with multimethods (like for rendering the error to the user, reporting, logging)
Hum, nice, ya I considered a custom try/catch, but I've been hoping to get around it, since I'm writing a lib, and I feel its weird to ask people to now use a custom try/catch as well.
It's very simple and also fully compatible with the default try/catch/finally, you can mix patterns. But yes it forces you to use that (or the associated functions)
I decided to go with a registry, so I have a ex-details function, and people can call that on a thrown error and it'll return the map of details attached with it.
Catching throwable is considered bad practice. Arguably it's ok if you're careful but it's easy to get into doggy situations
I'm in the same boat, catching all most of the time. The thing is, what I tend to need to express is 'if this operation fails', and not 'if this operation fails in this specific way'. Some of the time I may not even be fully aware of all the failure modes, all I know is that the operation is risky (like, involves IO) and I need to recover somehow.
What is key is being able to properly scope the try
to only cover the operation in question. This is notoriously hard and I cannot recommend rufoa/try-let enough.
> Catching throwable is considered bad practice. Arguably it's ok if you're careful but it's easy to get into doggy situations That's why I put a š on it. And I would advise people, in general, not to do it. But it sums up my feelings about Java's whole checked exceptions nonsense š
Is there a way to run proxy at runtime, where I get the name of the class dynamically?
I want to do something like:
(defn ->ex-data
[ex data]
(proxy [ex clojure.lang.IExceptionInfo] []
(getData [] data))
To create a child of the type of ex that also implements IExceptionInfoOk, its possible if you use get-proxy-class with construct-proxy and init-proxy like so:
(defn ->ex-data
[ex data]
(-> (get-proxy-class (class ex) clojure.lang.IExceptionInfo)
(as-> px (if (ex-message ex) (construct-proxy px (ex-message ex)) (construct-proxy px)))
(init-proxy {"getData" (fn [_this] data)})
(.initCause ex)))
I'm really just trying to decorate an exception, with a map of data, but such that it retain its original type.
What I have isn't robust though, because I can't easily figure out the correct way to recreate a new child instance.
I'm tempted to use a WeakHashMap instead. Has anyone used that before, if I have a WeakHashMap of object -> data, it should let me attach arbitrary additional data to specific instances of an object in a GC safe way correct? Where as soon as the object gets GCed the entry in the map will too and thus its associated data. And the map will not prevent the object from being GCed right?
Good morning, I use next-jdbc for interfacing with db and I have been trying to learn how to test the db, and looking at the: https://github.com/Bigsy/pg-embedded-clj. I wonder if anyone else is using it? Does it make sense to use or or is there a pitfall?
That's what next.jdbc
itself uses in its own test suite @timofey.sitnikov
@U04V70XH6, ahhh, thank you.
@timofey.sitnikov I've been using this one: https://github.com/babashka/babashka-sql-pods/blob/5792dd29cfd68ad0605d3ed859db5212323fa307/test/pod/babashka/postgresql_test.clj#L6
A sorted set cannot have multiple values that compare equally. Is there a data structure that permits that?
Ooo, interesting! It looks like it may work. It seems like most implementation for this are targeted towards the usual queue use case of pop/peek. I'm after the same ops a sorted set provides: (r)?(sub)?seq.
Is there a specific noun for an implementation of a sorted bag/multiset where it behaves exactly the same as a set (values unique by hash), and the sort allows for values to compare identically?
Just to be clear - you have values, for which
(= a b)
=> true
(= (hash a) (hash b))
=> false
Is that right?You could use a sorted map where the values are vectors of the entries that compare identically
No, sorry for the confusion. I'm specifically after a sorted set impl that allows for items that compare identical (i.e., comparator returns 0), but set semantics are based on the value. e.g., the following would returns a set of 3 items
(sorted-set-by #(compare (:k %1) (:k %2))
{:k 0
:v "a"}
{:k 1
:v "b"}
{:k 0
:v "c"})
=> #{{:k 0, :v "a"} {:k 1, :v "b"}}
> Note that the ordering maintained by a set (whether or not an explicit comparator is provided) must beĀ consistent with equalsĀ if it is to correctly implement theĀ `Set`Ā interface. (SeeĀ `Comparable`Ā orĀ `Comparator`Ā for a precise definition ofĀ consistent with equals.) This is so because theĀ `Set`Ā interface is defined in terms of theĀ `equals`Ā operation, but aĀ `TreeSet`Ā instance performs all element comparisons using itsĀ `compareTo`Ā (orĀ `compare`) method, so two elements that are deemed equal by this method are, from the standpoint of the set, equal. The behavior of a setĀ isĀ well-defined even if its ordering is inconsistent with equals; it just fails to obey the general contract of theĀ `Set`Ā interface.
(defn create [key-fn]
{::key-fn key-fn
::order (sorted-set)
::values #{}
::values-by-key {}})
(defn insert [ss value]
{::key-fn (::key-fn ss)
::order (conj (::order ss) ((::key-fn ss) value))
::values (conj (::values ss) value)
::values-by-key (update (::values-by-key ss) ((::key-fn ss) value) conj value)})
(-> (create :a)
(insert {:a 1})
(insert {:a 2}))
=> #:example.sorted-set{:key-fn :a, :order #{1 2}, :values #{{:a 1} {:a 2}}, :values-by-key {1 ({:a 1}), 2 ({:a 2})}}
(defn contains [ss value]
(contains? (::values ss) value))
(defn as-seq [ss]
(mapcat (::values-by-key ss) (::order ss)))
(as-seq (-> (create :a)
(insert {:a 1})
(insert {:a 1 :b 3})
(insert {:a 2})))
=> ({:a 1, :b 3} {:a 1} {:a 2})
(-> (create :a)
(insert {:a 1})
(insert {:a 1 :b 3})
(insert {:a 2}))
#:example.sorted-set{:key-fn :a,
:order #{1 2},
:values #{{:a 1} {:a 2} {:a 1, :b 3}},
:values-by-key {1 ({:a 1, :b 3} {:a 1}), 2 ({:a 2})}}
That's a great find @U3JH98J4R. I was looking for exactly that javadoc. It makes sense that it does not fit Java's Set. Thank you. Also, the snippet does look like it covers the use case! I'm thinking about extracting this into a small lib that works just like a sorted-set.
Thinking about calling this thing a SortedMultiset, but not sure if that is accurate given it's a bit at odds with the definition of Multiset.
This would be a sorted multiset with multiplicity capped at 1 and value equivalence defined by Set.
if random classes are not considered simple, my instinct would be to check for the simple types explicitly
(import (clojure.lang Keyword
Symbol)
java.util.regex.Pattern)
(defmulti simple? type)
(defmethod simple? :default [_]
false)
(defmethod simple? nil [_]
true)
(defmethod simple? Number [_]
true)
(defmethod simple? Keyword [_]
true)
(defmethod simple? Symbol [_]
true)
(defmethod simple? CharSequence [_]
true)
(defmethod simple? Pattern [_]
true)
some examples
% clj
Clojure 1.10.2
user=> clojure.pprint
Syntax error (ClassNotFoundException) compiling at (REPL:0:0).
clojure.pprint
user=> (require clojure.pprint)
Syntax error (ClassNotFoundException) compiling at (REPL:1:1).
clojure.pprint
user=> (require 'clojure.pprint)
nil
user=>
clojure.pprint/pprint
when in another namespace
I'd like to run my test suite (or a subset of my test suite) and get a flame graph of the code that is run (to see which parts are slowest/where the most time is spent). Is that possible?
you could use https://github.com/clojure-goes-fast/clj-async-profiler
I'll check that out. Idk how I missed it
Docker question -- the official clojure:latest
Docker image has boot, tools.deps, and lein installed. It is a bullseye
image. However, none of the static tagged images seem to have all 3 toolsets available. There are currently 902 images so I may have missed something. Is there a tag that I could pin, preferably with openjdk-11 installed, that has all 3 toolsets pre-installed? Can make a custom image I guess if this stumps or bores everyone.
I tried clojure:bullseye
, and it just has lein
installed.
@U0E2268BY Iām curious why you need all of them :thinking_face:
Don't need boot, there is a project that builds java classes with lein and also uses tools.deps, could change it I guess.
the clojure:latest
image does have all three
was wondering how/why that was without explicit tagging on it