off-topic

https://github.com/clojurians/community-development/blob/master/Code-of-Conduct.md Clojurians Slack Community Code of Conduct. Searchable message archives are at https://clojurians-log.clojureverse.org/
craftybones 2021-05-05T08:55:02.453900Z

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

Aron 2021-05-05T10:23:36.454900Z

How about variable/dynamic?

Thomas Moerman 2021-05-05T13:17:12.458100Z

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.

emccue 2021-05-05T13:18:32.458300Z

I would do this

emccue 2021-05-05T13:18:54.458900Z

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

emccue 2021-05-05T13:19:13.459100Z

then use the var

ghadi 2021-05-05T13:20:17.459500Z

bad idea to have vars proxying to keywords.

➕ 2
ghadi 2021-05-05T13:21:02.460300Z

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

😅 2
ghadi 2021-05-05T13:21:45.461Z

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

ghadi 2021-05-05T13:21:54.461300Z

which might include a docstring, might include other stuff too

lilactown 2021-05-05T14:19:50.462900Z

what's wrong with vars proxying keywords?

alexmiller 2021-05-05T14:20:34.463300Z

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

alexmiller 2021-05-05T14:20:59.463800Z

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

lilactown 2021-05-05T14:21:37.464Z

hmm ok

lilactown 2021-05-05T14:24:00.466400Z

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])

lilactown 2021-05-05T14:24:44.468Z

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

alexmiller 2021-05-05T14:25:01.468600Z

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

vemv 2021-05-05T14:25:43.469800Z

@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

👍 1
lilactown 2021-05-05T14:26:48.470700Z

mainly helps prevent typos via compiler warnings 😄

lilactown 2021-05-05T14:27:08.470900Z

and go-to definition

lilactown 2021-05-05T14:27:26.471200Z

sounds like tooling is catching up to those tho

vemv 2021-05-05T14:28:46.472300Z

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)

borkdude 2021-05-05T14:37:15.472800Z

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

borkdude 2021-05-05T14:38:25.473100Z

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

emccue 2021-05-05T14:45:10.473600Z

If you def the keyword, you get jump to definition

emccue 2021-05-05T14:45:43.474Z

and also you can list out "possibilities"

emccue 2021-05-05T14:46:07.475Z

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

borkdude 2021-05-05T14:46:12.475300Z

@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

borkdude 2021-05-05T14:46:40.475800Z

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

emccue 2021-05-05T14:47:44.476500Z

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

emccue 2021-05-05T14:48:24.477300Z

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

emccue 2021-05-05T14:49:55.478200Z

I don't always do it for sure

emccue 2021-05-05T14:50:51.479200Z

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

emccue 2021-05-05T14:51:22.479900Z

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

borkdude 2021-05-05T14:52:05.480600Z

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.

emccue 2021-05-05T14:52:15.480800Z

does it work with cursive?

borkdude 2021-05-05T14:52:35.481400Z

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

emccue 2021-05-05T14:53:12.482200Z

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-*

emccue 2021-05-05T14:53:40.482800Z

strawman example

borkdude 2021-05-05T14:53:52.483500Z

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

borkdude 2021-05-05T14:54:05.484Z

it's pluggable though using clj-kondo hooks

emccue 2021-05-05T14:55:54.485700Z

(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 { ... })

emccue 2021-05-05T14:56:59.486700Z

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

borkdude 2021-05-05T14:57:18.487500Z

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.

emccue 2021-05-05T14:57:50.488300Z

(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 { ... })

emccue 2021-05-05T14:58:18.488600Z

at least in this case I just mean constants

borkdude 2021-05-05T14:58:31.488900Z

a keyword is already a constant :)

emccue 2021-05-05T14:58:42.489200Z

so is a list [1 2 3]

emccue 2021-05-05T14:59:02.489900Z

I mean constants not in the "unchanging value" sense

borkdude 2021-05-05T14:59:05.490100Z

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

emccue 2021-05-05T14:59:24.490400Z

but in the "finite set of flags" sense

emccue 2021-05-05T14:59:30.490600Z

if that tracks

ghadi 2021-05-05T14:59:59.491200Z

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

borkdude 2021-05-05T15:00:24.491800Z

deffinitaly :)

ghadi 2021-05-05T15:00:29.492200Z

lol

borkdude 2021-05-05T15:01:41.493100Z

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

emccue 2021-05-05T15:02:00.493500Z

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

emccue 2021-05-05T15:02:02.493700Z

and yet...

borkdude 2021-05-05T15:02:25.494400Z

I can sympathize with that

emccue 2021-05-05T15:03:16.495900Z

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

dpsutton 2021-05-05T15:03:18.496Z

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

borkdude 2021-05-05T15:04:07.497Z

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

borkdude 2021-05-05T15:05:00.497300Z

anyway, each their own

2021-05-05T15:29:15.002100Z

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?

emccue 2021-05-05T15:57:02.002900Z

more off topic

emccue 2021-05-05T15:57:12.003200Z

insert-or-update has upsert

emccue 2021-05-05T15:57:27.003600Z

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

vemv 2021-05-05T15:59:58.004200Z

put-if-absent is used from time to time

emccue 2021-05-05T16:01:39.005100Z

that saves 0 letters though

😆 1
vemv 2021-05-05T16:02:29.005700Z

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

alexmiller 2021-05-05T16:02:50.006200Z

ensure

alexmiller 2021-05-05T16:03:03.006500Z

is a good word for get-or-create

emccue 2021-05-05T16:04:49.007300Z

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

emccue 2021-05-05T16:05:13.007900Z

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

emccue 2021-05-05T16:05:26.008300Z

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

dpsutton 2021-05-05T16:07:10.008600Z

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

souenzzo 2021-05-05T16:29:34.011600Z

@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?

henrik 2021-05-06T12:27:18.026900Z

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

alexmiller 2021-05-05T17:09:17.011900Z

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

alexmiller 2021-05-05T17:09:37.012300Z

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

alexmiller 2021-05-05T17:09:59.012600Z

docstrings for specs may be implemented in the future

👍 2
alexmiller 2021-05-05T17:10:51.013500Z

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