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

Helins 2021-05-17T07:11:34.417100Z

@alexmiller I am currently working on Convex Lisp (https://convex.world) and equality is defined in a strict way (different types are not equivalent). It is both an implementation detail and for the sake of being more explicit. I am not by all means complaining about Clojure here. No solution is perfect, it was a good decision to lean on something that was convenient for a majority of use cases. In my use case, it is extremely convenient to use Clojure for working on Convex Lisp, both are identical in many aspects. This is just one example where I encountered a hiccup because semantics were different and I am trying to find a good enough solution without re-inventing the wheel. Besides that particular point, there is a 1-to-1 mapping in collections and I really would like to keep it that way.

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