Fork me on GitHub

What's a good term for tooling to offer which program to run "a Clojure". ie, lumo, clojure, planck, bb, joker, etc. are these clojures, Clojures, or just a generic "choose a program"?


> ClojureScript is a compiler for Clojure that targets JavaScript. So, a clojure compiler

dominicm18:04:59 lists this and clojurescript under "host"


Oui, "host" seems good as well


Host is probably better, I'd go with that personally

👍 4

Clojure CLIs? Clojure REPLs?


just working on some wording


clojure runtimes?


I wonder if Clojure can be genericized like that. Is there only one Clojure or can many things be a clojure?


Clojure "flavours", maybe?


Target or runtime?


I don't think "a Clojure" makes sense. Clojure is a language so that's kind of generic by definition.


It's not like "a Lisp"


clojure (proper) is based on jvm; lumo is based on node.js; plank is based on javascriptcore; babashka is based on graal; joker is, let's say, based on go. so i guess "clojure runtime environment" might be a better choice.


I'm running into some problems with using multimethods in a repl-driven environment. Do they not get reevaluated like regular defs?


I just spent a bit being very confused why some logging wasn't showing up. Bouncing the repl fixed things but I don't want to do that more than once a week : )


@datran if by "they", you're referring to defmulti s, then the answer is yes (quoting "Clojure Programming", p. 415): > defmulti has defonce semantics, so dispatch functions are not updated simply by reloading a modified defmulti form. The workaround is to ns-unmap the multimethod's var--which unfortunately requires reloading each of the multimethod's method implementations as well.


thanks for that! I was going a bit crazy. That's pretty unfortunate, though. I'll have to see if I can incorporate that unmapping in my workflow : /

salam05:04:01 solves that and all other sorts of problems that arise with the "reloaded workflow". if you're practicing the "reloaded workflow", you should really be using this library one way or another. 🙂

👍 4

I am currently using juxt's clip library to handle that, which I thought used tools.namespace internally. I'll have to dig into it now


ok, clip does use, but it doesn't look like that will unmap multimethod Vars


i just created a minimal example to verify that correctly reloads multimethods.


i created a file: fruits.clj as follows:

(ns fruits)

(defmulti fruit :t)

(defmethod fruit "apple"
  (println "got" x))

(defmethod fruit "banana"
  (println "got" x))
and then, in the same directory, started a REPL as such:
clj -Sdeps '{:deps {org.clojure/tools.namespace {:mvn/version "1.0.0"}} :paths ["."]}'
and here are the steps to verify the behavior:
Clojure 1.10.1
user=> (require '[ :refer [refresh]])
user=> (require '[fruits :refer [fruit]])
user=> (fruit {:type "apple"})
got {:type apple}
user=> (fruit {:type "banana"})
got {:type banana}

;; Here, I switched to another
;; terminal tab where I have
;; `fruits.clj` open in vim and
;; changed the dispatch function for
;; `fruit` from `:type` to `:t`.

user=> (refresh)
:reloading (fruits)
user=> (fruit {:type "apple"})
Execution error (IllegalArgumentException) at user/eval1696 (REPL:1).
No method in multimethod 'fruit' for dispatch value: null
user=> (fruit {:type "banana"})
Execution error (IllegalArgumentException) at user/eval1698 (REPL:1).
No method in multimethod 'fruit' for dispatch value: null
user=> (fruit {:t "apple"})
got {:t apple}
user=> (fruit {:t "banana"})
got {:t banana}
user=> ^D


i'm not familiar with clip. i use integrant and integrant-repl and haven't had problems with reloading multimethods.


It looks like c.t.n.r/clear is the nuclear option here, I might try that


hmm, that doesn't seem to work


I would like to use Timbre as logging library (I am not very familiar with the java ecosystem, and would like to avoid xml’s), is there any way I can control the logs from the libraries that use tools.logging or java logs using timbre too? Also, if I would write a library, would use timbre for logs cause a headache for users of the library that do not use timbre? If someone has any resource that explains/compares these 2 logging strategies would be great


Expanding a bit, I would like to log maps, not strings (strings would be {:description msg})


At first sight, it seems Timbre would be ideal for “application-level” logging, looks like using you can forward almost everything to timbre and from there control the appenders. On the other hand, looks like would be preferred for a library, to let the user of the library decide which backend to use for logging


I am familiar with the Java and SLF4J ecosystem. You are right, libraries should always depend on slf4j-api only and the final app that is using those libraries specify a suitable implementation which will magically receive all the logs from all the libraries. For app level logging as well, I like using slf4j-api because then I can switch the logger implementation at will. You can use Timbre directly, but be aware of the tradeoffs.

👍 4

@UJRDALZA5 would you mind giving some Timbre tradeoff examples? That's interesting


Sorry, I wasn't clear enough. The tradeoff is, you are tying your code to a specific implementation (Timbre) rather than a facade (interface, SLF4J). I did not mean Timbre itself has some tradeoff, well, there might be, but I am not aware.

👍 4
Adam Helins12:04:37

What's the name of those vectors where the first item is a keyword representing an operation and the rest are arguments, like in Re-frame? I remember a talk where a specific name was given, but cannot manage to recall it.

Adam Helins12:04:50

Nope, more of a concept in functional programming, something more specific


event, command, mutation are all used commonly

Adam Helins12:04:52

I am fairly sure there is a more sophisticated name, I am looking after that talk but it was years ago I think


Named tuple maybe


But that's more an erlang thing than fp

Adam Helins13:04:36

Well, "vector variants" to be more precise, I guess


So it's like DIY variant types


how do I permanently and globally turn off clojure generating errors reports in /tmp instead of printing the errors directly?

Full report at:


I know its done in the spirit of better error messages but this is just worse for me


@thheller I looked this up in main.clj:

--report target     Report uncaught exception to \"file\" (default), \"stderr\",
                        or \"none\", overrides System property