Fork me on GitHub
#clojure-norway
<
2023-06-26
>
cjohansen06:06:00

Jeg starter dagen med en kaffe og @teodorlu (på tysk!) https://youtu.be/VJbLxRVOxuQ

🇩🇪 8
🎉 6
leifericf07:06:23

Guten Morgen meine genialen Freunde.

cjohansen07:06:11

Kjempekult foredrag @teodorlu! Hadde du ikke annonsert at du var så nervøs hadde ingen plukka det opp 😄 Hvordan er en memex annerledes fra en wiki?

😄 2
slipset17:06:41

Henger meg forøvrig på @christian767s ros. Veldig bra foredrag, du er engasjerende på scenen, har en type talk som jeg liker, du presenterer noe som er på siden av Clojure, men som likevel har litt med det å gjøre. Du burde forøvrig skaffe deg en klikker så du ikke er låst til maskina for å bytte slide. Slidene dine var drit bra!

❤️ 2
teodorlu17:06:34

Takk, setter pris på det! Enig om klikker. Jeg kjøpte én, men den var upålitelig på Linux. Ref nerver - med så utrolig flinke folk i publikum føltes det å gå på scenen å skulle snakke om hypertekst litt rart. Dette er det folk i salen som kan bedre enn meg. Og jeg har aldri presentert for Clojure-folk før. 🙌🙌

slipset18:06:16

Husk at uansett hvem som er i salen, uansett hvile flinke de er, så er det din talk, din historie. Ingen andre kan fortelle den. Det er også konferansen som har akseptert talken, så hvis du holder det du lovet i abstractet, så er du trygg. Mitt eneste ønske når jeg gir en talk er at jeg håper folk ikke kjeder seg.

👍 4
cjohansen14:06:56

Har sett foredraget til Neil Ford om å lage foredrag. Veldig bra 👏 han pratet litt om livekoding, der fikk jeg en liten idé. Han snakker om at man bør unngå livekoding hvis det blir mye oppsett og fluff som ikke handler om poenget man vil formidle. Jeg tenker at dette er en knallgod litmustest for et stykke tech: lar dette seg live-kode? Bra mål på hvor mye "incidental complexity" som følger med

👍 8
teodorlu14:06:33

> lar dette seg live-kode? Bra mål på hvor mye "incidental complexity" som følger med Enig! Hvis det lar seg demonstrere godt på noen minutter, kan det være noen minutter som er fine å bruke. Jeg lurer ofte på "men hvordan er dette egentlig?". Ref https://gist.github.com/adamwiggins/5687294#make-it-real (Adam Wiggins): > Ideas are cheap. Make a prototype, sketch a CLI session, draw a wireframe. Discuss around concrete examples, not hand-waving abstractions. Don't say you did something, provide a URL that proves it.

👍 2
cjohansen14:06:36

"Will it live code?" Ny screencast for review av programmeringsspråk og rammeverk 😁

😁 2
clojure-spin 4
isak14:06:15

Hmm, ville ikke RoR og andre frameworks med masse magic være bedre for det en Clojure?

teodorlu15:06:51

Det spørs jo litt hva du ønsker å vise fram! Man kan få en ekte blogg opp på beina fort med ruby on rails! Se feks https://www.youtube.com/watch?v=Gzj723LkRJY. Men i den videoen hopper forfatteren (https://dhh.dk/) over mange ting. Den lærer ikke akkurat bort Ruby. Da ville jeg heller sett på noen jobbe i REPL. Feks https://youtu.be/XDjBtkd4orw?list=PLaN-rC-CjQqDu1AVhGdGOoEqsSAhd2W6t&amp;t=709. Her skjer det ingen kodegenerering, han skriver ("henter fra historikken") all koden han bruker. Mer fokus på koden ("koden er ekte"), mindre fokus på "produktet". Eller https://youtu.be/KKvancXJJJg?list=PLaN-rC-CjQqDu1AVhGdGOoEqsSAhd2W6t&amp;t=221.

cjohansen16:06:40

Gyldig poeng @U08JKUHA9! Så livekoding er en forutsetning, men ikke tilstrekkelig alene.

