clojure

New to Clojure? Try the #beginners channel. Official docs: https://clojure.org/ Searchable message archives: https://clojurians-log.clojureverse.org/
Ben Sless 2021-05-18T08:28:12.001300Z

What's the reason loop forms inside let bindings get compiled to a function + instantiation + call? Can't they be inlined?

2021-05-18T13:04:26.003700Z

wouldn't that mean reimplmenting binding, destructuring, etc.? as it is currently recur inside a function acts identically to a loop with the same binding list, in order to preserve that you'd need two different implementations agreeing on that behavior

grzm 2021-05-18T13:59:47.005200Z

With clojure.tools.logging, can the clojure.tools.logging.impl/disabled-logger-factory be set via a Java system property (e.g., -Dclojure.tools.logging.factory=clojure.tools.logging.impl/disabled-logger-factory, per https://github.com/clojure/tools.logging/#selecting-a-logging-implementation)? It doesn’t look like it from some noodling, but perhaps I’m doing it wrong.

2021-05-18T14:07:48.005300Z

it asks for a function should return a logger factory when called with no args, you are providing the logger factory itself

2021-05-18T14:08:50.005500Z

try replacing clojure.tools.logging.impl/disabled-logger-factory with (constantly clojure.tools.logging.impl/disabled-logger-factory)

2021-05-18T14:09:32.005900Z

that's a very weird API in a very java way, asking for a thunk that returns a factory

2021-05-18T14:10:42.006100Z

I figured this out from your error: it tried to call the factory (created via reify which means the message printed is a bit obfuscated) as if it were a function. the docs you linked to specify that it wants a function as well.

grzm 2021-05-18T14:11:41.006300Z

cheers. I was thrown by the name: the example in the docs uses -Dclojure.tools.logging.factory=clojure.tools.logging.impl/slf4j-factory, which indeed is a function with no args that returns a logger. As you rightly point out, disabled-logger-factory is not.

grzm 2021-05-18T14:44:52.006500Z

I’m getting a dependency error. Could not resolve namespace for "user/my-logger-factory". Either it does not exist or it has a (circular) dependency on clojure.tools.logging. I appreciate the help. I’m just placing this here in case someone else tries something naïve like this and assumes that what I did worked.

2021-05-18T14:52:00.006700Z

does it change if you add an ns declaration to the file? seems like this lib is doing some black magic with namespaces

2021-05-18T14:55:03.006900Z

also I see that you are still misconfiguring the logger in the quiet-log function by providing a factory instead of a function returning a factory

grzm 2021-05-18T15:07:01.007100Z

I think the binding in quiet-log is correct: (a) it’s working, and (b) *logger-factory* is an instance satisfying clojure.tools.logging.impl/LoggerFactory not a function.

grzm 2021-05-18T15:10:12.007300Z

I did get this working by adding a namespace.

grzm 2021-05-18T15:55:13.007500Z

Yeah, doesn’t seem to work if the factory is in the same namespace:

Ben Sless 2021-05-18T16:48:10.009300Z

Today I realized eductions can be used to serialize directly to json

(defn iterduction
  [xf coll]
  (.iterator ^Iterable (->Eduction xf coll)))
Jackson ObjectMapper can take an iterator

hlship 2021-05-18T20:42:40.022100Z

I'm finally getting started using deps and I have a question: when invoking clj to start a REPL, is there a hook or configuration to invoke an arbitrary function as part of setup. In my case, I'd like to have a :pretty alias that adds Pretty to the classpath, and invokes io.aviso.repl/install-pretty-exceptions before the REPL starts accepting user input.

hlship 2021-05-18T20:53:32.022200Z

{:aliases {:pretty {:extra-deps {io.aviso/pretty {:mvn/version "1.1"}} :exec-fn clojure.main/repl :exec-args {:init io.aviso.repl/install-pretty-exceptions}}}

hlship 2021-05-18T20:54:23.022400Z

... is close, but fails (because clojure.main/repl is a varargs function). Also, what if I want multiple init functions? Is there an alternate repl starter for deps that supports this?

borkdude 2021-05-18T21:00:31.022800Z

@hlship -X only accepts functions that has a map argument (or in clojure 1.11 a keys-destructured args list)

alexmiller 2021-05-18T21:03:55.023500Z

you might find https://insideclojure.org/2020/02/11/custom-repl/ interesting

alexmiller 2021-05-18T21:04:37.023800Z

in the last part of that, you don't need the commas anymore, you can just use normal spaces

Adam Kalisz 2021-05-18T21:06:58.025200Z

@hiredman @ptaoussanis I have closed the issue and submitted a PR (linked in the issue comment): https://github.com/ptaoussanis/sente/issues/389 this seems to enable a workaround for us.

borkdude 2021-05-18T21:09:41.025400Z

@hlship This seems to do the trick as well:

{:aliases
 {:pretty {:main-opts ["-e" "((requiring-resolve 'io.aviso.repl/install-pretty-exceptions))"
                       "-e" "(clojure.main/repl)"]
           :extra-deps {io.aviso/pretty {:mvn/version "1.1"}}}}}

👍 1
borkdude 2021-05-18T21:09:55.025600Z

clojure -M:pretty

borkdude 2021-05-18T21:40:25.027200Z

Are there any illustrating examples of transit/write-handler that use a function for the tag and rep and some of the other options? Typically I see (write-handler "foo" (fn [o] ...)) which makes me wonder what other stuff you can do with it. The documentation is pretty terse in my opinion. In which cases do you need the tag arg to be a function?

borkdude 2021-05-19T17:35:50.076200Z

I think I figured it out: https://gist.github.com/borkdude/0a99a4f413b509315d54e1c68f861fad

borkdude 2021-05-19T17:38:07.076400Z

it's a bit unfortunate that the API requires to repeat logic like (.isArray ...) twice, one for the tag and once for the value which I can imagine isn't so good for performance, but ah well

alexmiller 2021-05-18T21:51:40.028400Z

not sure if you found https://www.cognitect.com/blog/2015/9/10/extending-transit but that's maybe useful

borkdude 2021-05-18T21:54:09.028700Z

I did read that, but it also doesn't show an example of "more advanced" usage

borkdude 2021-05-18T21:55:30.028900Z

I guess the fn lets you decide the tag based on something other than the type because you can inspect the value before it's written

borkdude 2021-05-18T21:55:53.029200Z

But I never saw an example of that so far

borkdude 2021-05-18T21:57:29.029400Z

Perhaps this comes in useful in the :default-handler

borkdude 2021-05-18T21:57:54.029600Z

which btw is not documented at all (or I didn't look hard enough)

alexmiller 2021-05-18T22:00:36.029900Z

I don't have time to dig in or say more useful things right now, but I may have some time end of week to look at it

borkdude 2021-05-18T22:02:06.030100Z

appreciate the help, thanks

bringe 2021-05-18T22:12:56.034100Z

Is there something similar to Postman (or can Postman somehow be used) for testing requests to a Clojure web service that accepts/expects transit? For example, say my frontend and backend both use edn, but send transit+json over the wire. I'd like a tool that will: 1. Allow me to input edn and it will format and highlight it, as Postman does with json 2. Convert the edn to transit+json before sending the request 3. Read transit+json from the response and convert it to edn, and also prettify it as in step 1 I know I can write up some code to do this in a repl, and maybe that's even better (I've already done a bit of this), but I'm just wondering if some tooling around this exists.

borkdude 2021-05-18T22:25:35.035300Z

@brandon.ringe This is pretty easy to do with babashka (can do http client + server, has transit, edn and json). There is also a puget CLI for colorization https://github.com/borkdude/puget-cli

borkdude 2021-05-18T22:27:04.036100Z

You could even write a small web app which does this for you, to make a nice UI (not sure about the colorization in that case, I'm sure there is some JS plugin which can do basic highlighting)

bringe 2021-05-18T22:33:49.037100Z

Oh, interesting. Thanks.

borkdude 2021-05-18T22:36:57.037700Z

@brandon.ringe There is also jet which can do EDN -> Transit and vice versa on the command line for you as well.

👍 1
hlship 2021-05-18T22:37:16.038Z

This is cool ... to a point. For example, I like to have my pretty exceptions enabled when running tests but the above is only for starting a REPL; I'm either have to create my own test runner, or use one that makes use of Pretty as well.

hlship 2021-05-18T22:39:15.038200Z

Just feels like there's room for an idea of "Scafollding" the environment prior to the main execution (of a REPL, of a test runner, of an arbitrary function). But that brings in questions about ordering and such ...

borkdude 2021-05-18T22:39:55.038400Z

I guess the user namespace is a spot where you can apply this kind of init code?