Fork me on GitHub
#clojure-norway
<
2023-02-03
>
magnars07:02:53

Det er fredag, og da er det god morgen om dere vil eller ikke! 😄 ☀️ Her er dagens episode, hvor @christian767 og jeg satset hardt på kvantitet. https://www.zombieclj.no/s02e43.html

😂 2
🎉 2
slipset07:02:40

God morgen og takk for igår!

🙌 2
leifericf08:02:27

Dette er potensielt en dum idé, men… Nå som jeg blir "tvunget" til å jobbe med .NET (for det meste i C#, men kanskje også F# etter hvert). Jeg er ikke spesielt glad i C#, men .NET er jo en åpen standard nå, som kjører på alle plattformer. Jeg er egentlig overrasket over hvor bra det har blitt! Det er også en åpen standard, og det er https://en.wikipedia.org/wiki/Category:.NET_programming_languages som støtter .NET (C#, F#, Visual Basic, C++, Python). Clojure er jo i utgangspunktet "platform agnostic" som et "hosted" språk. Jeg har naturligvis begynt å bli litt nysgjerrig på hvor krevende det hadde vært å lage "http://Clojure.NET" (en slags implementasjon av .NET Standard). Det kan gjøres på flere måter, f.eks. på samme måte som med JVM (targeting .https://github.com/dotnet/runtime). Eller kan kunne kompilert Clojure-kode til CIL (https://en.wikipedia.org/wiki/Common_Intermediate_Language). Tanken er å kunne utvikle i Clojure og kjøre appen sin på cross-platform .NET Runtime/VM. Er det noen som vet om det finnes noen slike prosjekter allerede, eller har en intuisjon for hvor omfattende det ville vært? Jeg ser for meg at det ville vært svært omfattende å få til noe slikt, men har ingen tidligere erfaring med den typen prosjekter.

msolli08:02:51

Det er ClojureCLR, som (så vidt jeg forstår, har aldri brukt denne platformen) er det du ser etter.

😮 2
2
augustl08:02:53

hvis jeg ikke tar feil så finnes det vel, i form av Clojure CLR eller noe sånt?

augustl08:02:37

som én stakkar har sittet og vedlikeholdt i alle år. Sikkert ikke like optimalisert som JVM-clj osv, men har inntrykket av at det er solide saker

2
msolli08:02:54

Han som laget det i sin tid er i ferd med å re-implementere hele greia i F#: https://dmiller.github.io/clojure-clr-next/

leifericf08:02:15

Jeg har så vidt kikket på ClojureCLR, men det ser ut som det ble bygget for gamle .NET Framework, som kun var for Windows. Microsoft har i ettertid laget en cross-platform standard (.NET Standard, hvor .NET Core er én implementasjon). Men jeg har ikke satt meg så godt inn i ClojureCLR, mulig jeg tar feil her. Jeg skal kikke litt mer på det! Takk for tipset 🙂

augustl08:02:42

trodde CLR = JVM og at CLR funker på mono osv osv. Hilsen en som aldri har brukt .Net eller noe sånt

msolli08:02:27

David Miller er aktiv på #C060SFCPR, du kan jo alltids sjekke med ham hva som er greia. Og opplyse oss ikke-.Net-folk etterpå 🙂

❤️ 4
augustl08:02:22

har ingen klart å finne et bra ordspill på clr og clj og clojure enda? 😮 😮 😮

leifericf08:02:33

Takk for tipsene, karer! Jeg skal melde meg inn i #C060SFCPR klubben og melde tilbake 😄

slipset09:02:25

Av og til blir jeg litt skuffet over Clojure:

erik@keep ~ % clj
Clojure 1.10.3
user=> (distinct #{})
Error printing return value (UnsupportedOperationException) at clojure.lang.RT/nthFrom (RT.java:992).
nth not supported on this type: PersistentHashSet
user=>

msolli09:02:06

Nja. Men skuffelse er en funksjon av forventning. Jeg synes også den feilmeldingen er rar, hvorfor skulle det ikke være mulig å skrive ut et set, liksom? På den annen side - hvorfor kalle distinct på et set, som per definisjon bare har distinkte verdier?

2
slipset09:02:16

Fordi distinct virker på en coll

slipset09:02:48

Så jeg kan ha en fn som tar whatever som er liste-aktig, og jeg har lyst til å fjerne likheter

msolli09:02:02

Problemet er i implementasjonen av distinct:

(let [step (fn step [xs seen]
             (lazy-seq
               ((fn [[f :as xs] seen]
                  (when-let [s (seq xs)]
                    (if (contains? seen f)
                      (recur (rest s) seen)
                      (cons f (step (rest s) (conj seen f))))))
                xs seen)))]
  (step coll #{}))
Destruktureringen av xs på linje 3 der. xs er et sett, og det kan ikke destruktureres sekvensielt.

slipset09:02:10

Men jeg var akkurat i ferd med å begynne å lure på hvorfor distinct ikke er implemtert som (seq (set coll))

Jakub Holý (HolyJak)21:02:26

Set could lose ordering?

leifericf09:02:48

Jeg kan se for meg en situasjon hvor man kan ha en vector som inneholder flere datastrukturer, hvorav noen muligens er av typen set (men det er kanskje dårlig design i utgangspunktet). Kanskje en ønsker å bruke map eller reduce med distinct for finne ut om det er noen tomme datastrukturer types i vector. :thinking_face: Enig med @msolli at det virker litt rart å kalle distinct på et set i utgangspunktet.

cjohansen09:02:22

Tror aldri jeg har brukt distinct. Hvorfor ikke bare bruke set? Rekkefølge?

slipset09:02:27

Poenget er jo at du ikke nødvendigvis vet om du har et set eller ikke.

cjohansen09:02:39

(forøvrig enig i at distinct driter seg ut her)

msolli09:02:50

(distinct coll) returnerer en lazy-seq, mens (set coll) er ivrig, det er vel forskjellen på dem.

cjohansen09:02:04

ja, det kan jo være litt essensielt

msolli09:02:06

Alex Miller sier i den ask-en over at: > A better answer is for distinct to seq it’s input, producing a stable logical list view of a set, similar to all the other sequence functions. Så ja, den burde kanskje vært fikset?

slipset09:02:08

Forøvrig, det er her jeg synes at Clojure møter seg selv i døra, eller evt er inkonsekvent, (get 9 3) funker liksom helt fint, men (distinct #{}) , nei, dette er ulovlig

cjohansen09:02:30

haha, gjør det?

augustl09:02:57

(max 5 nil) ;; REEE

slipset09:02:14

Det er egentlig litt kult fordi det lar deg gjøre ting som:

(let [r (whatever foo)]
  (if (:error r)
     (throw (Exception. "whatever"))
     r))

slipset09:02:34

Uten at whatever behøver a returnere et map.

cjohansen09:02:02

Jeg bærer en del nag til denne: (apply max [])

😢 2
slipset09:02:19

@augustl det er masse gotchas til apply og en del fns som max og min og sånt.

cjohansen09:02:38

Kan løses med (apply max 0 []) men KOM IGJEN A

augustl09:02:42

prioriteringen er vel ytelse + saklig opplegg under panseret, ikke dev convenience

slipset09:02:55

Der burde man nok heller bruke reduce med en passende identitetsverdi

👌 2
slipset09:02:22

(reduce max Integer.MinInt xs) eller noe sånt

cjohansen09:02:34

jeg ville foretrukket at implementasjonen gjorde det for meg

augustl09:02:10

er vel strengt tatt “bare” for noen å lage et lite lag som er clojure.core bare med convenience-greier oppå

cjohansen09:02:20

det vil jeg ikke ha

slipset09:02:34

Problemet (som teoretikerne liker å påpeke) er at identitetsverdien til max ikke er universell, eller noe.

cjohansen09:02:08

muligens, men den funker bare med tall, så du har noen kandidater

cjohansen09:02:34

ettersom nil-punning er så gjennomgående i språket blir hver eneste sånn exception ekstra graverende syns jeg

slipset09:02:34

Eksempelvis så er (+) 0 , men (max) er ikke implementert

slipset09:02:54

Ja, det er vel det jeg synes er inkonsevent.

slipset09:02:23

Det som er kanskje verre er at true? ikke er definert for null argumenter.

cjohansen09:02:47

Det har jeg aldri støtt på tror jeg

cjohansen09:02:53

Hvordan får du problemer med det?

augustl09:02:28

dette skal Kotlin ha forresten, det har jo problemet at det ikke er en lisp, men det er veldig konsekvent design hele vegen igjennom

cjohansen09:02:23

Hvis jeg ikke kan ha REPL og gjennomgående immutability så vet jeg ikke om jeg gidder å være programmerer mer 😅

augustl09:02:04

skulle likt å lese Kotlin-folkets svar på hvorfor de ikke kan ha et REPL. Eller er det noe med lisp som gjør REPL fundamentalt bedre alltid uansett, som ikke-lisper ikke klarer å gjenskape?

augustl09:02:39

håper det går dypere enn at Kotlin-miljøet sier “jeg klarer meg fint uten et REPL”

augustl09:02:18

jeg skal ikke si noe, skjønte først i 2022 hvor awesome REPL er

slipset09:02:01

erik@keep ~ % clojure
Clojure 1.10.3
user=> (max)
Execution error (ArityException) at user/eval1 (REPL:1).
Wrong number of args (0) passed to: clojure.core/max
user=> (max "foo")
"foo"
user=> (max "foo" "bar")
Execution error (ClassCastException) at user/eval5 (REPL:1).
class java.lang.String cannot be cast to class java.lang.Number (java.lang.String and java.lang.Number are in module java.base of loader 'bootstrap')
user=>

😻 2
slipset14:02:58

En ting jeg lurer på @augustl. Hvor mye due dilligence har Oiiku gjort? Jeg kunne lett sett for meg at det er en del folk i denne kanalen som burde fått en telefon eller noe fra Oiiku i forbindelse med denne stillingen. Jeg vet jo at jeg ikke har fått noen 🙂

cjohansen14:02:34

Telefon? 😬

slipset14:02:55

eller noe 🙂

slipset14:02:40

Jeg fikk jo en telefon fra Kolbjørn i sin tid.

augustl14:02:52

godt spørsmål. De sier det er ~umulig å få tak i Clojure-utviklere. Men jeg har hatt ganske mange armlengders avstand til hele prosessen

magnars14:02:45

De har noen nå, da. 😊 @emil0r kan kanskje fortelle mer.

cjohansen14:02:25

Det der er en jobb jeg kunne funnet på å vurdere under rette omstendigheter, men jeg ville nok ikke vært på Finn og lett etter den.

augustl14:02:30

bærer kanskje litt preg av at en stor del av jobben er å ta over en svær gammel angular-frontend?

magnars14:02:14

Det er ikke så mange steder man kommer og får jobbe med Clojure og Datomic :star-struck:, så litt Angular kan man sikkert leve med.

augustl14:02:33

(og mongodb)

augustl14:02:05

nei enig, er et lite mysterie at de ikke har fått tak i noen. Jeg lurer på om jeg har postet link her før når de har lagt ut stillingsannonser tidligere

slipset14:02:07

Poenget mitt er vel at det er vel ikke sååå mange kandidater til den stillingen i Oslo, kanskje og det burde være mulig å ta kontakt med de få.

augustl14:02:22

har også inntrykk at de var på veldig god vei i 2019/2020, og så kom covid og satt en demper på budsjettene i eventbransjen

slipset14:02:54

Interessant at de ikke har noen som kan gjøre noe 🙂