borkdude / deflet

Make let-expressions REPL-friendly!

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

deflet

Clojars Project

Make let-expressions REPL-friendly!

Let them have their inline-def and eat it too.

Usage

(require '[borkdude.deflet :refer [deflet]])

Write inline-defs like you would in a Rich comment form, so you can evaluate things expression by expression as you go:

(comment
  (def x 10) ;; => #'x
  (def y (inc x)) ;;=> #'y
  y ;;=> 11
)

but now without polluting the global environment in production / library code, while still having the ability to evaluate expressions in the REPL:

(deflet
  ;; evaluation still works for individual forms in a REPL-connected editor:
  (def x 10) ;;=> #'x
  (def y (inc x)) ;;=> #'y
  ;; but the whole expression is compiled into a let-expression which returns the last value:
  y) ;;=> 11

The above deflet form expands into:

(let [x 10]
  (let [y (inc x)]
    y)) ;;=> 11

I find the inline-def style particularly helpful when exploring code in the REPL, e.g. when writing tests:

(deftest deflet-test
  (deflet
    (def x 10)
    (is (= 10 x))))

Nbb

This library also contains an nbb REPL-friendly variant, called defletp which works in concert with promesa:

(require '[borkdude.deflet :refer [defletp defp]]
         '[cljs.test :refer [deftest async is]]
         '[promesa.core :as p])

(deftest defletp-test
  (async
   done
   (-> (defletp
         (defp x (p/delay 100 :result))
         (is (= :result x)))
       (p/finally done))))

The defp works like def but wraps the result with nbb.core/await to await top level promises. So when evaluating (defp x (p/delay 100 :result)) in the nbb REPL, you'll get a var x bound to 100 instead of a promise. But the defletp macro expands this into a promesa.core/let expression.

Here is a demo of how you can use deflet with nbb and playwright tests.

About

Make let-expressions REPL-friendly!


Languages

Language:Clojure 100.0%