isak17:06:42

@teodorlu Ja, den fra DHH er vel en av de mest kjente live-coding sessions. Jeg tenker egentlig at det er lett å forbedre 'live-coding/demo vennlighet' via å legge til kompleksitet. Et parr andre eksempler hvor dette skjedde (i min mening): • react med JSX (i stedet for vanlig js - React.DOM, eller andre js teknikker). • GraphQL med GraphQL query språket (i stedet for vanlig JSON).

cjohansen17:06:38

Jeg har live-koda med React.DOM uten problemer!

cjohansen17:06:26

Men ja, ser poenget ditt. Min tanke var først og fremst at dersom det å live-kode noe blir for mye stuk og styr, så er det et signal om det du driver med er stukete (feks Java, innfløkte rammeverk, osv)

👍 2
isak17:06:33

Ja. Så det spørs jo på audience om det er en forbedring eller ikke, men de fleste foretrekker vel JSX selv om det er dumt.

cjohansen17:06:48

Jeg har aldri forstått apellen til JSX

augustl19:06:40

hvordan ville React i JS sett ut om man ikke hadde JSX egentlig? Jeg har blitt så vant til JSX i JS/TS at jeg ikke tenker over det noe særlig

isak19:06:12

Et lite eksempel:

...
render: function () {
      return d.input({
        className: "noselect",
        ref: "field",
        type: "checkbox",
        onChange: this.onChange,
        checked: this.state.checked,
        disabled: this.props.disabled,
        onKeyUp: this.onKeyEvent,
        style: { cursor: this.props.disabled ? "not-allowed" : "pointer" },
      });
    }
...
d er React.DOM. Eller noen tar denne:
var h = require('react-hyperscript');
var React = require('react');

var AnotherComponent = require('./another-component');

module.exports = React.createClass({
  render: function render() {
    return (
      h('div.example', [
        h('h1#heading', 'This is hyperscript'),
        h('h2', 'creating React.js markup'),
        h(AnotherComponent, {foo: 'bar'}, [
          h('li', [
            h('a', {href: ''}, 'One list item')
          ]),
          h('li', 'Another list item')
        ])
      ])
    );
  }
});

cjohansen19:06:51

At noen foretrekker JSX-rælet fremfor det første eksempelet her er helt 🤯 for meg

2
infosophy07:06:42

Forventet fullt foredrag på tysk, jeg. Etter den reklamen (fra @christian767). 😁

😂 4
☝️ 2
cjohansen07:06:55

Det var det heldigvis (for meg) ikke 😄

teodorlu07:06:32

> Hvordan er en memex annerledes fra en wiki? > Jeg vil si at du kan bruke en Wiki som en memex. Putt informasjon inn, wiki-en lagrer informasjon, du kan få informasjon ut. Men jeg har aldri fått wiki-er til å funke helt for meg. Litt uklart hvor jeg skal begynne å skrive når jeg vil utforske noe. Vanskelig å gi noe en tittel før jeg helt vet hva det er. Og du får med deg mye greier. Kan ikke gjøre helt som du vil med HTML-en. Må ha en server. Grensesnitt for å skrive er det samme som grensesnitt for å lese. Men jeg har inntrykk av at en del av proffene som jobber med Wikipedia daglig får dette til på et godt vis! Synes Ward Cunningham Har laget mye spennende i senere tid også. Et av spørsmålene var "har du sett federated wiki?", og etter å ha gravd litt så det spennende ut. Federated Wiki: http://fed.wiki.org/view/welcome-visitors Eksempel på Federated Wiki i bruk: http://makecommoningwork.fed.wiki/view/welcome-visitors/view/commons

cjohansen07:06:02

Det er mange små forskjeller her. På en måte kan man jo også si “hvordan er wiki annerledes fra en webside?” 😅

👍 2
😅 2
teodorlu08:06:03

Jepp :) Tror feks vimwiki er basert på filer og Git. Er det fremdeles en wiki? I så fall, hva er en wiki? Og hvis filer og lenker kan være en memex, er Internett en memex? Jeg er i alle fall opptatt av prosessen med å bygge kunnskap ved å skrive ting ned og referere (lenke) til andre ting som andre har skrevet/laget!

