This page is not created by, affiliated with, or supported by Slack Technologies, Inc.
2023-07-19
Channels
- # babashka (39)
- # beginners (58)
- # calva (45)
- # clerk (9)
- # cljsrn (10)
- # clojure (23)
- # clojure-denver (13)
- # clojure-europe (39)
- # clojure-norway (6)
- # clojurescript (10)
- # clr (3)
- # cursive (5)
- # data-science (6)
- # datomic (27)
- # events (1)
- # fulcro (33)
- # graphql (5)
- # hyperfiddle (24)
- # introduce-yourself (4)
- # kaocha (1)
- # malli (8)
- # off-topic (23)
- # pedestal (5)
- # re-frame (2)
- # releases (4)
- # shadow-cljs (8)
- # xtdb (12)
Hey all, is there are consensus with regards to best practices when using keywords?
I tend to like Eric Normand’s ideas about using double colon keywords, and often prefer to just use namespaced keywords that don’t refer to an actual namespace (like :not-a-real-ns/keyword
).
https://ericnormand.me/issues/purelyfunctional-tv-newsletter-430-use-keyword-notation-for-unique-values
However I’ve also seen this post, which sort of advices an opposite approach: https://blog.jeaye.com/2017/10/31/clojure-keywords/
Would really appreciate hear about your thoughts, experiences and advice with using keywords.
There's no consensus and you'll see all approaches used in the wild. I myself use both that you mentioned and also nested maps with only plain keywords, sometimes within the same project - depends on the context.
I wonder how people would consider
(ns com.company.ns
(:require
[com.company.ns :as-alias a]))
::a/blah
which neatly solves the problem of not being transportable while also keeping concisionjust a note that that latter blog blog pre-dates the 1.11 feature of :as-alias
which is a big help in the specific case of using qualified keywords that don't refer to a loadable namespace
the idea here is that:
1. qualified keywords ("qualified" used here specifically as whether they correspond to a namespace is orthogonal) are useful for disambiguating names in global attribute space
2. but qualifiers can be long, so it's helpful to use aliases
3. but aliases (in :require :as) load the namespace, which makes it hard to use qualifiers that don't correspond to a namespace
4. which is why we added :as-alias
so: use qualifiers to disambiguate, use aliases with either :as
or :as-aliase
as appropriate to type less
all that said, keywords exist in a context, and not all contexts need global disambiguation. if you are passing options to a function, probably unqualified is sufficient, etc
are there performance penalties/differences between top-level functions and inline functions in a let block?
they're both compiled to function classes so my guess is no difference. but as a wise man named Rich once told me, why guess when you can measure? :)
that's a good point.
I guess a top-level function may require a var lookup whereas inline does not so that is one possible difference (that is independent from the function itself)
if direct linked, that would presumably not be relevant
cool, that makes sense. my small tests didn't show much difference so thanks for the clarity
Another difference between them would be that inline functions in a let block would construct instances (and if you don't close over anything it would have no instance variables) which requires an allocation, but it's reasonably likely that after some iterations the JVM would be able to realize that the instance only exists to call a static method, and optimize it out.
Absolutely, and on JDK 11+ even better for this case because of the G1 collector being the default.
On JDK 8 there is a small possibility of this becoming a performance concern, but it's unlikely and you'd have to measure to know.
and it would have to be an extremely hot loop.
There are some other elements to consider: • top level defns emit classes with static methods • how everything works with the JIT compiler ◦ will inline forms get optimized the same way as a top level def? • direct linking (once you eliminate var lookups, the JIT compiler can freely inline method calls
I take back my initial reaction, it's not the same and it's a complicated question :)