Fork me on GitHub

The input is like input at a repl, needs a new line to trigger


Is there a way to pipe REPL output through more , Linux shell style? There are some large data structures I'd like to check more carefully but they just go flying by.


Override :print as an option to do whatever you like :)

thanks2 1

@zanategdl Maybe take a look at Cognitect's REBL which can display data structures as tables and lets you drill into them?

thanks2 1

So I really want to use Plumatic Schema to write libraries, without forcing it as a dependency upon users. My idea for how to accomplish this is to write a shim around the schema types/methods I use, that delegates to schema.core if it exists and can be loaded, and does nothing otherwise (e.g. my.shim/defn delegates to schema.core/defn if it exists, and otherwise delegates directly to clojure.core/defn). Is this doable/reasonable? And if so, how should I go about detecting if schema.core exists, and loading it only if it does? Is this possible for clj and cljs?

Daniel Stephens12:07:44

I saw something similar to this done in They have

(defmacro when-joda-time-loaded
  "Execute the `body` when Joda-Time classes are found on the classpath.

  Take care - when AOT-compiling code using this macro, the Joda-Time classes
  must be on the classpath at compile time!"
  [& body]
  (if (try (Class/forName "org.joda.time.DateTime")
           (catch Throwable e))
    `(do [email protected])))
for example to only execute some code if a class exists

Daniel Stephens12:07:37

as they mention there, you have to be careful with AOT stuff since it's a macro, you could do it on the fly but since it's reflection and throw/catching an exception performance may suffer if that is a concern


Cool, thanks! I’m not sure how I’d adapt that for Schema though, since Schema’s a Clojure lib


As for doing this on the fly, I’m thinking I could just do it once and then memoize the result, since Schema probably won’t be added to the classpath mid-program-execution

Daniel Stephens12:07:50

ahh yeah mb, I haven't tried it but if require throws an error if it doesn't exist that might be possible


The piggieback source does this fwiw


Cider piggieback, that is

👍 1

seems like I can do the same thing in cljs via (try (require ' true (catch :default _ false))


…so I guess that answers my question 🙂 thanks!


there's also requiring-resolve

Clojure 1.10.1
(ins)user=> (requiring-resolve '
Execution error (FileNotFoundException) at user/eval1 (REPL:1).
Could not locate foo/bar__init.class, foo/bar.clj or foo/bar.cljc on classpath.
(ins)user=> (requiring-resolve '


doesn't work in cljs though

ojureScript 1.10.758
(ins)cljs.user=> (requiring-resolve '
WARNING: Use of undeclared Var cljs.user/requiring-resolve at line 1 <cljs repl>
Execution error (TypeError) at (<cljs repl>:1).
Cannot read property 'call' of undefined


Code management: Has anyone else considered def ing central keywords or strings and then referring to the symbols in your code rather than the more “keywordly” (or “stringly”) typed approach we usually see in Clojure, where people just sprinkle the literals all over the code? So, rather than the usual (when (= role :my-important-central-keyword) ... , you’d do

(def my-important-reference :my-important-central-keyword)

... in another ns
(when (= role constants/my-important-reference) ...


I basically do that when I want compile-time enforcement around constants


it’s a lot nicer to have the compiler tell you when you’ve made a typo than to have to figure it out yourself because your program is inexplicably not working


I like the idea, it feels more secure with that enforcement. Do you limit it to certain things, or do you use it a lot?


Yeah, exactly


this is in general, an anti-pattern in Clojure


the whole benefit of making keywords invokable is to reduce the distance between the attribute and the invocation.


realistically, if you have (def foo :foo), you're not ever going to change :foo or if you do, you will also change foo. and you have also made it harder for static analysis tools to track where that keyword is being used


I end up using it every once in a while, especially when e.g. building a DSL or generating code for something


you've also made everything slower by introducing a var lookup in your keyword invocation


so you're doubling the invocation overhead


another benefit is that tooling support is better for vars than for keywords, so you can get autocomplete etc


as a rule of thumb for ‘normal’ code, I’d recommend defing constants including keywords that feel like ‘magic numbers’, and leaving keywords used for lookups etc inlined

Ben Sless13:07:51

Is the lookup overhead eliminated if I use direct linking?


for instance, if you’re generating HTML/CSS/React/whatever it’s not unlikely you’ll have a bunch of magic number-style keywords like :ff1212, and defing these is generally a good idea


but if you find yourself doing stuff like {constants/keyword-a 123, constants/keyword-b true} a lot, then you’ll probably want to consider @alexmiller’s points


There's autocomplete for keywords in cider


@UK0810AQ2 no? maybe? direct linking eliminates var lookup for invocation but I don't remember if you get the same effect for resolution. it would also potentially ruin the optimized keyword call site invocation used in record lookups.


Cursive also has keyword autocomplete

Ben Sless14:07:28

I see. And if I define it as :const there will be no lookup as well because the compiler will inline it?


it should in that case. but this seems to me to be going increasingly far just to avoid doing the simple thing

👍 1

Go to definition doesn't always work if you just use keywords, so that is one point in favor of defing. An example where that comes up a lot is re-frame, since it uses this pattern for registering handlers: (rf/reg-event-db :my-keyword (fn [...] ...)


But the definition you jump to will be pointless


@U09LZR36F Not if you use a macro, and tell Cursive to resolve it like a def


@U15RYEQPJ hard disagree about vars to keywords, if you want the compiler enforcement there's more effective options than def of a keyword, and it makes the code harder to read rather than easier


to me human readability is first priority


@alexmiller (and others): points taken 🙂 I’m not so worried about invocation optimization (in my current app) as I am about readability and safe refactorability. I don’t think it’d make sense to def all of your constants - the example that @U15RYEQPJ brought up, {constants/keyword-a 123, constants/keyword-b true}, is in the silly end. Rather, I’m considering using constants for string values whose literal representation might change slightly over time (outside of my power), and whose semantic value (and usage of the same) in the application should not be disrupted by these changes. In addition, there’s quite a few of them, and their literal representations can be very similar, so the extra layer of indirection gives a chance to make them more dissimilar + to attach docstrings.


with that scope, seems reasonable


@U0AQ3HP9U if I don't control the string used as a key in a data structure, and especially if someone else can decide to change that string, I prefer to have an explicit re-keying step (with a single mapping, used locally in one place), rather than changing a key that is dereferenced throughout the app


I think one of the biggest clojure antipatterns is the transition from "use vanilla data type and simple keys" to "use the data representation provided by some external API in all application logic"


@U051SS2EU the string is not used as a key in a data structure, it’s used as a val in predicates. Like I posted originally, (when (= role constants/my-role) .... But I get your point, I think. In the case of the key being used in maps, for example, you’d do

(->> my-domain-data-map 
     (map (fn [[k v]] 
            [(get rekeying-map k k) v])) 
     (into {})
at the edge of your application, right? Or something to that effect.


yes - sorry, this is most frequently seen in keys, but even vals should be translated if they are symbolic constants as opposed to primitive types IMHO


Right. Thank you for your thoughts 🙂


anyone know what might cause (io/resource "") to resolve to my user folder and not my project folder, created a few projects and not seen this behaviour previously 😕


resource just loads from your classpath, probably whatever is first on your classpath


maybe compare (System/getProperty "java.class.path")


well it seems to resolve to this jar:file:/home/oly/.m2/repository/javax/xml/bind/jaxb-api/


I would not really expect that to resolve to anything particularly stable and useful


> (io/resource "") to resolve to my user folder > resolve to this jar:file:/home/oly/.m2/repository/javax/xml/bind/jaxb-api/ these sentences seem conflicting to me


well /home/oly/ being my user folder and my project being in /projects/


I will try removing the files in my home folder, the getproperty command does list these "resources:src/clj:src/cljc:tests:" and then all the /home/oly/.m2/files


okay may have figured it out, I think its something todo with I am using lein but with deps and moved the file to a sub folder to avoid conflicts with the cljs deps file seems that may have changed the resources root 😕


:lein-tools-deps/config {:config-files [:install :user :project "deps-backend.edn"]}


doing that in the root seemed to fix my issue instead of using a nested path


How can I pass a symbol into a syntax-quote in a macro without evaluation? E.g. how can I get the following to print [java.lang.Long clojure.lang.Keyword clojure.lang.Symbol] instead of throwing java.lang.RuntimeException: Unable to resolve symbol: 3 in this context?

(defmacro mc [] `(prn (mapv type [1 :2 ~(symbol "3")]))) (mc)


type works on objects and it looks like you're trying to get the type of (symbol "3"), which is invalid


symbols can't start with a number



> (prn (type (symbol "3")))


but that’s beside the point; pretend that it says "hello" instead of "3" if that helps 🙂


invoking type on that vector via mapv is going to evaluate the vector, which is going to evaluate the symbol, so you need some kind of quoting


(defmacro mc [] `(prn (mapv type '[1 :2 ~(symbol "3")])))


sorry if I misdiagnosed above


oh, cool, thanks 🙂


So… what if I want some things to be quoted and some not? Something like the following:

(defmacro foo [xs] `(prn ~(vec (for [x xs] (if (string? x) (symbol x) x))))) (foo ["foo" :bar "baz"])


(list 'quote (symbol x))


or a bit more esoteric

`'~(symbol x)


I was trying to call quote in the macro


Hello! What do you guys think about Riemman for monitoring system health and performance? How do you compare it with other options?


riemann doesn't keep history so it's not a complete solution


alerts and processing is done in clojure, so that is powerful but pretty brittle in my experience


it's easy to accidentally break stuff, which is not something i'd want in my monitoring stack


what alternatives are you considering?


Kibana, Instana and Zabbix are the other options