Fork me on GitHub
#clojure-europe
<
2021-04-24
>
slipset08:04:16

Listening to the defn podcast with @viebel I think that an error many devs do when it comes to types is that we tend to be too specific, ie we talk about a “user” when we should have talked about “identifiable”. At least in our current codebase the specific types (like “user”) don’t travel too far nor between many namespaces, whereas the more general types (like “identifiable”, “subject”, etc) do.

dominicm08:04:56

I'll add another similar one ^ - writing functions that operate on whole data structures instead of just a part of that data. e.g. add-age - takes a user and returns an updated user with the age calculated from their birthday. Instead write (age) which takes a date and returns the age as of now. This is known as stamp coupling. It's a "low" form of coupling, but it's still annoying. :D

slipset08:04:16

Yes! it would be interesting with a fn like derive, eg (derive user :age :date-of-birth age)

slipset08:04:16

which would take the :date-of-birth of a user, pass it to age and then assoc the return value onto the user under :age

slipset08:04:37

(defn derive [m derived-key value-key derivation] (assoc m derived-key (derivation (get m value-key)))

dominicm08:04:53

I happen to know someone who has written exactly what you're after @slipset :) https://github.com/riverford/mappings

dominicm08:04:41

I guess lacking the specific merge functionality, which surprises me.

pez08:04:57

Morning. I'm not following completely about stamp coupling. Can you explain it like if I am five?

slipset08:04:32

Not familiar with that term specifically, but in general, one is completing the what with the where.

slipset08:04:56

So at work we have some nested datastructures, consider a user with an address with a street:

{:name "Pez"
  :address {:street "Fina Gatan 3"}}
Now, how do you write the function which updates the street of a user?

slipset08:04:18

I just realize that this example is terrible, as it’s basically an (update-in user [:address :street] bla), but if the structure was more complex, say :addresses instead of :address it would be better to have a update-address fn which could be called on any address, not just the one which was inside the user

pez09:04:12

Hmm. I now feel guilty of this crime in squares.

pez09:04:04

You came amazingly close to the address where i grew up, btw.

slipset09:04:25

I discussed this at ClojureD last year https://www.youtube.com/watch?v=Tq7r97G4b7Y at 15:54

metal 6
❤️ 3
otfrom16:04:44

good talk. thx for doing it

slipset16:04:57

Thank you!

reefersleep10:04:34

Good morning 🙂

dominicm11:04:16

i studied coupling/cohesion when I was developing clip. I read "composite/structured design" by Myers: https://en.wikipedia.org/wiki/Special:BookSources?isbn=9780442805845 In that book he outlines levels of coupling & cohesion and how they're found. Myers & Constantine laid most of the foundation for understanding how software systems are tied in this way. Their work is an interesting read to articulate things that have become programming lore/intuition. Wikipedia has the same information & more around OO programming. I'm not sure on the origins of those though. https://en.wikipedia.org/wiki/Coupling_%28computer_programming%29#Types_of_coupling

dominicm11:04:45

@pez to actually answer your question 😁 Stamp coupling is when you're coupled by extraneous information and data. The classic example would be my above add-age. It's the second-weakest form of coupling, the weakest (best) form being "data coupling" - which is the age function I outlined - it takes the minimal value required. Ring request stuffing in middleware (shoving dbs, kafka conns, current timestamp, parsed data, event streams, clocks, etc. etc.) is a form of stamp coupling. My belief is that this contributes to the lack of "rails on clojure" - it's so hard to reuse ring stuff because it's so entangled with your specific request map.

pez11:04:04

Thanks, both of you! ❤️