augustl08:06:36

er iterasjonsrekkefølgen på sets stabil? :thinking_face: Altså om man itererer et sett to ganger, itereres det i samme rekkefølge? (Vil tippe at svaret er ja)

slipset16:06:57

Jeg tror/mener å ha hørt at dette er grunnen til at Sets i JS ikke har map/filter/reduce.

augustl08:06:37

denne testen får vel sies å være god nok, svaret er ja

(= 
  (into [] (set (range 0 100))) 
  (into [] (set (range 0 100))))
; => true

cjohansen09:06:01

sorted-set er en egen datastruktur, så jeg ville vært forsiktig med å gå for langt med den antagelsen

cjohansen09:06:15

Tipper du kan få forskjellig rekkefølge mellom forskjellig JVM-versjon feks

Zeniten09:06:29

God morgen!

augustl09:06:42

det var ifbm zipmap jeg lurte, så det skjer i samme run-time rett etterhverandre (og visste jo egentlig at det var sånn, siden man kan gjøre (keys m) to ganger og sende inn til zimpap)

leifericf09:06:57

I morgen er det en Clojure meetup i London (og online) som ser interessant ut, FYI. https://www.meetup.com/london-clojurians/events/292730420/

👍 2
leifericf13:06:19

Jeg forsøker å skrive en funksjon som kan dumpe hva som helst til en fil på disk:

(defn write-to-file
  ([filename lines]
   (let [default-path (str (babashka.fs/home) (:local/output-dir settings))]
     (write-to-file filename lines default-path)))

  ([filename lines path]
   (let [prefixed-filename (format "%s_%s" (get-filename-prefix) filename)]
     (if-not (babashka.fs/exists? path) (file/create-dir path) nil)
     (babashka.fs/write-lines (str path "/" prefixed-filename) [lines]))))
babashka.fs/write-lines bruker java.nio.file.Files/write, som krever en "seqable of strings." Hvordan kan jeg sørge for at lines-parameteret til funksjonen write-to-file alltid er en "seqable of strings?" Uansett hva jeg måtte finne på å sende inn der. Dette funker fint:
(write-to-file "test.txt" "Some file content.")
Men dette funker ikke nå:
(->> (find-in-files ["csproj"] "netcoreapp3.1")
     (write-to-file "test.txt"))
Fordi find-in-files returnerer en clojure.lang.LazySeq ; java.lang.ClassCastException: clojure.lang.LazySeq cannot be cast to java.lang.CharSequence

augustl13:06:43

vil tro at du sannsynligvis ikke vil gjøre [lines], men bare lines på siste linje

augustl13:06:05

i og med at lines er i flertall, så antar jeg at det er en seq med strings (en string per linje), men så wrapper du den i en vector, så da blir det en nøsta liste plutselig

augustl13:06:27

aka bør ikke denne funke fint: (write-to-file "test.txt" "Some file content.")

augustl13:06:46

men den bør snus om på så dette funker fint: (write-to-file "test.txt" ["Some file content." "Another line"])

leifericf14:06:28

Aha, ja, det funket fint med test vector av strings! Mange takk. Men det funker ikke med output av find-in-files, som er en liste av maps:

(defn find-in-file [file-path pattern]
  (->> file-path
       (file/read-all-lines)
       (map-indexed #(when (str/includes? %2 pattern)
                       {:directory (str (file/parent file-path))
                        :filename (file/file-name file-path)
                        :pattern pattern
                        :line (inc %1)
                        :column (inc (.indexOf %2 pattern))}))
       (filter identity)))
Output:
({:filename "A.csproj",
  :pattern "netcoreapp3.1",
  :line 4,
  :column 22}
 {:filename "B.csproj",
  :pattern "netcoreapp3.1",
  :line 4,
  :column 22}
 {:filename "B.csproj",
  :pattern "netcoreapp3.1",
  :line 4,
  :column 22}
 ...)

leifericf14:06:43

Er det "best practice" å konvertere den først til et format som babashka.fs/write-lines liker?

