Fork me on GitHub
#clojure-norway
<
2022-06-28
>
slipset08:06:37

Hmm, lurer på om jeg ikke skal forsøke det gode gamle #clojure-europe trikset: God morgen!

mariuene08:06:37

God morgen!

cjohansen08:06:13

Good morning!

cjohansen08:06:51

Hva er målet egentlig? Ser ut som om #clojure-europe har lykkes i å få sin kanal til å hovedsakelig bestå av “good morning” 😁

slipset09:06:01

For meg har det gitt en veldig hyggelig følelse av tilhørighet. Det er også et sted der jeg føler at jeg kan stille dumme/rare spørsmål blant venner som antar at slike spørsmål er stilt i beste hensikt.

slipset09:06:46

Men, ja, som oftest er det bare masse good morning, men i blant blir det noe fint ut av det.

1
cjohansen09:06:34

Jada, fint tiltak!

cjohansen09:06:45

Innser at kommentaren min fremstår mer surmaget enn den var ment som

slipset09:06:10

Noen må jo ha den rollen også 🙂 Uansett. Jeg tror målet er oppnådd 🙂

magnars09:06:21

God morgen, ja 😄

teodorlu10:06:42

(hvor lenge er det lov å si god morgen?)

magnars11:06:27

> Universal Greeting Time, an Internet Relay Chat convention whereby a person who joins a conversation is greeted "Good morning" and a person who leaves is bidden "Good night", regardless of the time zones of participants.

❤️ 1
slipset12:06:40

Ok, så her kommer et sånt spørsmål, eller noe. Gitt at vi er i et multithreaded miljø:

(defn sideffecting-expensive-operation [label]...)

(defn setup [some-atom label]
  (let [r (sideffecting-expensive-operation label)]
    (swap! some-atom assoc label r)))
Problemet med det over er at nå kan den tunge operasjonen bli kalt flere ganger for samme label En løsning:
(defn setup [some-atom label]
 (let [r (delay (sideffecting-expensive-operation label))]
    (swap! some-atom (fn [m] (if (contains? m label) m (assoc m label (force r))))))
Men det gir jo også litt sånn vond smak i munnen.

slipset12:06:52

Grunnen til at vi ikke kan gjøre:

(defn setup [some-atom label]
   (swap! some-atom (fn [m] (if (contains? m label) m (assoc m label (sideffecting-expensive-operation label))))))
er jo at funksjoner til swap! kan bli kalt flere ganger og skal derfor ikke være sideffecting.

msolli12:06:03

Kan du memoize sideffecting-expensive-operation? Det hindrer ikke at den kan bli kalt flere ganger samtidig hvis setup kalles flere ganger samtidig, riktignok.

slipset12:06:36

Jeg lurte litt på det….

msolli12:06:07

Hvis du vil garantere at sideffecting-expensive-operation aldri kjører samtidig for samme verdi av label kan du bruke locking:https://clojuredocs.org/clojure.core/locking

msolli12:06:25

Tilsvarer synchronized i Java.

Ivar Refsdal12:06:37

Ein kan nytta fnil...?

(defn setup [some-atom label]
  (let [r (delay (sideffecting-expensive-operation label))]
     (swap! some-atom update label (fnil force r))))
om eg liker den koden: tja, tja, tja... Men ikkje så heilt verst, eller?

slipset12:06:19

Sant nok, men det var delay/`force` jeg ville unngå

Ivar Refsdal13:06:43

Kva med locking som msolli føreslo?

(defn setup [some-atom label]
  (locking some-atom
    (when (nil? (get @some-atom label))
      (swap! some-atom assoc label (sideffecting-expensive-operation label)))
    @some-atom))
Vakkert var det ikkje

Jakub Holý (HolyJak)13:06:40

That's what I proposed. Cons is you now lock on the whole atom, limiting concurrency more than necessary. But it might well be acceptable...

magnars14:06:38

Kan du ha et atom med future's i?

magnars14:06:37

(swap! some-atom assoc label (delay (sideffecting-expensive-operation label)))

magnars14:06:43

og så deref'e den ved bruk?

magnars14:06:03

Hvis du er bekymret for at den blir assoc'et på flere ganger, så kan du trygt gjøre

(swap! some-atom update label #(or % (delay (sideffecting-expensive-operation label))))

👀 1
magnars14:06:27

☝️ denne tåler å bli kjørt mange ganger

magnars14:06:01

Dette var løsningen vi havnet på hos Norled, i hvert fall, etter en del diskusjoner her på Slack'en.

teodorlu14:06:13

Er det viktig her om man bruker future eller delay? Future betyr kanskje at man starter å regne ut svaret ved første kall til swap!, uten å vente på første deref?

magnars14:06:08

i så fall vil du unngå det

👍 1
magnars14:06:11

hvis du vil starte prosessen med det samme, så er det bedre å gjøre noe slikt:

(-> (swap! some-atom update label #(or % (delay (sideffecting-expensive-operation label))))
    (get label)
    deref)

❤️ 2
magnars14:06:32

for da er du sikker på at du er ferdig med Compare and Swap når du sparker den i gang 🙂

✔️ 1
teodorlu14:06:42

ahhh, ja. Sant. Fint å slippe race conditions.

teodorlu14:06:38

Kjempefint spørsmål, Erik. Har lurt på det samme før selv.

teodorlu14:06:58

Jeg synes primitivene i Clojure er kjempebra, men det tar tid å lære seg å sette dem sammen på en god måte