https://github.com/borkdude/deflet
Make let-expressions REPL-friendly!
https://github.com/borkdude/deflet
babashka clojure clojurescript nbb
Last synced: 20 days ago
JSON representation
Make let-expressions REPL-friendly!
- Host: GitHub
- URL: https://github.com/borkdude/deflet
- Owner: borkdude
- Created: 2023-03-02T17:32:56.000Z (about 2 years ago)
- Default Branch: main
- Last Pushed: 2025-04-11T15:05:44.000Z (about 1 month ago)
- Last Synced: 2025-04-19T01:32:03.937Z (about 1 month ago)
- Topics: babashka, clojure, clojurescript, nbb
- Language: Clojure
- Homepage:
- Size: 28.3 KB
- Stars: 70
- Watchers: 4
- Forks: 0
- Open Issues: 0
-
Metadata Files:
- Readme: README.md
Awesome Lists containing this project
README
# deflet
[](https://clojars.org/io.github.borkdude/deflet)
Make let-expressions REPL-friendly!
> Let them have their inline-def and eat it too.
## Usage
``` clojure
(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:``` clojure
(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:``` clojure
(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:
``` clojure
(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:
``` clojure
(deftest deflet-test
(deflet
(def x 10)
(is (= 10 x))))
```In constrast to writing inline defs without deflet, type hints actually work the
way you'd expect and you can still run your tests in parallel.## Nbb
This library also contains an [nbb](https://github.com/babashka/nbb) REPL-friendly variant, called `defletp` which works in concert with [promesa](https://github.com/funcool/promesa):
``` clojure
(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](examples/playwright) is a demo of how you can use deflet with nbb and playwright tests.
![]()