Fork me on GitHub
#off-topic
<
2021-05-05
>
craftybones08:05:02

What kind of CSS framework/design system/principles would you recommend to help build a simple CSS based presentation?

Aron10:05:36

How about variable/dynamic?

Thomas Moerman13:05:12

Hi, I was wondering what mechanism(s) are available for documenting individual namespaced keywords. If there is no such approach in the language, how do you go about this? thx.

emccue13:05:32

I would do this

emccue13:05:54

(def thing 
  "Indicates that you should do the thing"
  ::thing)

emccue13:05:13

then use the var

ghadi13:05:17

bad idea to have vars proxying to keywords.

6
ghadi13:05:02

@thomasmoerman that question is totally on-topic 🙂 , which is off-topic in the off-topic room

😅 6
ghadi13:05:45

you could always make a little table (a map) of keyword -> information about the keyword

ghadi13:05:54

which might include a docstring, might include other stuff too

lilactown14:05:50

what's wrong with vars proxying keywords?

Alex Miller (Clojure team)14:05:34

it's slower and it makes two things that need to be synced

Alex Miller (Clojure team)14:05:59

it's the moral equivalent of creating a set of "getFoo()" methods for the foo field on a Java class

lilactown14:05:00

I find it useful sometimes when I want to have like a global singleton I can use as data, e.g. in re-frame:

(def user-sub ::user-sub)

(rf/reg-sub user-sub ,,,)

(rf/subscribe [user-sub])

lilactown14:05:44

this is due to the fact that re-frame doesn't return a reified thing, of course; a little quirky

Alex Miller (Clojure team)14:05:01

I don't see what value that provides over just using ::user-sub

vemv14:05:43

@thomasmoerman if you use spec, you can make your own spec/def wrapper that accepts an extra docstring argument when you "jump to keyword" (cider does that) you would reach that definition additionally, your wrapper can push the docstring to a registry that you would query with rebl or such I've done exactly this, worked well

👍 3
lilactown14:05:48

mainly helps prevent typos via compiler warnings 😄

lilactown14:05:08

and go-to definition

lilactown14:05:26

sounds like tooling is catching up to those tho

vemv14:05:46

jump-to-def for keywords was implemented circa 2017 the compiler-check part is true but can also be tackled otherwise (e.g. intentful spec usage)

borkdude14:05:15

clojure-lsp now also has jump to keyword definition which works out of the box with clojure.spec and re-frame

borkdude14:05:25

clj-kondo delivers this analysis so it can be leveraged by other tools as well

emccue14:05:10

If you def the keyword, you get jump to definition

emccue14:05:43

and also you can list out "possibilities"

emccue14:05:07

(def process-state:a ::a)
(def process-state:b ::b)
(def process-state:c ::c)

borkdude14:05:12

@emccue that's not idiomatic so it won't work with typical code, and has been discussed already here: https://clojurians.slack.com/archives/C03RZGPG3/p1620220712458300

borkdude14:05:40

I don't mean to be pedantic, just saying that most people don't do this

emccue14:05:44

we aren't using spec, so having all the options listed out in the source code is beneficial

emccue14:05:24

and autocompletion with ns/pr -> ns/process-state:a, ns/process-state:b, ... is also helpful

emccue14:05:55

I don't always do it for sure

emccue14:05:51

and alex is right - it is slower and it is mostly ceremony

emccue14:05:22

but its ceremony that I appreciate when coming back to code after a month or two

borkdude14:05:05

I can heartily recommend use clojure-lsp. It works with the most widely used editors for clojure and provides this kind of navigation without introducing such a major workaround.

emccue14:05:15

does it work with cursive?

borkdude14:05:35

yes. afaik cursive already has keyword navigation out of the box as well

emccue14:05:12

cursive lets me search for usages of a keyword and jump to definition if its being used in a specific set of forms like re-frame/reg-*

emccue14:05:40

strawman example

borkdude14:05:52

same for clojure-lsp, so if that's not sufficient, then ignore what I said

borkdude14:05:05

