Fork me on GitHub
#clojure-norway
<
2023-09-08
>
slipset07:09:17

Jeg lurer på om jeg skal velge meg følgende arrogante påstand: Du får ikke lov til å kode i et sterkt typet språk før du viser at du kan kode i et dynamisk typet språk.

teodorlu08:09:39

Ooooh Dette minner mistenkelig om en magefølelse jeg har: "når du lærer deg å strukturere kode skikkelig i clojure, klarer du å gjøre det i alle språk, fordi du ikke bruker støttehjul i clojure. Navnerom, navn, operasjoner og data er alt du trenger"

teodorlu08:09:46

Føler at denotational design / skriv typer på data og typer på operasjoner mellom typer før du begynner å kode også er et plausibelt motargument. Men dette er kun noe jeg har sett i Elm-kode og Haskell-kode.

slipset08:09:19

Det som jeg tror jeg savner litt er konkrete eksempler på “OMG hvis jeg ikke hadde typer her så ville alt gått til helvete”. Som regel så er reaksjonen min på det “shrug, ikke skriv koden sånn”.

slipset08:09:03

Ramla over følgende kode hos oss:

export function registerForFilterChange(
  this: {
    _throttledFilterChangeCallback?: (payload?: { filter?: Filter }) => void;
  },
  callback: (filter?: Filter | Record<string, never>) => void,
  updateWhenInactive: boolean
) {
  this._throttledFilterChangeCallback = throttle(
    (payload?: { filter?: Filter }) => {
      if (shouldViewUpdate(this as ViewPlugin, updateWhenInactive)) {
        callback(payload ? payload.filter : {});
      }
    },
    THROTTLE_TIME,
    { leading: false }
  );

  [notifyFiltersChanged, setActivePerspective].forEach(action =>
    subscribeToAction<any>(action, () => this._throttledFilterChangeCallback!())
  );
}
Typechecker som bare det, men er fortsatt umulig å lese. Det viste seg at dette kunne splittes opp i to distinkte use-caser, hvorav den ene ble slik:
private registerForFilterChange() {
    const throttledFilterChangeCallback = throttle(
      () => {
        this._dispatchTreeChanged();
      },
      THROTTLE_TIME,
      { leading: false }
    );

    subscribeToAction(notifyFiltersChanged, () =>
      throttledFilterChangeCallback!()
    );
    subscribeToAction(setActivePerspective, () =>
      throttledFilterChangeCallback!()
    );
  }

slipset08:09:04

Dette kunne gjøres fordi ved a lese callsite så man at throttle dingsen aldri ble kalt med parametre, så alt av typer kunne bare fjernes.

leifericf08:09:37

"Du får ikke lov til å sykle med støttehjul før du viser at du kan sykle uten støttehjul," hehehe.

😄 2
slipset08:09:00

Mine barn har aldri syklet med støttehjul

🚲 2
🔥 6
slipset08:09:40

Og grunnen til det er at du lærer deg fantastiske uvaner når du gjør akkurat det.

💯 4
leifericf08:09:47

Men det er et godt poeng bak analogien: Hvis man lærer uten, trenger man dem aldri.

slipset08:09:56

Løpesykkel er måten du bør lære å sykle på.

leifericf08:09:25

Det med løpesykkel har jeg hørt fra flere! Det kommer vi til å kjøre også.

leifericf08:09:58

Hvis sterkt typede språk er som sykkel med støttehjul, er dynamisk typede språk er som sykkel uten støttehjul, hva er så løpesykkelen i denne analogien? Er det språk med såkalt "optional" eller "gradual" typing, som f.eks. TypeScript, Elixir og Mojo?

leifericf08:09:02

Med clojure.spec kan en kanskje også argumentere for at Clojure har "optional" eller "gradual" types.

odinodin10:09:55

😂 14
❤️ 7
4
teodorlu11:09:50

Plassen jeg jobber er det mye TypeScript og lite Clojure. Vi fikk to nyansatte utviklere første august. Jeg har brukt mye tid sammen med dem, og vi har jobbet på Clojure. Ingen hadde brukt Clojure før. Vi kjørte en retrospektiv i går, og de sa hva de hadde syntes om tiden i starten. Clojure kom opp. “Ja, Teodor liker Clojure. Det har vi fått med oss!“. Men også “Skulle ønske vi kunne brukt Clojure litt mer, da.” og “nå tar jeg meg i å trykke cmd+endter på javascript-kode for å prøve å evaluere toplevel form og se hva som skjer” (jeg skriver om for å legge på litt kontekst her). Så … to nye personer som har ramlet ned i hullet? 😅

💪 4
😄 2
❤️ 4
slipset11:09:48

Her er råd jeg ga til en kollega: > Here is how I like to think about it: > 1. Even though I don’t care about performance, i believe that the render function of a react component should do as little as possible so that it can be as fast as possible. For this to happen, you need to do stuff outside of render and have tailor-made props for the component. > 2. Even though we don’t write tests, write the code as if it were possible to unit test it. If you have a bunch of logic inside your render function that’s harder to test. If you have a fn which takes some data and returns some data which you then pass to your react component as props, you could trivially unit test it. > 3. Even though we’re not going to replace React with something else any time soon, make sure that you write code in such a fashion that such a replacement would be as easy as possible. > IMO, if you follow these three things, a lot of good stuff happens.

💯 2
slipset11:09:05

Kanskje TS/React folka dine kan ha nytte av det samme.

👍 2
Jakub Holý (HolyJak)11:09:41

You are obviously evil, Teodor 🙂

😈 2
leifericf11:09:35

Haha, samme her @teodorlu! Flere på kontoret og LinkedIn har stemplet meg som "han fyren som aldri holder kjeft om Clojure."

❤️ 4
cjohansen11:09:26

Jeg fikk høre i går av en ny kollega at allerede før @magnars og jeg møtte opp på kontoret var vi kjent som "clojure-folka" 😂

😂 5
leifericf11:09:34

Et par av utviklerne som sitter ved siden av meg har sett på når jeg skriver Babashka scripts, og jeg har laget en intern GitHub template med en liten README.md how-to guide. Noen av dem har lyst til å prøve det ut. Jeg går og venter på muligheten til å lage en ny microservice fra scratch, og da skal jeg pitche Clojure for den.

👌 2
cjohansen11:09:34

"Så bra", sa jeg 😄

😄 4
leifericf11:09:36

Hahaha, du (@christian767) og @magnars er jo "Clojure-folka" her til lands. Mye pga. ZombieCLJ. Det er flere på kontoret her som vet hvem dere er pga. det.

cjohansen14:09:55

Stor takk til @slipset som posta foredraget mitt på news-kanalen, nå kom det med på deref-nyhetsbrevet ❤️

🎉 18
👏 2