Fork me on GitHub
#clojure-norway
<
2023-08-26
>
teodorlu16:08:28

En lørdagstanke. Hvis du skal gjøre ikke-påkrevde tilpasninger på kode, er det fint å bruke binding og dynamiske variabler. Hvis koden må ha argumenter for å fortsette å kode, bør du sende inn et parameter. Å legge på en cache for kode som kjører fint uansett er OK å gjøre med binding fordi det funker fint uten cache. Databasetilkobling skal ikke være satt i en dynamisk variabel — uten den kjører ikke koden, derfor bør den være en eksplisitt parameter. Enig/uenig?

anders17:08:37

På generelt grunnlag er jeg veldig skeptisk på å benytte thread-locals (som binding er) til å styre noen form for flyt. Selv en cache (med unntak av evigvarende "memoization") er med på å gjøre koden din impure. Om cachen står foran noe som uansett er impure (som kanskje er det mest naturlige) er jeg fortsatt skeptisk. Jeg er veldig glad i la parametre styre flyt og ikke noe magisk thread-local som plutselig kommer inn fra siden langt nedi callstack'n. Om du skal bruke binding, husk å realisere all data du eventuelt henter ut og som er påvirket av bindingen inne binding-uttrykket. Returnerer du en lazy seq som utfører operasjoner som hviler på bindingen din så har du noen overraskelser i vente. Når det er sagt er binding et fint verktøy. Jeg har for eksempel brukt binding for å legge ved nyttig verdier (f.eks. korrelasjons-id'er) til loggerammeverket så jeg slipper å forholde meg til dette overalt hvor det logges.

👍 8
anders17:08:22

Nå er jeg ikke noe fan av stubbing heller, men enkelte ganger er det vanskelig å komme unna. Da er jo binding et greit verktøy (https://github.com/magnars/stubadub)

leifericf18:08:34

"You should treat stubbing your code much like stubbing your toe: It's painful and you should strive to avoid it." —@U07FCNURX 😂👏

😂 8
anders18:08:54

Ikke engang stubadub bruker binding lenger kom jeg på 😅

cjohansen18:08:24

Enig med @U0ESP0TS8 og tilføyer at binding er en sånn ting som nok er mest nyttig i biblioteker, og selv der svært sparsomt

anders18:08:42

Fortsatt skeptisk 😅

cjohansen18:08:08

Jeg tror bindings stammer fra Clojures barndom. Printgreiene bruker det feks. Print-greiene til Clojure er ikke det mest imponerende i språket.

teodorlu18:08:53

Hvordan kunne print-greier vært løst bedre? Feks *print-namespace-maps* og *out*.

teodorlu18:08:32

Det er ganske mange dynamiske variabler i core, fra http://clojure.github.io/clojure/clojure.core-api.html#clojure.core/*agent* og nedover

cjohansen18:08:56

Mye av det er fra tidlig

cjohansen18:08:26

Det er ganske vilt at det er noen ting man må binde out for å kunne gjøre

cjohansen18:08:41

pprint til en streng feks

teodorlu18:08:25

ja — jeg har skrevet (with-out-str (clojure.pprint/pprint my-data)) flere ganger enn jeg skulle ønske

teodorlu18:08:09

det overrasker meg egentlig litt at det ikke finnes noen clojure.pprint/pprint-str. Vi har jo pr-str og prn-str.

cjohansen18:08:08

Ja, det er mye det som skrangler litt

augustl05:08:44

når Clojure var nytt husker jeg det var helt vanlig å bruke binding for config og sånt i Ring, i stedet for å bare putte det på request-mappet

augustl05:08:33

Ring sin dokumentasjon i 2010 :)

teodorlu08:08:29

Kult! Ja - kode på request-mappet blir mer eksplisitt. I alle fall når du skriver koden som legger noe på request-mappet, og når du skriver koden som henter ting ut av request-mappet.

augustl12:08:22

i starten tenkte jeg at det er feil å putte ting som ikke har med et request å gjøre på request-mappet. Det var den gangen jeg var vant til OO og så på maps som aggregater, ikke data :)

👍 1
teodorlu14:08:46

Synes også det er skikkelig fint at man får mange funksjoner som tar inn ett argument: en request (med ekstra greier). Hvos man skal begynne å sende med ekstra greier som ekstra argumenter, blir det mye mer ... styr i koden. Og da blir det fristende å putte ting "på siden" - og man slutter å skrive funksjoner som tar inn argumenter og gir tilbake verdier. Som @U04V5VAUN var innom på fredag! https://clojurians.slack.com/archives/C061XGG1W/p1692955976169749?thread_ts=1692955976.169749&amp;cid=C061XGG1W Jeg lærte først FP med Haskell, og akkurat denne tingen synes jeg "luktet feil" lenge. Fordi det er vanskelig å "request og ekstra ting man kan trenge".

slipset06:08:55

Jeg tror at den tidlige bruken av bindings i Clojure (og biblioteker) er en arv fra Common Lisp? Hele condition systemet til CL er såvidt jeg kan forstå/huske bygget over dyn-vars. Man må også huske på at CL ikke nødvendigvis er et programmeringsspråk der man programmerer funksjonelt 🙂

👍 6
teodorlu07:08:35

Sant. Jeg prøvde meg litt på boka "Land of Lisp", der man skriver spill i Common Lisp. I det første spillet tar man input fra brukeren. Da bruker man defparameter. Jeg synes det var litt rart å "def-e" det, i stedet for å ta input til funksjoner - så man kan skrive tester som funksjonskall.

augustl07:08:37

sant, det har aldri gitt mening for meg når folk sier de “programmerer i Lisp”, for meg høres det ut som “programmerer i et språk med C-style syntax”, aka det sier meg omtrent ingenting

teodorlu07:08:22

History of Clojure har noen interessante betraktninger om designvalg clojure deler med (Common) Lisp. Så litt på den over helga. Rich har skrevet rasjonale for valgene han gjorde i clojure 1.0, samt da defprotocol kom i 1.2. https://clojure.org/about/history

augustl07:08:38

aaaah må få lest den der

teodorlu07:08:17

Anbefales! I alle fall de korte rasjonale-avsnittene.

teodorlu07:08:59

Jeg fikk mer ut av å lese PDF-en enn å se på konferanse-presentasjonen.