Fork me on GitHub
#off-topic
<
2020-02-09
>
emccue02:02:51

I haven't used integrant before, but looking into it because of the conversation in the main channel

emccue02:02:38

its kinda interesting that component, mount, and integrant try and solve for resources using the dynamic parts of protocols, namespaces, and multimethods

emccue02:02:58

Is there something that doesn't use a global mechanism like that?

emccue02:02:37

like integrant, but instead of relying on multimethods, you supply a map with the info needed to start and stop components?

hiredman06:02:22

While protocols are global, in practice I find it doesn't come up, component identity is tied into their start and stop behaviors so taking a component and givimg it some other start and stop just doesn't make much sense

hiredman06:02:05

Hover component is extremely flexible, I've worked on projects that reconfigured it to work using multimethods on maps(hated that) and you can of course create a defrecord that satisfies lifecycle by calling functions you assoc in to it

hiredman07:02:52

It is crazy to me that anyone would choose mount, like, it is just global state with extra steps. It is bad, you can't build large understandable(deconstructable) systems with that. It is wild to me(having been a professional clojure programmer 10 years at the end of March) that someone would like clojure and also choose mount.

8
hiredman07:02:30

I found https://gist.github.com/pandeiro/9a1c8fd431e1b4c78c99 trying to dig up my ur component gist, which is a gist someone made of a big mount vs component discussion that I mostly try to avoid these days (not that I do a good job it), bit at least there someone who likes mount is having their say

dominicm08:02:16