it's pluggable though using clj-kondo hooks

emccue14:05:54

(ns a)

(defn record-transaction [source transaction-info]
  (jdbc/execute ....)
  (tracking/track {:event :recorded-transaction
                   :came-through source}))

(ns b)

(record-transaction ::a/email-blast { ... })
(record-transaction ::a/phone-call { ... })

emccue14:05:59

just easier for me to read the code if I have this

borkdude14:05:18

so you mean, custom macros or functions that "register" something using a fully qualified keyword. and you want to navigate to those. yes, you can customize this using clj-kondo hooks in clojure-lsp.

emccue14:05:50

(ns a)

(def source:email-blast ::email-blast)
(def source:phone-call  ::phone-call)

(defn record-transaction [source transaction-info]
  (jdbc/execute ....)
  (tracking/track {:event :recorded-transaction
                   :came-through source}))

(ns b)

(record-transaction a/source:email-blast { ... })
(record-transaction a/source:phone-call { ... })

emccue14:05:18

at least in this case I just mean constants

borkdude14:05:31

a keyword is already a constant :)

emccue14:05:42

so is a list [1 2 3]

emccue14:05:02

I mean constants not in the "unchanging value" sense

borkdude14:05:05

ok, not going to argue, if this works for you, then by all means, enjoy ;)

emccue14:05:24

but in the "finite set of flags" sense

emccue14:05:30

if that tracks

ghadi14:05:59

deffing the keyword in service of tooling or typo-catching is a hack

borkdude15:05:24

deffinitaly :)

borkdude15:05:41

you might as well not use keywords in this case. (def source:email-blast 0)

emccue15:05:00

so is avoiding macros that def multiple symbols because cursive can't recognize them

emccue15:05:02

and yet...

borkdude15:05:25

I can sympathize with that

emccue15:05:16

^ in debugging :some.ns/email-blast is still straightforward to track down. say if these are put into re-frame state or something

dpsutton15:05:18

previous codebase would use (declare foo) above macros that def'd things to get around static limitations like that. one benefit of nrepl for sure

borkdude15:05:07

I think the spec or malli way of doing that might be to define an "enum" of keywords, like (s/def const #{::email-blast})

borkdude15:05:00

anyway, each their own

Drew Verlee15:05:15

Given the tools available currently (cider, paredit-functionality, LSP, clj-kondo, RDD) what language feedback features is Clojure lacking? e.g I feel like project wide refactors (e.g rename) are now reliable with LSP, a big missing piece. I'm left curious what else is out there?

emccue15:05:02

more off topic

emccue15:05:12

insert-or-update has upsert

emccue15:05:27

is there an equivalent shorthand for get-or-create?

vemv15:05:58

put-if-absent is used from time to time

emccue16:05:39

that saves 0 letters though

😆 3
vemv16:05:29

yeah it's simply that is has a standardized meaning I think the JCIP book uses it

Alex Miller (Clojure team)16:05:03

is a good word for get-or-create

emccue16:05:49

hmm, so at least to me usage with that would be

emccue16:05:13

(ensure-thing-created ...)
(let [thing (get-thing ...)]
  ...)

emccue16:05:26

like it doesn't imply that the thing will be returned

dpsutton16:05:10

(doc ensure-thing-created) <- yes it does

souenzzo16:05:34

@alexmiller is "docstrings for keywords" a thing? I mean, it will be implemented in the future? Or it's not implemented because it's not a good idea? If this is implemented, it will be a "clojure" feature or a "spec" feature?

henrik12:05:18

You could def your keyword as a symbol and give that a docstring.

Alex Miller (Clojure team)17:05:17

it's not a thing, and will not be implemented in the future

Alex Miller (Clojure team)17:05:37

keywords are shared (interned) and may be used for more than one thing

Alex Miller (Clojure team)17:05:59

docstrings for specs may be implemented in the future

👍 6
Alex Miller (Clojure team)17:05:51

that's a narrower context (I would not expect those to be stored on the keyword, but rather available via some api)