This page is not created by, affiliated with, or supported by Slack Technologies, Inc.
2022-09-04
Channels
- # announcements (9)
- # babashka (5)
- # beginners (50)
- # calva (13)
- # clj-kondo (11)
- # clojure (30)
- # clojure-australia (1)
- # clojure-china (1)
- # clojure-europe (4)
- # clojure-filipino (1)
- # clojure-hk (1)
- # clojure-indonesia (1)
- # clojure-japan (1)
- # clojure-korea (1)
- # clojure-my (1)
- # clojure-norway (2)
- # clojure-sg (1)
- # clojure-taiwan (1)
- # clojurescript (32)
- # conjure (2)
- # honeysql (1)
- # hyperfiddle (8)
- # jobs-discuss (9)
- # leiningen (2)
- # malli (3)
- # off-topic (21)
- # reitit (4)
- # shadow-cljs (10)
- # sql (3)
- # squint (17)
- # tools-deps (14)
To avoid using potemkin, for functions I know I can just do:
(def foo impl/foo)
Does this work for macro as well?I've noticed there's a few other annoying things with this approach, it doesn't copy the documentation, and then calling source at the REPL won't show it, etc. 😞 Right now I'm trying the odd approach of splitting the same namespace across many files, which has downsides in my linting 😛, but decluters my files. Maybe I'll end up moving the entry function all into one file and go with the _impl namespace approach once I'm done, but this also annoys me a bit, because if I need to work some more on them, I don't like having the entry function elsewhere when I modify the impl and I want to test things its more annoying to call into a different namespace.
:thinking_face: that would solve the doc-string issue, would this also make clojure.repl/source work?
but yeah, this is a common problem. I usually prefer to have the docstrings in the API namespace and just refer to those when you want to read the docs
I guess it's not the end of the world if people need one more hop to see the real source
Cool, ya I'll try it, not sure which option I'll end up with in the end, but nice to know what all the options are
I tried this and it works:
(ns foo)
(defmacro foo [])
(ns bar (:require [foo]))
(def foom @#'foo/foo)
(alter-meta! #'foom (constantly (meta #'foo/foo)))
(prn (meta #'foom))
(require '[clojure.repl])
(clojure.repl/source foom)
Note that this only works in the JVM, but potemkin already doesn't work with CLJS anyway
Side question, since I have your attention. What do you do to walk a form and maintain meta, since clojure.walk doesn't? I'm using riddley instead, but ztellman doesn't maintain the repo actively anymore, I wonder if there's a small change I can make to my use of walk to add it back myself or some other lib
Hum, is there a workaround until this patch: https://clojure.atlassian.net/browse/CLJ-2568 ??
(defn nav'
[x k]
(nav x k (get x k)))
(defn nav-in
[x path]
(loop [x x
path path]
(if-some [k (first path)]
(let [x (datafy x)]
(recur (-> (nav x k (get x k)))
(rest path)))
x)))
I'm curious if anyone knows an example where these helpers wouldn't be useful?used like
(-> (datafy foo)
(nav' :bar)
(datafy)
(nav' :baz)
(datafy)
(nav-in [:asdf :jkl :qwerty :uiop])
(datafy))
Hey there 👋. Is anyone aware of a package that allows me to register validators around functions that allow me to check for invariants. I want to be able to implement my domain functions without having to consider invalid state or bad input while still handling errors in a kind of robust way. Something like this:
(defn attack [game-state, attack-info] (...stuff...))
(defguard attack [game-state, attack-info]
(and
(is-valid-game-state? game-state)
(not (is-dead? game-state attacker-id))
(not (is-dead? game-state defender-id))
(is-turn-of? game-state attacker))
(attack game-state attack) ;; new-game-state
(attack game-state invalid-attack) ;; !invalid-game-state!
(valid? attack game-state attack) ;; true
(valid? attack game-state invalid-attack) ;; false
(guarded attack game-state attack) ;; :ok new-game-state
(guarded attack game-state invalid-attack) ;; :err error
(guarded! attack game-state attack) ;; new-game-state
(guarded! attack game-state invalid-attack) ;; throw Err
Additionally, functions have builtin support for pre and post conditions, https://clojure.org/reference/special_forms#_fn_name_param_condition_map_expr
Just in case, :pre and :post are not meant for production usage (which is presumably what is wanted by "domain invariants")
> Just in case, :pre and :post are not meant for production usage Why is this?
DbC is meant to be exercised at dev/test time https://en.wikipedia.org/wiki/Design_by_contract#Performance_implications