augustl14:06:21

vil tippe det - fint å ha en write-to-file som kan ta imot hva som helst, og ikke bare den map-strukturen der

augustl14:06:19

(->> (find-in-files ...)
     (map str)
     (write-to-file "test.txt")
typ, leser jo ganske greit. Tipper kanskje du vil skrive noe annet en string-versjonen av maps, men det ser du jo

leifericf14:06:23

Men er det lurest å konvertere parameteret inni selve write-to-file funksjonen, eller på utsiden før en kaller write-to-file? :thinking_face:

leifericf14:06:47

Aha! Er det ikke værre en å bruke map sånn, ja!

leifericf14:06:20

Ja, se der! Det gjorde jo susen!

augustl14:06:32

kunne også vurdert å endre write-to-file sånn at den med tre args tar [filename path lines]

augustl14:06:35

altså lines til slutt

augustl14:06:49

generelt er det greit å ha ting som tar lister med lista som siste argument, så det passer inn i threading macro

💡 2
augustl14:06:02

altså:

(->> (find-in-files ...)
     (map str)
     (write-to-file "test.txt" "/this/folder")

leifericf14:06:05

Åja, godt poeng!

leifericf14:06:52

Tusen takk for hjelpen, @U0MKRS1FX! Da lærte jeg noen nyttige ting i dag også 🙂 Scriptet begynner å ta form nå: https://github.com/leifericf/leifs-utils/blob/main/src/leifs_utils/git.clj Men jeg må rydde opp en del. Det er masse i git.clj som ikke har noe med Git å gjøre 😅 #lazyboy

leifericf14:06:09

Tror jeg skal lage mine egne fs og sh moduler.

augustl14:06:20

jeg ble inspirert på Clojure/west for mange herrens år siden, og tar kontroll på kaoset ved å ha et namespace som rett og slett heter homeless. Det oppleves som mere praktisk å være ærlig på at man ikke klarer å strukturere alt riktig, enn å prøve å få alt til å passe inn på “riktig” sted. Tror @U07FCNURX ofte har det namespacet og 🙂

😂 2
leifericf14:06:27

God idé, det! I podkasten "Functional Design in Clojure" prater karene on "fiddles." Men jeg har ikke prøvd det enda. https://clojuredesign.club/episode/014-fiddle-with-the-repl/

augustl14:06:00

umiddelbar første tanke er at navnet “fiddles” indikerer for meg at man tror at det noen gang kommer til å ryddes opp og at dette var en midlertidig plassering. Men noen ting er jo bare permanent hjemløse 🙂

leifericf14:06:50

I podkasten prater de om at "fiddles" på en måte er som "notebooks" som bør sjekkes inn i repo ved siden av koden og fungere som eksempler på hvordan funksjoner er skal brukes. Nesten som "levende dokumentasjon" som man skriver mens man utvikler og eksperimenterer.

augustl14:06:16

ah, sånn sett ja. Høres litt ut som sånn flere bruker comment-blokker i koden, som er lette å kjøre i REPL osv

leifericf14:06:38

Jepp! Som en stor comment-blokk på en måte.

augustl14:06:48

eksempel fra jobb

leifericf14:06:09

Basically bare for å flytte comment-blokker ut av selve koden sånn at det ikke blir så mye clutter der.

augustl14:06:24

kult egentlig, litt som devcards for ikke-frontend-kode

leifericf14:06:37

Ja, jeg synes det var en artig idé!

augustl14:06:39

alt dette blir jo fort veldig nære å være en automatisk test, men

leifericf14:06:39

Ja, det er sant. Men automatisk testing viser vel mest hvordan hver enkelt funksjon fungerer, og ikke så mye hvordan man kombinerer dem for å gjøre mer sofistikerte ting. "Fiddles" idéen er på en måte en slags "oppskriftsbok," som også skal illustrere måten utvikleren tenkte på, og hvordan koden har endret seg over tid.

leifericf14:06:56

I podkasten prater de om hvordan nye utviklere bruker dem for å lære seg kodebasen.

augustl14:06:47

spennende!

augustl14:06:08

dataene “hvilken kode er viktigst og hvordan brukes den i praksis” er noe et git-repo er dårlig til å svare på

magnars14:06:03

comment-blokk i slutten av fila 👍

👍 4
magnars14:06:09

ser ingen grunn til å rydde det bort

slipset16:06:39

jeg ville forøvrig hatt en fn ala:

(write-to-file full-path-to-file content)
Man kunne kanskje tilog med kalt den spit

👍 4
😁 2
leifericf07:06:01

Lol, kanskje jeg bare kunne brukt clojure.core/spit istedenfor å skrive min egen funksjon til å begynne med 😂

augustl07:06:22

den tar vel ikke linje-etter-linje da, hilsen August “The Premature Optimizer” Lilleaas

leifericf07:06:19

Åja, sant, hmmm.

leifericf07:06:32

Og jeg er ikke sikker på om den er tilgjengelig i Babashka heller, det må jeg sjekke.

leifericf07:06:49

Joda, den er der!

augustl07:06:01

ah, nemlig. Babashka er litt sånn “cljc-modus”, altså du gjør ikke JVM-ting der naturlig nok?

leifericf07:06:30

Nope, Babashka kjører jo på GraalVM og har ikke alt som JVM Clojure har. Men den er overraskende mye.

augustl07:06:06

ah ok, så da er det en “JVM” der med standardlibbet osv

leifericf07:06:41

Jeg tror Babashka har "nesten alt" fra clojure.core + en del libs som borkdude og andre har implementert støtte for.

leifericf09:06:01

@U04V5VAUN Slik omtrent? 🙂 Se spit-file nedenfor.

(defn get-filename-prefix []
  (.format (java.time.ZonedDateTime/now)
           (java.time.format.DateTimeFormatter/ofPattern "yyyyMMdd-HHmmss")))

(defn write-to-file
  ([filename lines]
   (let [default-path (str (file/home) (:local/output-dir settings))]
     (write-to-file default-path filename lines)))

  ([path filename lines]
   (let [prefixed-filename (format "%s_%s" (get-filename-prefix) filename)]
     (if-not (file/exists? path) (file/create-dirs path) nil)
     (file/write-lines (str path "/" prefixed-filename) lines))))

(defn spit-file [path content]
  (write-to-file (file/parent path) (file/file-name path) content))

(comment
  (write-to-file "test.txt" ["This is" "just a" "test"])

  (write-to-file "/Users/leif/tmp/test" "test.txt" ["This is" "just a" "test"])

  (spit-file "/Users/leif/tmp/test2/test.txt" ["This is" "just a" "test"])

  (->> (find-in-files ["csproj"] "netcoreapp3.1")
       (map str)
       (write-to-file "test.txt")))

slipset09:06:36

Skriv en test for get-filename-prefix

slipset09:06:00

Jeg ville kanskje latt write-to-file (eller spit) bare ta en text blob som den skreve til filystemet. Noen(TM) over kunne ha ansvaret for transformasjonen fra data til text.

👍 2
leifericf10:06:58

Har planer om å skrive en del tester, ja! Har ikke satt meg inn i hvordan det gjøres i Clojure (og Babashka) enda.

slipset10:06:35

@U01PE7630AC det om å skrive test for akkurat den funksjonen er en invitasjon til en diskusjon.

😅 2
leifericf10:06:57

Jeg var for noob til å forstå det 😅

slipset10:06:59

En funksjon som ikke tar argumenter er enten side-effektende, eller så er det en konstant.

slipset10:06:16

En sideeffektende funksjon er vanskelig å skrive unittest for.

leifericf10:06:57

De fleste av funksjonene mine har vel sideeffekter i og med at de direkte eller indirekte eksekverer shell commands, leser og skriver filer, osv.?

augustl10:06:29

går alltids an å ha en fixtures-mappe med noen ekte filer i som man kan kjøre testene mot på en stabil måte

augustl10:06:49

så kan man kanskje skrive til en tempfile elns så den blir rydda opp av OS

leifericf10:06:51

Ja, det var det jeg tenkte også, @U0MKRS1FX — Bare lage en mappe med en masse filer i for å teste.

augustl10:06:20

haha lurt, Optimus mm gjør jo en del fil-greier som er greit å få testet!

🎯 2
leifericf10:06:33

Haha! Takk, @U07FCNURX — Så klart du har et bibliotek for det også 🙂 Nice. Vil det funke i Babashka, tro? :thinking_face:

magnars10:06:34

Aner ikke. Det bruker java.nio

👍 2
leifericf10:06:55

Da tipper jeg det funker, fordi det gjør babashk.fs også.

slipset10:06:36

Men trikset er jo å skrive kode på en slik måte at mesteparten er pure, og bare noe er sideffecting

👍 2
augustl10:06:56

FC/IS 😻

augustl10:06:17

noen må lage en mere catchy forkortelse

leifericf10:06:21

Ja, absolutt. Jeg har mye å lære der.

slipset10:06:53

Vanlig kode skriver man ofte som:

augustl10:06:13

er utvilsomt en trade-off der da, for relativt små greier så blir det jo fort flere ting å ha i hodet om man skal abstrahere bort I/O

slipset10:06:40

(defn foo [whatever]
  (let [a ;; some calculation
        b ;; some calculation
        c ;; some calculation]
   (sideffect a b c))
Nå er foo vanskelig å teste Hvis man isteden lager seg en:
(defn calculate-it [whatever]
  {:a ...
   :b ..
   :c ..})
og mekker litt på sideffect så kan man gjøre:
(->> whatever calculate-it sideffect)

slipset10:06:05

og nå er calculate-it ren og superenkel å unit-teste

augustl10:06:32

foonctional core

slipset10:06:34

mens for å teste foo må man ty til mocking og annen styggedom.

cjohansen10:06:48

FC/IS er fint og flott, men her har @U01PE7630AC virkelig starta i side-effektenes land. Shell script er nødvendigvis mye side-effekter, og når det er mer side-effekter enn forretningslogikk så er det ofte litt vanskelig å treffe godt med FC/IS

🎯 2
💡 2
leifericf10:06:59

Haha, godt å høre, @christian767. Jeg har sittet og revet meg litt i håret og tenkt: "Hvordan i alle dager skal jeg få bukt med disse sideeffektene når jeg driver med shell scripting? Er jeg helt idiot?"

augustl10:06:30

businesslogikken til et shellscript er jo på en måte selve I/O-en

magnars10:06:39

Enig, men samtidig: Dra likevel ut logikken fra sideeffektene der du kan. Ikke klabb logikk inn sammen med skrivingen bare fordi du har "gitt opp".

👍 4
magnars10:06:05

Hvis du skal filtrere og rødde litt i dataene før de skrives, så gjør det i en egen funksjon som kan testes for seg.

💡 4
leifericf10:06:02

For min del er det ikke at jeg har "gitt opp" men at jeg egentlig ikke forstår meg på alt dette enda. Er ganske grønn. Men jeg føler at jeg lære ganske mye hver dag nå egentlig, med hjelp fra dere og i andre kanaler her på Slack.

cjohansen10:06:11

Jeg vil bare gi en liten trøst 🙂 Shell script er ikke der man får til FC/IS best, så ikke bli demotivert og gi opp. Gjør som @U07FCNURX foreslår, men også slå deg til ro med at det er mye side-effekter i et shell-script.

💜 2
slipset10:06:46

Men tilbake til mitt lille poeng med den lille funksjonen.

(defn get-filename-prefix []
  (.format (java.time.ZonedDateTime/now)
           (java.time.format.DateTimeFormatter/ofPattern "yyyyMMdd-HHmmss")))
Denne funksjonen tar ingen argumenter. Da er den enten en konstant, hvilket den ikke er, eller den er sideffektende. Hvis du nå isteden skriver den som :
(defn get-filename-prefix [ts]
  (.format ts
           (java.time.format.DateTimeFormatter/ofPattern "yyyyMMdd-HHmmss")))
Så har du en testbar funksjon.

💯 4
💡 2
augustl10:06:29

å sende “now” som argument ftw

cjohansen10:06:00

Ja, det er et godt tips. Du vil aldri kalle now inne i random funksjoner - bare helt ytterst i systemet ditt

leifericf10:06:40

Takk for det, @christian767! Jeg har også observert at teamet sideeffekter er en gjenganger i #babashka, og der klanger et lignende sentiment.

leifericf10:06:48

Er det "lov" å "skjule" java.time.ZonedDateTime/now bak en egen liten wrapper-funksjon? Typ:

(defn get-current-time []
  (java.time.ZonedDateTime/now))
Bare fordi jeg synes java.time.ZonedDateTime/now ser stygt ut og er vanskelig å huske? 😅 Så kan den brukes slik, etter forslaget til @U04V5VAUN:
(defn get-filename-prefix [timestamp]
  (.format timestamp (java.time.format.DateTimeFormatter/ofPattern "yyyyMMdd-HHmmss")))

(get-filename-prefix (get-current-time)) ; => "20230627-125216"

augustl10:06:59

kan kalles som (ZonedDateTime/now) og hvis den er importert med (:import [java.time ZonedDateTime])

💡 2
cjohansen10:06:37

Jeg trodde ikke egentlig Java time drev med defaults, men dette ser mistenkelig ut som om du antar systemets locale? :thinking_face:

augustl10:06:27

har vel strengt tatt ikke noe å si hvilken tidssone du har i en ZonedDateTime, sånn rent funksjonelt/logisk

cjohansen10:06:52

(defn get-current-time []
  (java.time.ZonedDateTime/now))
Dette har veldig liten verdi, og jeg gjør sånt bare unntaksvis om koden er ille krøllete. Men som @U0MKRS1FX påpeker kan du gjøre (ZonedDateTime/now), som tar ca like mye plass og kommuniserer helt utvetydig hva som skjer.

👍 2
cjohansen10:06:12

@U0MKRS1FX nei, men det spiller en rolle i hvilken tidssone du ber om now

augustl10:06:46

hmmmm :thinking_face: Om du får 12:57 i GMT+2 eller 10:57 i GMT+0 har vel ingenting å si senere i koden

augustl10:06:34

altså, du ber om “now” når koden kjører, og hvilken tidssone den er representert i blir vel hipp som happ

cjohansen10:06:45

det er kanskje det?

cjohansen10:06:55

Hvorfor ikke bare bruke LocalDateTime/now?

augustl10:06:49

da er den vel ikke et timestamp lengere, men en referanse til hva som stod på klokka når/der koden kjørte

cjohansen11:06:23

Så for meg ut som om hva som står på klokka er det den brukes til

augustl11:06:19

ah, jeg var i generisk si-smarte-ting-om-tidssoner-modus, ikke hva-trenger-egentlig-koden-modus 😄

augustl11:06:09

enig der ja, gir mening å bruke LocalDateTime når man skal skrive filer med timestamp til disk der og da

leifericf11:06:48

(:import [java.time ZonedDateTime]) ser ikke ut til å fungere i Babashka.

cjohansen11:06:11

prøv (:import java.time.ZonedDateTime)

leifericf11:06:56

Jeg gjorde det slik:

(:require [babashka.fs :as file]
            [babashka.process :as process]
            [cheshire.core :as json]
            [clojure.edn :as edn]
            [clojure.string :as str]
            [java.time.ZonedDateTime :as datetime])
Og da får jeg:
; java.lang.Exception: Could not find namespace: java.time.ZonedDateTime.

cjohansen11:06:11

:import, ikke :require

2
cjohansen11:06:34

(ns my.lol
  (:require [babashka.fs :as file]
            [babashka.process :as process]
            [cheshire.core :as json]
            [clojure.edn :as edn]
            [clojure.string :as str])
  (:import [java.time ZonedDateTime]))

magnars11:06:17

Kan du ha :as på imports?

cjohansen11:06:50

Ble litt for mye Møllers copy-paste

😂 2
💪 2
leifericf11:06:01

Det ser ut som den forventer navn på klasser også, så jeg måtte gjøre:

(ns leifs-utils.git
  (:require [babashka.fs :as file]
            [babashka.process :as process]
            [cheshire.core :as json]
            [clojure.edn :as edn]
            [clojure.string :as str])
  (:import [java.time.ZonedDateTime now]))

leifericf11:06:09

Eller, nei…

cjohansen11:06:40

Import kan enten se sånn ut: (:import [java.time ZonedDateTime]) eller sånn: (:import java.time.ZonedDateTime)

💡 2
cjohansen11:06:58

Eneste grunn til å bruke førstnevnte er hvis du vil importere flere klasser fra samme pakke

cjohansen11:06:16

Begge resulterer i at ZonedDateTime kan brukes ukvalifisert i namespacet

til 2
leifericf11:06:20

Ahaaa. Fancy.

cjohansen11:06:39

Ja, kanskje til og med unødvendig fancy 😅

😅 2
augustl11:06:16

det er overraskende mye syntaks i Clojure til å være et språk uten syntaks 😬

😂 2
Ivar Refsdal11:06:08

Eg har brukt

(defn today-yyyy-MM-dd-utc []
  (.format (ZonedDateTime/now (ZoneId/of "UTC")) (DateTimeFormatter/ofPattern "yyyy-MM-dd")))
med (:import (java.time ZoneId ZonedDateTime) og i tester har eg:
(with-redefs [mitt-ns/today-yyyy-MM-dd-utc (fn [& _args] "2000-01-01")]
...
Dette for kode som skal køyra på ein vilkårleg server (som kanskje har ein ukjent tidssone?). Mest for å ha eit bevisst forhold til det ...

💡 2
slipset12:06:18

Jeg synes jo da at with-redefs er en code-smell som du hadde sluppet unna dersom du hadde sendt now som en parameter.

slipset12:06:33

Og for å kaste stein i glasshus. I vår eminent navngitte parameter ctx som holder diverse informasjon vedrørende gjeldene request, så finnes også :user-time . Denne blir satt i det requesten mottas.

👌 2
slipset12:06:02

Så ingen funksjoner som mottar en ctx trenger å side-effecte for å finne tiden.

cjohansen12:06:39

Vi gjør det på samme vis

Ivar Refsdal12:06:51

Einig i at with-redefs er (litt) smelly... Samstundes: Dømet over er frå eit lite bibliotek. Eg tenker (av og til?) at det vert tungt å sende "ned" 'now' overalt, og ikkje alle bibliotek støtter det heller naturlegvis. (Men ja jo det er naturlegvis betre å ha det som ein (optional) parameter/input) Eg vil ikkje kalle å henta tida for ein side-effect, heller ein "world"/external dependency

slipset12:06:10

Da kaller vi det side-effect på bokmål og “world”/external dependency på nynorsk?

slipset12:06:25

/me hiding

🙈 2
😁 2
Ivar Refsdal12:06:04

høhø, janei 😁 Godt spørsmål kva ein skal kalle det på norsk. Google seier biverknad (bivirkning på bokmål). Eg kalte det https://github.com/ivarref/yoltq/blob/main/src/com/github/ivarref/yoltq/ext_sys.clj i yoltq (eige namespace)

slipset12:06:41

Bivirkning er jo konge!

Ivar Refsdal12:06:45

Ja, det er bra for ting som endrar ting (på disk f.eks.). Ting som berre "les" verdiar frå systemet (klokke f.eks.), meiner eg kan (burde?) heita noko anna

slipset12:06:56

“denne funksjonen har bivirkninger”, da skjønner man jo at det er noe galt på ferde.

👍 2
😄 2
cjohansen14:06:56

Har sett foredraget til Neil Ford om å lage foredrag. Veldig bra 👏 han pratet litt om livekoding, der fikk jeg en liten idé. Han snakker om at man bør unngå livekoding hvis det blir mye oppsett og fluff som ikke handler om poenget man vil formidle. Jeg tenker at dette er en knallgod litmustest for et stykke tech: lar dette seg live-kode? Bra mål på hvor mye "incidental complexity" som følger med

👍 8
cjohansen14:06:36

"Will it live code?" Ny screencast for review av programmeringsspråk og rammeverk 😁

😁 2
clojure-spin 4