Fork me on GitHub

Hi, does anyone know of a nice solution for validating a pre-defined spec (using s/keys) on the metadata of a value? For context, I'm trying to provide s/fdef with an :args argument that says "This value should have metadata conforming to the following spec ::foo".


It seems transit is giving an NPE instead of a meaningful error message when using :handlers and you give it a type it can't handle:

(defn write-transit [v]
  (let [baos (]
    (transit/write (transit/writer baos :json {:handlers {java.time.LocalDateTime ldt-write-handler}}) v)
    (.toString baos "utf-8")))

(write-transit (into-array String ["foo"]))
Syntax error (NullPointerException) compiling at (/tmp/transit.clj:19:1).


This might be a terrible question... but is it bad form to perform any I/O (like db query) in the dispatch fn of a multimethod?


I think the big question is how does the dispatch function get its db connection


in general, a defmulti is a top level form, and the dispatch function only gets the arguments to the defmulti


so either 1. the database connection is an argument to the defmulti, or 2. you have the database connection def'ed somewhere and the dispatch function refers to it


#2 is gross


@jmckitrick Not any more bad form than any other function


uses a multimethod for the copy function and that does IO


ohhhh wait


you mean for the determining the implementation to call


i don't think it is often done, but i still think its neither better or worse than doing IO in a regular function


very curious the usecase though

Noah Bogart18:05:01

it feels like doing a db call in a getter in a C-like language. it's not only messy (where is the db connection coming from?), but hides a potential area of slowdown and side effects by hiding the db call in the defmulti instead of exposing it directly in either the calling location or the defmethod


I thought the value I needed was in the one map I was passing to the multimethod, but now I see it's a different map, from a different query. I could just add the map as an extra arg to the multimethod, but that makes it ugly. But now that I think about it... it actually makes sense. So the simplest solution might be the best.


I have a "stupid" problem with clojure deps. I have a couple of alias defined. Now some I have to call with "clojure -X:alias" and others with "clojure -M:alias". I can remember the names of my aliases (cljfmt, lint, release, test, etc). But I dont remember how I did set them up. I understand the difference, but I dont uderstand why there cannot be just one way to execute an alias. The alias knows if it would use a main function or if it would call the function directly.


@hoertlehner a task runner like the one in babashka can solve this problem (at least it does so for me):


Seems like I am not the only one with bad memory

Alex Miller (Clojure team)19:05:49

as far as why, it's because the arguments are interpreted differently


But if I have no args at all


then it shouldnt matter


is it possible to switth all -M aliases to -X aliases


I guess this would solve my issue also


just some time to look into the namespaces to find the right fucton names I guess


the thing being passed to -M or -X is a argument


-M is launching via clojure.main, sort of the classic launch, it used to be (maybe still is supported but is deprecated) that you got this behavior if you didn't specify a flag at all


-X is launching via the new fn/args mechanism