Fork me on GitHub

I’m messing around with . If I require it in a lein repl and call the fn, I get an empty list. I would expect to see something at least…


make sure you have a version that actually supports JDK9+, older versions only work up to JDK8


the documentation says:

"Returns a sequence of File objects of the elements on the
  classpath. Defaults to searching for instances of in the classloader hierarchy above
  clojure.lang.RT/baseLoader or the given classloader. If no
  URLClassloader can be found, as on Java 9, falls back to the
  'java.class'path' system property."


In Joy of Clojure, 2nd ed p. 450 they say: > Using dynamic binding is the preferred way to handle recoverable errors in a context-sensitive manner. They also say on p. 447 that > In its purest form, dynamic binding is a structured form of a side effect. The example they show is something like this:

(defn ^:dynamic handle-weird-animal
  [{[name] :content}]
  (throw (Exception. (str name " must be 'dealt with'"))))
(defmethod visit :animal [{[name] :content :as animal}]
  (case name
    ;; Note: could be `cond` and use `#{"Spot" "Lopshire"}
    "Spot" (handle-weird-animal animal)
    "Lopshire" (handle-weird-animal animal)
    (println name)))

;; the default error handling
(traverse DB visit)
;; 1. Unhandled java.lang.Exception
;;     Spot must be 'dealt with'

;; custom error handling
(binding [handle-weird-animal (fn [{[name] :content}] (println name "is harmless"))]
  (traverse DB visit))
Is this something that people actually use as a standard practice? I tend to frown at dynamic binding because it's implicit rather than explicit and can lead to unpleasant surprises.

👀 3

Yeah a defn that throws exeptions unconditionally by default sounds like a defprotocol/defmulti in disguise


That is an idiom you can use to emulate Common Lisp -style conditions and restarts but I haven't seen it actually used And I avoid dynamic binding in general because it is bound to the low-level thread abstraction so it breaks in the presence of fancy thread pooling like core.async and even just lazy seqs

👍 9

If you're looking for an actual implementation of Common Lisp's condition system, check out, which uses dynamic bindings

Karol Wójcik15:04:04

@nilern point is just right! I’m working with dynamic binding (async context) in conjuction with core async on daily basis and it’s one big hack which I wish to get rid of someday.


Stupid question: is Pedestal still the go-to choice for web applications? I had a good experience with it so far but wondering if people are using something different nowadays


I wouldn't say that there even is the go-to choice for web applications. There are many choices.


FWIW, I'm using Yada.

👍 3

I guess a better question would be — what are the alternatives today?


@U015VUATAVC Are you asking about full stack apps or just backend web apps?


I’m mostly interested in developing backend — pure API apps


At Metosin the go-to stack was Ring + Reitit and it is in the new Web Development with Clojure book too


I think most folks just go for compojure-api for backend API apps?


At work we don’t even use compojure-api — just plain ol’ Ring + Compojure, although we also have a GraphQL app. And one app uses Bidi instead of Compojure.


Nobody wants to maintain compojure-api, definitely prefer Reitit for new apps


Pedestal always felt like overkill to me.

☝️ 5

@nilern Yeah, that’s def. the impression I’ve been getting too. I think I would try Reitit for any new web apps I wrote at this point. But compojure-api is def. “popular” still 🙂


I like pedestal - its docs could use some love and probably some parts of it could use a decoupling, but the interceptor thing is overhead i like the moment i want to do websockets


Reitit has interceptors too 😜


You can use any interceptor lib with plain ring


I still like yada but it's not very actively maintained. Still, it has what I need, including swagger and async


What I do not like about Pedestal so far (I know that’s stupid) is the fact they ask for a :route-name that really feels useless


Other than that, I do not have any particular complains — I was mostly interested in alternatives


It's useful for reverse routing in theory, like from templates


But maybe nowadays it's less of a thing


Not something that i’m particularly interested but I see the point


On frontend reverse routing is more often useful but also on the backend good to have for redirections at least


Of course if you don't make a SPA then all that link generation moves to the backend as well


Reitit, ring-jetty


we use pedestal at Nubank & Cognitect


The main lib combo I use for webapps these days is integrant (system composition) + http-kit (server) +ring (server abstraction) +reitit (routing). I’m very happy with it.


Same as @U0JUR9FPH except with Mount instead of Integrant.


Pedestal is pretty great and I like how the server part is integrated (if you use jetty).


Regardless Jetty seems to be the real go to