Fork me on GitHub
#biff
<
2024-05-16
>
jf15:05:42

I am having trouble trying to understand the generated -main (https://github.com/jacobobryant/eelchat/blob/6a0f3eeb84c081c6e29054007ff44ae5d44054ee/src/com/eelchat.clj#L85):

(defn -main []
  (let [{:keys [biff.nrepl/args]} (start)]
    (apply nrepl-cmd/-main args)))
1. let: I understand that start basically runs initial-system through each of the components. I see that the output of (start) gets put into the list of bindings for let.. so I am expecting some kind of destructuring form. However, the output of (start) is a hashmap?
{:biff.xtdb/topology :standalone, :biff.tasks/deploy-untracked-files ["target/resources/public/css/main.css" "config.env"], :biff.tasks/server "example.com", :biff.tasks/generate-assets-fn com.eelchat/generate-assets!, :biff.middleware/on-error #'com.eelchat.ui/on-error, :biff.eval/on-eval (#'com.biffweb.impl.htmx-refresh/send-refresh-command), :biff.beholder/enabled true, :biff/handler #object[com.biffweb.impl.htmx_refresh$wrap_htmx_refresh$fn__27264 0x9ecc862 "com.biffweb.impl.htmx_refresh$wrap_htmx_refresh$fn__27264@9ecc862"], :biff.xtdb.jdbc/jdbcUrl nil, :recaptcha/site-key nil, :biff/malli-opts #'com.eelchat/malli-opts, :biff.nrepl/args ["--port" "7888" "--middleware" "[cider.nrepl/cider-middleware,refactor-nrepl.middleware/wrap-refactor]"], :biff.xtdb/dir "storage/xtdb", :biff.xtdb/tx-fns #:biff{:ensure-unique (fn [ctx kvs] (let [kvs (for [[i [k v]] (map-indexed vector kvs) :let [sym (symbol (str "v" i))]] {:k k, :v v, :sym sym}) query {:find (quote [doc]), :limit 2, :in (mapv :sym kvs), :where (vec (for [{:keys [k sym]} kvs] [(quote doc) k sym]))}] (when (< 1 (count (apply xtdb.api/q (xtdb.api/db ctx) query (map :v kvs)))) false)))}, :biff/queues {}, :biff.tasks/watch-dirs ["src" "dev" "resources" "test"], :mailersend/api-key nil, :biff/port 8080, :biff.xtdb/node #, :com.eelchat/chat-clients #object[clojure.lang.Atom 0x544ff0a1 {:status :ready, :val #{}}], :biff.tasks/on-soft-deploy "\"(com.eelchat/on-save @com.eelchat/system)\"", :biff.tasks/main-ns com.eelchat, :mailersend/from nil, :biff.refresh/enabled true, :biff.middleware/secure false, :biff/secret #object[com.biffweb.config$use_aero_config$secret__1256 0x32c0e664 "com.biffweb.config$use_aero_config$secret__1256@32c0e664"], :recaptcha/secret-key nil, :biff/base-url "", :biff.system-properties/clojure.tools.logging.factory "clojure.tools.logging.impl/slf4j-factory", :biff.tasks/css-output "target/resources/public/css/main.css", :biff.beholder/on-save #'com.eelchat/on-save, :biff.tasks/deploy-cmd ["git" "push" "prod" "master"], :biff/stop (#object[com.biffweb.impl.misc$use_beholder$fn__23616 0x3d5811cf "com.biffweb.impl.misc$use_beholder$fn__23616@3d5811cf"] #object[com.biffweb.impl.misc$use_jetty$fn__23649 0x7a13da5e "com.biffweb.impl.misc$use_jetty$fn__23649@7a13da5e"] #object[com.biffweb.impl.xtdb$use_tx_listener$fn__20813 0x51f2f745 "com.biffweb.impl.xtdb$use_tx_listener$fn__20813@51f2f745"] #object[com.biffweb.impl.queues$use_queues$fn__27188 0x6434d8d9 "com.biffweb.impl.queues$use_queues$fn__27188@6434d8d9"] #object[com.biffweb.impl.xtdb$use_xt$fn__20777 0x191f7bf9 "com.biffweb.impl.xtdb$use_xt$fn__20777@191f7bf9"]), :biff/jwt-secret #object[com.biffweb.config$eval1234$fn__1236$fn__1238 0x7dba93ae "com.biffweb.config$eval1234$fn__1236$fn__1238@7dba93ae"], :biff.middleware/cookie-secret #object[com.biffweb.config$eval1234$fn__1236$fn__1238 0x3bb40b83 "com.biffweb.config$eval1234$fn__1236$fn__1238@3bb40b83"], :biff.system-properties/user.timezone "UTC", :biff/send-email #'com.eelchat.email/send-email, :biff/host "0.0.0.0", :biff.nrepl/port "7888", :mailersend/reply-to nil, :biff.refresh/clients #object[clojure.lang.Atom 0x7904ee3c {:status :ready, :val #{}}], :biff/modules #'com.eelchat/modules}
I dont understand how this would work where it is in let, and why 2. I see {:keys [biff.nrepl/args] in the let binding vector... so I am expecting to see biff.nrepl/args used in the body of the let. However, this does not appear to be the case? am I missing something? 3. the body of the let is (apply nrepl-cmd/-main args) . What is args , and where does it come from?

onetom16:05:55

args is the name part (as returned by clojure.core/name) of the biff.nrepl/args symbol. in a let u can only bind non-qualified symbols (aka. simple symbols, which can be checked with the clojure.core/simple-symbol? predicate), because the meaning of qualified symbols is to reference the current value of clojure.lang.Var objects in other clojure.lang.Namespace objects. so (let [{:keys [some.ns/sym]}] ,,, sym ,,,) is just a shorthand for (let [{sym :some.ns/sym}] ,,, sym ,,,) and :keys is short for keyword keys, not hash-map keys. it's more understandable, if u know u can also use :syms and :strs to destructure maps, where the keys are symbols, like {'some.namespaced/attribute 123} and `{"some.namespaced/attribute" 123}`

☝️ 1
onetom16:05:13

the official docs cover all of these variations: https://clojure.org/guides/destructuring it's quite similar to javascript destructuring, it's just javascript does the other way around, as if it would be pattern matching:

let {"key in object": symbol_to_bind_its_value_to} = {"key in object": 123}
symbol_to_bind_its_value_to
=> 123

onetom16:05:42

the same logic would be this in clojure:

(let [{symbol_to_bind_its_value_to "key in object"} {"key in object" 123}]
  symbol_to_bind_its_value_to)