I wrote juxt/clip in that way @U3JH98J4R. You apply start / stop as a list with the var and any parameters. (it looks like code, but it isn't).

dominicm08:02:05

I think that conversation missed a point a little. Integration tests are hard in that scenario, I've been on projects where the mandate was to only have integration tests. I do think there's a workflow or style gap that we can't see between us, due to proprietary code we don't share between us (the code at $job).

emccue02:02:03

(def system-config {:some-ns/db {:port 8000 :cache (ref :some-ns/cache)}
                    :some-ns/cache {:max-size 1000}}

(def system-implementation {:some-ns/db {:start make-connection :stop #(.stop %)
                            :some-ns/cace {:start (constantly {})})

(def system (boot-up-resources system-config system-implementation)) 

emccue02:02:47

I haven't used clojure in this sort of situation yet, but doing things like canary-ing out new configs to services was pretty routine when i was working

emccue02:02:41

so in that space integrant seems a bit mismatched with what I would probably have to do to support that requirement

emccue02:02:21

which would amount to treating config as an object which might update itself on another thread

emccue02:02:52

and be a stateful entity

hiredman07:02:52

It is crazy to me that anyone would choose mount, like, it is just global state with extra steps. It is bad, you can't build large understandable(deconstructable) systems with that. It is wild to me(having been a professional clojure programmer 10 years at the end of March) that someone would like clojure and also choose mount.

8
hiredman07:02:59

Didn't mean to spam the channel with me expressing incredulity at something that very obvious is a thing, but I just can't get over it

hiredman07:02:30

I found https://gist.github.com/pandeiro/9a1c8fd431e1b4c78c99 trying to dig up my ur component gist, which is a gist someone made of a big mount vs component discussion that I mostly try to avoid these days (not that I do a good job it), bit at least there someone who likes mount is having their say

lilactown15:02:50

I've often wished that there was something similar to React in Clojure-land w.r.t. composing "components" that are are abstracting over app functionality (not resources, like component / mount / integrant), that coordinate side effects in a top-down way, can be stored as a value, and can easily reload only the changed components

vemv16:02:37

At work we call those units of code "modules". A module has a Sierra Component, which represents app-specific functionality. It also may have specs, protocols, and even its own tests, inlined somehow. In our Sierra System we compose all kind of components together (e.g. old-style IO resources and business-concerned modules). i.e. one can achieve what you describe without inventing a lot of tooling (if only just conventions, like folder/ns organisation). Would love to elaborate on the topic but honestly I cannot say we've nailed down every single detail, i.e. there are still open questions. One day. I just shared something very related in #announcements btw :)

👀 4
lilactown17:02:48

neat, I'll check it out!

vemv17:02:07

Side-effect coordination is also part of our idea, which is why ideally a module would be written in .cljc That forces you to use protocols for side-effects, so the whole notion of side-effect is reified. So e.g. modules can communicate via Kafka in JVM clojure in production but via a core.async impl in CI. related read (not mine): http://widdindustries.com/cross-platform/

lilactown17:02:49

I think that the way React handles side effects, using essentially a user-land condition and continuation system, very nice for isolating, coordinating and composing side effects and is what I'd like to see explored on the server side

vemv17:02:45

:thumbsup: I've seen "what's a re-frame for Clojure backends?" asked a few times. Kafka seems to be the standard answer, which while not exactly wrong, it solves at the system level something that can also be solved at the 'language' level. (non-exclusive approaches)

vemv16:02:37

At work we call those units of code "modules". A module has a Sierra Component, which represents app-specific functionality. It also may have specs, protocols, and even its own tests, inlined somehow. In our Sierra System we compose all kind of components together (e.g. old-style IO resources and business-concerned modules). i.e. one can achieve what you describe without inventing a lot of tooling (if only just conventions, like folder/ns organisation). Would love to elaborate on the topic but honestly I cannot say we've nailed down every single detail, i.e. there are still open questions. One day. I just shared something very related in #announcements btw :)

👀 4
borkdude19:02:27

what's a good name for a linter that detects usages of (< x), (> x) etc, so comparisons which always yield the same boolean, due to single arguments. the name in the proposed PR is now :single-arity-comparison but single arity really means something else: a function with a single arity instead of multiple ones...

borkdude20:02:15

:single-arg-comparison?

vemv20:02:34

:thumbsup: single-operand-comparison also

borkdude20:02:58

sounds good

hindol20:02:37

Maybe :constant-condition? Also :constant-predicate.

borkdude20:02:05

or :constant-comparison

hindol20:02:27

I like yours better!

borkdude20:02:27

That name might also be confusing since you can interpret it as comparing constants (e.g. (< 4 5))

p-himik20:02:56

(+ 1) falls somewhere nearby. Maybe it makes sense to combine all such cases under a single umbrella?

p-himik20:02:02

Other similar functions: dissoc, disj, conj.

borkdude21:02:38

those examples behave as the identity function, while (< x) always gives the same result, so it's close, but not the same

andy.fingerhut21:02:40

In mathematics, the word "degenerate" is often used for this kind of thing, where a general thing becomes trivial/uninteresting when you reduce it to its smallest size possible (smallest number of args in this case).

andy.fingerhut21:02:06

It would make sense in a linter if you wanted different names for different "kinds" of these things.

borkdude21:02:13

:degenerate-call?

andy.fingerhut21:02:37

That would be a name if you wanted to put as many of these kinds of things under the same error message.

borkdude21:02:05

I tend to avoid the word :suspicious-x since almost anything a linter complains about is suspicious

andy.fingerhut21:02:10

But I can see why a developer might prefer different messages for different cases you are thinking about and mentioning above.

borkdude21:02:52

yeah, I think it might be good to split this into multiple different things, that also gives more options for configurability

andy.fingerhut21:02:12

Good short names are a pleasure to find, of course, and I may not be the most helpful in discovering those. I would recommend that whatever messages you have, having an easy way to find each message in the linter docs, and have a more full description of why the message was given, when that kind of code might be a problem, vs. when it is maybe what you intended anyway, how to disable it, etc. is goodness (if someone wants to write such docs).

borkdude21:02:32

yeah, that's very handy and still something that has to be done, although you can also emit JSON or EDN where the name / key of the rule is printed

andy.fingerhut21:02:09

Certainly once a developer has seen a name / key, good ones will help remind them of the meaning when they see them again, without having to go back to the docs, so I am all in favor of your finding good descriptive names.

andy.fingerhut21:02:22

Only :warning would be a very frustrating linter indeed 🙂