Fork me on GitHub
#clojure
<
2021-05-17
>
conjunctive00:05:42

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".

borkdude10:05:36

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 (java.io.ByteArrayOutputStream.)]
    (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).
null

jmckitrick17:05:47

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?

hiredman17:05:49

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

hiredman17:05:02

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

hiredman17:05:58

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

hiredman17:05:05

#2 is gross

emccue18:05:16

@jmckitrick Not any more bad form than any other function

emccue18:05:23

uses a multimethod for the copy function and that does IO

emccue18:05:50

ohhhh wait

emccue18:05:02

you mean for the determining the implementation to call

emccue18:05:30

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

emccue18:05:01

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

jmckitrick18:05:12

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.

awb9919:05:34

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.

borkdude19:05:15

@hoertlehner a task runner like the one in babashka can solve this problem (at least it does so for me): https://book.babashka.org/#tasks

awb9919:05:56

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

awb9919:05:12

But if I have no args at all

awb9919:05:18

then it shouldnt matter

awb9919:05:54

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

awb9919:05:04

I guess this would solve my issue also

awb9919:05:37

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

hiredman20:05:24

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

hiredman20:05:59

-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

hiredman20:05:24

-X is launching via the new fn/args mechanism