clojure

New to Clojure? Try the #beginners channel. Official docs: https://clojure.org/ Searchable message archives: https://clojurians-log.clojureverse.org/
conjunctive 2021-05-17T00:35:42.415700Z

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

borkdude 2021-05-17T10:15:36.419700Z

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

borkdude 2021-05-17T10:36:39.420Z

I'll make an issue for it: https://github.com/cognitect/transit-clj/issues/50

borkdude 2021-05-17T11:12:33.420900Z

And another issue: https://github.com/cognitect-labs/test-runner/issues/29 Also provided a solution proposal: https://github.com/cognitect-labs/test-runner/pull/30

jmckitrick 2021-05-17T17:41:47.423200Z

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?

2021-05-17T17:51:49.423900Z

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

2021-05-17T17:53:02.424700Z

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

2021-05-17T17:53:58.425600Z

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

2021-05-17T17:54:05.425800Z

#2 is gross

emccue 2021-05-17T18:05:16.426100Z

@jmckitrick Not any more bad form than any other function

emccue 2021-05-17T18:06:23.427Z

<http://clojure.java.io|clojure.java.io> uses a multimethod for the copy function and that does IO

emccue 2021-05-17T18:06:50.427200Z

ohhhh wait

emccue 2021-05-17T18:07:02.427600Z

you mean for the determining the implementation to call

emccue 2021-05-17T18:08:30.429Z

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

emccue 2021-05-17T18:09:01.429300Z

very curious the usecase though

NoahTheDuke 2021-05-17T18:12:01.431500Z

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

jmckitrick 2021-05-17T18:16:12.433700Z

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.

awb99 2021-05-17T19:02:34.437100Z

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.

borkdude 2021-05-17T19:04:15.437800Z

@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

awb99 2021-05-17T19:05:39.438Z

Thanks!

awb99 2021-05-17T19:05:56.438200Z

Seems like I am not the only one with bad memory

alexmiller 2021-05-17T19:11:49.438700Z

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

awb99 2021-05-17T19:38:04.438800Z

thanks!

awb99 2021-05-17T19:38:12.439Z

But if I have no args at all

awb99 2021-05-17T19:38:18.439200Z

then it shouldnt matter

awb99 2021-05-17T19:38:54.439400Z

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

awb99 2021-05-17T19:39:04.439600Z

I guess this would solve my issue also

awb99 2021-05-17T19:39:37.439800Z

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

2021-05-17T20:09:24.440Z

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

2021-05-17T20:11:59.440200Z

-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

2021-05-17T20:12:24.440400Z

-X is launching via the new fn/args mechanism