Oke, nu ondersteunen wij ook geen IE11 meer dus dat verklaard waarschijnlijk alles
Waarom voelt het soms zo lastig om gewoon een leuk framework te pakken om in te gaan werken. Vanuit professioneel leven veel met Kotlin en Spring Boot. Maar ik wil nu toch eigenlijk een keer wat anders voor hobby projecten, niet zo veel bloated code voor mijn gevoel. Al is dat ook weer niet helemaal kloppend als ik naar Rails zit te kijken. Of dan toch met Laravel wat doen.
@Martindo Ga lekker met Ktor aan de gang. Leuk spul.
Engineering is like Tetris. Succes disappears and errors accumulate.
@Martindo Django heeft mijn voorkeur als je snel iets gedaan wilt krijgen. Ligt er natuurlijk wel aan wat je wilt doen, want heel "cutting edge" is Django niet.
🠕 This side up
Soms is het handig dat je in meerdere programmeertalen kan programmeren.
Ik ben bezig om in .NET (C#) een koppeling te maken met een telefooncentrale (Grandstream UCM6202) middels een HTTP API. En elke keer kreeg ik vage errors, terwijl ik naar mijn mening alles goed deed. Cookie errors, terwijl ik toch echt de juiste cookie mee stuurde bijvoorbeeld.
Na een hoop pogingen heb ik voor de gein een testscript in Python geschreven en die werkt gewoon! Dus ik denken "dit kan niet"
Wat blijkt nou? De HttpClient van .NET stuurt een charset "utf-8" mee, terwijl de telefooncentrale "UTF-8" verwacht. Dus ik de volgende regel code toegevoegd die van "utf-8" maar "UTF-8" maakt:
En ja hoor, nu werkt het
Ik ben bezig om in .NET (C#) een koppeling te maken met een telefooncentrale (Grandstream UCM6202) middels een HTTP API. En elke keer kreeg ik vage errors, terwijl ik naar mijn mening alles goed deed. Cookie errors, terwijl ik toch echt de juiste cookie mee stuurde bijvoorbeeld.
Na een hoop pogingen heb ik voor de gein een testscript in Python geschreven en die werkt gewoon! Dus ik denken "dit kan niet"

Wat blijkt nou? De HttpClient van .NET stuurt een charset "utf-8" mee, terwijl de telefooncentrale "UTF-8" verwacht. Dus ik de volgende regel code toegevoegd die van "utf-8" maar "UTF-8" maakt:
C#:
1
| content.Headers.ContentType.CharSet = "UTF-8"; |
En ja hoor, nu werkt het

Ask yourself if you are happy and then you cease to be.
'et is ook UTF-8
Somniferous whisperings of scarlet fields. Sleep calling me and in my dreams i wander. My reality is abandoned (I traverse afar). Not a care if I never everwake.
Volgens mij is de correcte schrijfwijze ook met hoofdletters en niet wat MS er van maakt.
Dat veel systemen tolerant zijn op casing is een 2e.
Dat veel systemen tolerant zijn op casing is een 2e.
Volgens mij niet: https://www.iana.org/assi...sets/character-sets.xhtmlhackerhater schreef op donderdag 22 april 2021 @ 17:15:
Volgens mij is de correcte schrijfwijze ook met hoofdletters en niet wat MS er van maakt.
Dat veel systemen tolerant zijn op casing is een 2e.
Dat heeft overigens ook niks met de HttpClient te maken, maar puur met het feit dat Encoding.UTF8.WebName de string literal "utf-8" heeftThe character set names may be up to 40 characters taken from the
printable characters of US-ASCII. However, no distinction is made
between use of upper and lower case letters.
“Build a man a fire, and he'll be warm for a day. Set a man on fire, and he'll be warm for the rest of his life.”
@farlane, @hackerhater
Het is inderdaad wat @Woy aangeeft. https://tools.ietf.org/html/rfc7231 geeft het volgende aan:
Het is inderdaad wat @Woy aangeeft. https://tools.ietf.org/html/rfc7231 geeft het volgende aan:
Maar er zijn genoeg niet standaard HTTP(s) servers in deze wereld, ik weet zeker dat die paar die ik heb geschreven ook niet voldoen.HTTP uses charset names to indicate or negotiate the character encoding scheme of a textual representation [RFC6365]. A charset is identified by a case-insensitive token.

"Doubt—the concern that my views may not be entirely correct—is the true friend of wisdom and (along with empathy, to which it’s related) the greatest enemy of polarization." -- Václav Havel
Headers zijn hoofdletterongevoelig, dus beide zouden exact hetzelfde moeten doen.farlane schreef op donderdag 22 april 2021 @ 17:15:
'et is ook UTF-8
Standaard alleen de naam voor zover ik weet.RagingPenguin schreef op donderdag 22 april 2021 @ 20:23:
[...]
Headers zijn hoofdletterongevoelig, dus beide zouden exact hetzelfde moeten doen.
Header values kunnen hoofdletter gevoelig zijn, maar bijna elke standaard header (volgens mij elke?) is hoofdletter ongevoelig.Pizzalucht schreef op donderdag 22 april 2021 @ 20:27:
[...]
Standaard alleen de naam voor zover ik weet.
Fun fact: de http spec en MDN schrijven ook allebei utf-8 i.p.v. UTF-8.
Volgens mij hebben zowel ik als Woy al aangegeven dat het niks zou moeten uitmaken volgens de standaards. Waar Farlene tegen aanpraat heeft een implementatie die zich blijlkbaar niet strikt aan de standaard houdt en daarom mag hij nu kunstgrepen uitvoerenRagingPenguin schreef op donderdag 22 april 2021 @ 20:38:
[...]
Header values kunnen hoofdletter gevoelig zijn, maar bijna elke standaard header (volgens mij elke?) is hoofdletter ongevoelig.
Fun fact: de http spec en MDN schrijven ook allebei utf-8 i.p.v. UTF-8.
offtopic:
Fun fact: In de oudere standaards had men de voorkeur aan utf-8 in hoofdletters te schrijven terwijl in de nieuwe standaards voornamelijk met de kleine letters wordt geschreven. Er was zelfs één die verschillende mogelijkheden gaf en expliciet voorkeur had voor kleine letters.
Fun fact: In de oudere standaards had men de voorkeur aan utf-8 in hoofdletters te schrijven terwijl in de nieuwe standaards voornamelijk met de kleine letters wordt geschreven. Er was zelfs één die verschillende mogelijkheden gaf en expliciet voorkeur had voor kleine letters.
"Doubt—the concern that my views may not be entirely correct—is the true friend of wisdom and (along with empathy, to which it’s related) the greatest enemy of polarization." -- Václav Havel
Compromis: uTf-8
🠕 This side up
Leet speak: u7f-8
Of als we het dan volledig uittypen: UNiCOD3 7R4n5fOrM47iOn ForM@ – 8-8i7
Veeeeeel duidelijker
Of als we het dan volledig uittypen: UNiCOD3 7R4n5fOrM47iOn ForM@ – 8-8i7
Veeeeeel duidelijker
Without nipples, boobs are pointless - 365 project - In mijn hoofd is het alle dagen Kerstmis - What type of bees make milk? Boobies! - What type of bees are scary? BoooOOOOOooobeees! - Cactusliefhebster
ElkeBxl schreef op vrijdag 23 april 2021 @ 12:45:
Leet speak: u7f-8
Of als we het dan volledig uittypen: UNiCOD3 7R4n5fOrM47iOn ForM@ – 8-8i7
Veeeeeel duidelijker

Ik had eigenlijk het volgende verwacht:
µ₸℉➖⫕⫖
"Doubt—the concern that my views may not be entirely correct—is the true friend of wisdom and (along with empathy, to which it’s related) the greatest enemy of polarization." -- Václav Havel
Grapping, want veel websites doen al iets als ?utf8=✓ in de URLDevWouter schreef op vrijdag 23 april 2021 @ 14:15:
[...]
![]()
Ik had eigenlijk het volgende verwacht:
µ₸℉➖⫕⫖
🠕 This side up
Zo hadden wij ook een leuke. Bij een on-premise van een klant ging een deel van de requests van de webclient naar de server niet door. Bij sommige mensen deed ie het altijd, bij anderen af en toe niet en dan was het een CORS error.
Wat bleek: sommige medewerkers hadden Do Not Track aangezet in hun browser. Deze stuurt een DNT header mee. Echter, IT van de klant had een application firewall waar alle onbekende headers uitgefilterd werden. Tenzij het een OPTIONS was. Die werden namelijk steeksproefgewijs (ongeveer 1 op 20) gecontroleerd en geblokkeerd als er eentje inzat die niet klopte en dus blokkeerde die af en toe waardoor de browser weer een CORS error gaf. Het toevoegen van de DNT header in de application firewall loste het op. Echter dit moest wel via hun security werkgroep die eens in de 2 weken samenkwam. Na formele goedkeuring was het er na 4 weken doorheen.
Oh, dit is een bedrijf met 15 werknemers. Just so you know.
Wat bleek: sommige medewerkers hadden Do Not Track aangezet in hun browser. Deze stuurt een DNT header mee. Echter, IT van de klant had een application firewall waar alle onbekende headers uitgefilterd werden. Tenzij het een OPTIONS was. Die werden namelijk steeksproefgewijs (ongeveer 1 op 20) gecontroleerd en geblokkeerd als er eentje inzat die niet klopte en dus blokkeerde die af en toe waardoor de browser weer een CORS error gaf. Het toevoegen van de DNT header in de application firewall loste het op. Echter dit moest wel via hun security werkgroep die eens in de 2 weken samenkwam. Na formele goedkeuring was het er na 4 weken doorheen.
Oh, dit is een bedrijf met 15 werknemers. Just so you know.
[ Voor 5% gewijzigd door armageddon_2k1 op 24-04-2021 18:07 ]
Engineering is like Tetris. Succes disappears and errors accumulate.
Huh? Wat is het nut van je firewall steekproefgewijs te laten controleren en blokkeren? Je voegt EN geen security toe EN je maakt het eindeloos veel moeilijker om te debuggen/onderzoeken.armageddon_2k1 schreef op zaterdag 24 april 2021 @ 18:06:
Zo hadden wij ook een leuke. Bij een on-premise van een klant ging een deel van de requests van de webclient naar de server niet door. Bij sommige mensen deed ie het altijd, bij anderen af en toe niet en dan was het een CORS error.
Wat bleek: sommige medewerkers hadden Do Not Track aangezet in hun browser. Deze stuurt een DNT header mee. Echter, IT van de klant had een application firewall waar alle onbekende headers uitgefilterd werden. Tenzij het een OPTIONS was. Die werden namelijk steeksproefgewijs (ongeveer 1 op 20) gecontroleerd en geblokkeerd als er eentje inzat die niet klopte en dus blokkeerde die af en toe waardoor de browser weer een CORS error gaf. Het toevoegen van de DNT header in de application firewall loste het op. Echter dit moest wel via hun security werkgroep die eens in de 2 weken samenkwam. Na formele goedkeuring was het er na 4 weken doorheen.
Oh, dit is een bedrijf met 15 werknemers. Just so you know.
@Neverwinterx Ja euhm, don't shoot the messenger. Weet ik veel waarom ze dat doen 
Volgens mij wilden ze via OPTIONS loggen wat voor headers er zo nu en dan binnenkomen en of ze niet teveel blokkeren, maar was het niet de bedoeling de OPTIONS te blokkeren als er iets inzat wat ze nog niet kenden. Zoiets.
Volgens mij wilden ze via OPTIONS loggen wat voor headers er zo nu en dan binnenkomen en of ze niet teveel blokkeren, maar was het niet de bedoeling de OPTIONS te blokkeren als er iets inzat wat ze nog niet kenden. Zoiets.
[ Voor 56% gewijzigd door armageddon_2k1 op 27-04-2021 17:01 ]
Engineering is like Tetris. Succes disappears and errors accumulate.
Ik zou zeggen: laat het verzoek binnenkomen, zit er een header tussen die je niet kent, dan in de wacht houden, automatisch een e-mail sturen naar de afzender met "Wij hebben uw OPTIONS-verzoek ontvangen. We zullen deze binnen 10 werkdagen een beslissing nemen of we dit verzoek honoreren. Bij vragen kunt u een fax sturen naar 085 42 24 52.", en dan handmatig iemand naar alle verzoeken laten kijken, en laten accepteren of afkeuren
🠕 This side up
Maar log dan gewoon alles en filter dan 1x per zo veel tijd alle onbekende headers uitarmageddon_2k1 schreef op dinsdag 27 april 2021 @ 17:00:
@Neverwinterx Ja euhm, don't shoot the messenger. Weet ik veel waarom ze dat doen
Volgens mij wilden ze via OPTIONS loggen wat voor headers er zo nu en dan binnenkomen en of ze niet teveel blokkeren, maar was het niet de bedoeling de OPTIONS te blokkeren als er iets inzat wat ze nog niet kenden. Zoiets.
Bij mijn huidige klant zijn ze ook erg goed in plannen maken met een hoop mensen en met z'n allen commisies te volgen die een plasje moeten doen over wat veel minder mensen daadwerkelijk ontwikkelen.armageddon_2k1 schreef op zaterdag 24 april 2021 @ 18:06:
Oh, dit is een bedrijf met 15 werknemers. Just so you know.
https://niels.nu
Waarom niet gewoon doen wat jij denkt dat het beste is en dan een commisie oprichten om het terug te draaien?Hydra schreef op woensdag 28 april 2021 @ 13:33:
[...]
Bij mijn huidige klant zijn ze ook erg goed in plannen maken met een hoop mensen en met z'n allen commisies te volgen die een plasje moeten doen over wat veel minder mensen daadwerkelijk ontwikkelen.
"Doubt—the concern that my views may not be entirely correct—is the true friend of wisdom and (along with empathy, to which it’s related) the greatest enemy of polarization." -- Václav Havel
Oh, we werken er ook zoveel mogelijk omheen. Mensen die een mening hebben zonder kennis, zorgen meestal alleen maar voor vertraging. Je merkt ook dat als je eenmaal iets werkend hebt dat ze het liefst gewoon doen alsof het altijd al hun idee was.DevWouter schreef op woensdag 28 april 2021 @ 13:52:
Waarom niet gewoon doen wat jij denkt dat het beste is en dan een commisie oprichten om het terug te draaien?![]()
https://niels.nu
Klinkt alsof het tijd is om wat eendjes te introduceren?Hydra schreef op woensdag 28 april 2021 @ 13:33:
[...]
Bij mijn huidige klant zijn ze ook erg goed in plannen maken met een hoop mensen en met z'n allen commisies te volgen die een plasje moeten doen over wat veel minder mensen daadwerkelijk ontwikkelen.
I'm not a complete idiot. Some parts are missing.
.Gertjan.: Ik ben een zelfstandige alcoholist, dus ik bepaal zelf wel wanneer ik aan het bier ga!
Er zijn zo van die dagen dat je beter in je bed had gebleven...maar er zijn er ook dat je iets wat je 8 jaar geleden gebouwd had, maar toch niet nodig bleek te zijn, ineens toch nodig is, en het werkt dan ook nog gewoon
Website|Air 3s|Mini 4 Pro|Avata 2|Canon R6|Canon 5d2|8 fisheye|14f2.8|24f2.8|50f1.8|135f2|10-22|17-40|24-105|70-300|150-600
Je bent nog aan het dromen @qless ...
Without nipples, boobs are pointless - 365 project - In mijn hoofd is het alle dagen Kerstmis - What type of bees make milk? Boobies! - What type of bees are scary? BoooOOOOOooobeees! - Cactusliefhebster
Helaas niet, ben goed wakker met het geblaas van de macbook ventilator naast me...
Website|Air 3s|Mini 4 Pro|Avata 2|Canon R6|Canon 5d2|8 fisheye|14f2.8|24f2.8|50f1.8|135f2|10-22|17-40|24-105|70-300|150-600
En toen kwam er een macbook met een lange ventilatiesleuf en die blies het verhaaltje uitqless schreef op donderdag 29 april 2021 @ 10:38:
Helaas niet, ben goed wakker met het geblaas van de macbook ventilator naast me...
En toen kwam er een macbook M1 waar de ventilator nooit van aangaat...gekkie schreef op donderdag 29 april 2021 @ 11:29:
[...]
En toen kwam er een macbook met een lange ventilatiesleuf en die blies het verhaaltje uit.





Website|Air 3s|Mini 4 Pro|Avata 2|Canon R6|Canon 5d2|8 fisheye|14f2.8|24f2.8|50f1.8|135f2|10-22|17-40|24-105|70-300|150-600
En toen kwam er een MacBook Air die uberhaupt geen ventilator heeft!qless schreef op donderdag 29 april 2021 @ 12:31:
En toen kwam er een macbook M1 waar de ventilator nooit van aangaat...![]()
![]()
![]()
![]()
Iemand nog een grotere piemel?
https://niels.nu
* gekkie pakt de haspel en zet hem op tafel
Ben wel benieuwd hoe de performance van die nieuwe M1's is. Heb net een Mini besteld, hopen dat mijn workflow er niet op achteruit gaat. Ben wel een beetje klaar met het vliegtuig dat nu onder m'n bureau hangt..qless schreef op donderdag 29 april 2021 @ 12:31:
[...]
En toen kwam er een macbook M1 waar de ventilator nooit van aangaat...![]()
![]()
![]()
![]()
Prive heb ik een M1 draaien (voor final cut pro, lightroom, ptgui etc) en ik krijg de ventilator niet aan. Was ter vervanging van een imac 2011, en het verschil is dramatisch in snelheid.
Voor programmeren van niet apple spul ( android studio, vscode ) zou ik nog even afwachten hoe dat werkt met debuggen e.d.
Voor programmeren van niet apple spul ( android studio, vscode ) zou ik nog even afwachten hoe dat werkt met debuggen e.d.
Website|Air 3s|Mini 4 Pro|Avata 2|Canon R6|Canon 5d2|8 fisheye|14f2.8|24f2.8|50f1.8|135f2|10-22|17-40|24-105|70-300|150-600
Ik vraag mij eerder af hoe ze aan de term Hydra Code komen in jouw link.Firesphere schreef op donderdag 29 april 2021 @ 02:34:
[...]
Klinkt alsof het tijd is om wat eendjes te introduceren?
@Hydra maar vragen ?Giesber schreef op donderdag 29 april 2021 @ 14:38:
[...]
Ik vraag mij eerder af hoe ze aan de term Hydra Code komen in jouw link.
Dat staat toch uitgelegd daar?Giesber schreef op donderdag 29 april 2021 @ 14:38:
[...]
Ik vraag mij eerder af hoe ze aan de term Hydra Code komen in jouw link.
I'm not a complete idiot. Some parts are missing.
.Gertjan.: Ik ben een zelfstandige alcoholist, dus ik bepaal zelf wel wanneer ik aan het bier ga!
Ik doelde dan ook eerder op gekkie zijn suggestie, maar ik kon het er toch niet al te dik opleggen
* DevWouter pakt de gehaktmolen en zet die naast de haspelgekkie schreef op donderdag 29 april 2021 @ 12:59:
[...]
* gekkie pakt de haspel en zet hem op tafel
"Doubt—the concern that my views may not be entirely correct—is the true friend of wisdom and (along with empathy, to which it’s related) the greatest enemy of polarization." -- Václav Havel
* gekkie ziet een aanleiding voor Pé Daalemmer en rooie Rinus en laat hem niet voorbij gaan
YouTube: YouTube
YouTube: YouTube
[ Voor 5% gewijzigd door gekkie op 30-04-2021 18:28 ]
* Janoz wist niet dat@gekkie ook bekend was met de grunniger kklasiekers
Ken Thompson's famous line from V6 UNIX is equaly applicable to this post:
'You are not expected to understand this'
~Verkeerde topic, * Firesphere is an idiot~
[ Voor 89% gewijzigd door Firesphere op 01-05-2021 07:28 ]
I'm not a complete idiot. Some parts are missing.
.Gertjan.: Ik ben een zelfstandige alcoholist, dus ik bepaal zelf wel wanneer ik aan het bier ga!
* gekkie haalt z'n verse pinda's uiteraard bij de SPARJanoz schreef op vrijdag 30 april 2021 @ 23:40:
* Janoz wist niet dat@gekkie ook bekend was met de grunniger kklasiekers
Hi fellow tweakers,
Na overleg met de mods ben ik hier terecht gekomen voor mijn vraag :-). Het lijkt mij leuk om andere tweakers in de stad waar ik woon, Deventer, te ontmoeten die of hobby matig of beroepsmatig in hun dagelijks leven bezig zijn met data analyses/data engineering/currating etc. Ik werk zelf namelijk in de wetenschap en ben zowel beroepsmatig als hobby matig met allerlei data science projecten bezig. Ik werk momenteel thuis en ik mis eigenlijk een paar vrienden of kennissen in mijn directe omgeving die hier ook veel mee bezig zijn. Ik zou het zelf leuk vinden om samen op een locatie of bij iemand thuis afzonderlijk of samen aan een project te werken, maar sta ook open voor andere ideeen. Misschien een beetje vergelijkbaar met een hackerspace, al kan ik die niet zo snel vinden in de buurt van Deventer.
Dus welke tweakers die in de mooiste Hanze stad van Nederland wonen en met data 'tweaken' vinden het leuk om een keer te meeten of hebben een tip voor mij hoe ik een paar mensen kan ontmoeten :-). Stuur me gerust een pbtje of reageer hier even.
Na overleg met de mods ben ik hier terecht gekomen voor mijn vraag :-). Het lijkt mij leuk om andere tweakers in de stad waar ik woon, Deventer, te ontmoeten die of hobby matig of beroepsmatig in hun dagelijks leven bezig zijn met data analyses/data engineering/currating etc. Ik werk zelf namelijk in de wetenschap en ben zowel beroepsmatig als hobby matig met allerlei data science projecten bezig. Ik werk momenteel thuis en ik mis eigenlijk een paar vrienden of kennissen in mijn directe omgeving die hier ook veel mee bezig zijn. Ik zou het zelf leuk vinden om samen op een locatie of bij iemand thuis afzonderlijk of samen aan een project te werken, maar sta ook open voor andere ideeen. Misschien een beetje vergelijkbaar met een hackerspace, al kan ik die niet zo snel vinden in de buurt van Deventer.
Dus welke tweakers die in de mooiste Hanze stad van Nederland wonen en met data 'tweaken' vinden het leuk om een keer te meeten of hebben een tip voor mij hoe ik een paar mensen kan ontmoeten :-). Stuur me gerust een pbtje of reageer hier even.
Even wat frustratie over java (of ligt het aan eclipse?) van me af typen: altijd als ik denk "jee, dit kan mooi met een streams, maps en lambda's!" ben ik daar altijd heel erg snel van genezen.
Code completion, syntax highlighting, het markeren van syntaxfouten... alles vliegt uit het raam zodra je met streams en lambda's aan de slag gaat. Dat je een hele keten aan methodes aan elkaar mag plakken met de nodige haakjes helpt daar ook niet bij.
Volgende keer pak ik weer gewoon een for-loopje. Ik bewaar de lambda's wel weer voor mijn gehobby in haskell.
Volgende keer pak ik weer gewoon een for-loopje. Ik bewaar de lambda's wel weer voor mijn gehobby in haskell.
Heeft geen speciale krachten en is daar erg boos over.
Gelukkig werkte je code nog meteen, anders moest je lambda's gaan debuggen.bwerg schreef op vrijdag 7 mei 2021 @ 12:19:
Even wat frustratie over java (of ligt het aan eclipse?) van me af typen: altijd als ik denk "jee, dit kan mooi met een streams, maps en lambda's!" ben ik daar altijd heel erg snel van genezen.Code completion, syntax highlighting, het markeren van syntaxfouten... alles vliegt uit het raam zodra je met streams en lambda's aan de slag gaat. Dat je een hele keten aan methodes aan elkaar mag plakken met de nodige haakjes helpt daar ook niet bij.
Volgende keer pak ik weer gewoon een for-loopje. Ik bewaar de lambda's wel weer voor mijn gehobby in haskell.
Al vind ik over het algemeen streams lambda's wel een pak beter leesbaar dan een massa geneste for loops.
Probeer IntelliJ anders gewoon eens. Eclipse ligt gewoon enorm achter kwa features.bwerg schreef op vrijdag 7 mei 2021 @ 12:19:
Even wat frustratie over java (of ligt het aan eclipse?) van me af typen: altijd als ik denk "jee, dit kan mooi met een streams, maps en lambda's!" ben ik daar altijd heel erg snel van genezen.Code completion, syntax highlighting, het markeren van syntaxfouten... alles vliegt uit het raam zodra je met streams en lambda's aan de slag gaat. Dat je een hele keten aan methodes aan elkaar mag plakken met de nodige haakjes helpt daar ook niet bij.
Daarbij zou ik als je Java ook professioneel gebruikt streams niet gaan ontwijken ofzo, het is gewoon voor ervaren devs een vereiste om onder de knie te hebben.
[ Voor 11% gewijzigd door Hydra op 07-05-2021 12:51 ]
https://niels.nu
Misschien wel, maar blijft wel de ene boilerplate-constructie omwisselen voor de andere. Als je de boilerplate negeert is het inderdaad alsnog beter leesbaar. Zeker als je jarenlang alleen maar functioneel hebt geprogrammeerd.Giesber schreef op vrijdag 7 mei 2021 @ 12:44:
Al vind ik over het algemeen streams lambda's wel een pak beter leesbaar dan een massa geneste for loops.
Echt ontwijken doe ik het ook niet. Maar elke keer dat ik zo'n trein apen.stream().map(aap -> aap.getBanaan()).collect(Collectors.toList) denk ik wel steeds weer "prachtig" op sarcastische toon.Hydra schreef op vrijdag 7 mei 2021 @ 12:51:
Daarbij zou ik als je Java ook professioneel gebruikt streams niet gaan ontwijken ofzo, het is gewoon voor ervaren devs een vereiste om onder de knie te hebben.
Nou is de vergelijking met haskell misschien wat flauw omdat vertaling tussen lijsten/collecties en streams vaak niet bestaat in een lazy taal, terwijl het toch wel wat doet in een strikte taal. Maar even klagen kan nooit kwaad.
Heeft geen speciale krachten en is daar erg boos over.
Is apen.map(aap -> aap.getBanaan()) geen optie? Anders is het inderdaad wel heel veel boilerplate met wrs veel overheat. Waarom zou je een list moeten omzetten naar een stream, een list zou ook gewoon 'mapbaar' moeten zijn, functor is functor.bwerg schreef op vrijdag 7 mei 2021 @ 13:10:
Echt ontwijken doe ik het ook niet. Maar elke keer dat ik zo'n trein apen.stream().map(aap -> aap.getBanaan()).collect(Collectors.toList) denk ik wel steeds weer "prachtig" op sarcastische toon.
Nou is de vergelijking met haskell misschien wat flauw omdat vertaling tussen lijsten/collecties en streams vaak niet bestaat in een lazy taal, terwijl het toch wel wat doet in een strikte taal. Maar even klagen kan nooit kwaad.
Voordat mensen roepen: streams zijn efficienter omdat ze lazy zijn: dat maakt met maar 1 map niet uit, en al helemaal niet als je er toch direct weer een list van maakt. Dat is alleen maar overhead.
[ Voor 18% gewijzigd door RagingPenguin op 07-05-2021 13:23 ]
Note: ik werk niet professioneel met Java 
Heb laatst eens gekeken hoe Eclipse zich heeft ontwikkeld sinds ik 6-7 jaar geleden naar Jetbrains/IntelliJ ben overstapt. Ben weer snel teruggerend.
Leek net alsof de IDE zich nauwelijks heeft ontwikkeld in die jaren, en veel (met name debug-functies) miste ik enorm in Eclipse; waar ook de streams een van de onderdelen zijn ja.
(Ik werk fulltime in Rubymine, ook van Jetbrains. Dus ik ben niet geheel onpartijdig)
Heb laatst eens gekeken hoe Eclipse zich heeft ontwikkeld sinds ik 6-7 jaar geleden naar Jetbrains/IntelliJ ben overstapt. Ben weer snel teruggerend.
Leek net alsof de IDE zich nauwelijks heeft ontwikkeld in die jaren, en veel (met name debug-functies) miste ik enorm in Eclipse; waar ook de streams een van de onderdelen zijn ja.
(Ik werk fulltime in Rubymine, ook van Jetbrains. Dus ik ben niet geheel onpartijdig)
Ik zou als je Java ook professioneel gebruikt sowieso Eclipse ontwijken.Hydra schreef op vrijdag 7 mei 2021 @ 12:51:
[...]
Probeer IntelliJ anders gewoon eens. Eclipse ligt gewoon enorm achter kwa features.
Daarbij zou ik als je Java ook professioneel gebruikt streams niet gaan ontwijken ofzo, het is gewoon voor ervaren devs een vereiste om onder de knie te hebben.
Java Streams support in IntelliJ is meer dan prima. We hebben nog een fossiel die zweert bij Eclipse in onze organisatie, maar die begint ook heel langzaam te overwegen om toch maar eens over te stappen.
"The question of whether a computer can think is no more interesting than the question of whether a submarine can swim" - Edsger Dijkstra
Vertel mij wat, maar een List in Java heeft geen map, dus dan houdt het wel op.RagingPenguin schreef op vrijdag 7 mei 2021 @ 13:15:
Waarom zou je een list moeten omzetten naar een stream, een list zou ook gewoon 'mapbaar' moeten zijn, functor is functor.
Of nou ja, ik zou een utility-functie static List<T> map(List list<S>, Function<S,T> f) kunnen maken, en die dan naar alle java-projecten toeslepen waar ik iets aan doe - samen met Tuple<S,T>, guava en ander generiek spul. Maar daar ben je ook wel een keer klaar mee.
Oh, en List implementeert dus ook geen Functor, dat moge duidelijk zijn.
Heeft geen speciale krachten en is daar erg boos over.
@bwerg Heeft u een momentje om over onze verlosser Kotlin te praten? 
Zou moeten kloppen, al heb ik al in geen eeuwigheid meer iets met Kotlin gedaan.
code:
1
| apen.map { aap -> aap.getBanaan() } |
Zou moeten kloppen, al heb ik al in geen eeuwigheid meer iets met Kotlin gedaan.
🠕 This side up
Ja, dat is die taal waarvan ik al jaren zeg dat ik daar eens naar moet kijken, terwijl ik daar nooit aan toe kom.Koenvh schreef op vrijdag 7 mei 2021 @ 15:37:
@bwerg Heeft u een momentje om over onze verlosser Kotlin te praten?
Heeft geen speciale krachten en is daar erg boos over.
Andere mensen keken ook naar:bwerg schreef op vrijdag 7 mei 2021 @ 15:50:
[...]
Ja, dat is die taal waarvan ik al jaren zeg dat ik daar eens naar moet kijken, terwijl ik daar nooit aan toe kom.
- Rust
- Go
- Julia
Ik vind Kotlin erg leuk, maar ik vind de hoeveelheid syntactische suiker in eerste instantie wel overweldigend.
🠕 This side up
Al eens naar Vavr gekeken?bwerg schreef op vrijdag 7 mei 2021 @ 13:58:
[...]
Vertel mij wat, maar een List in Java heeft geen map, dus dan houdt het wel op.
Of nou ja, ik zou een utility-functie static List<T> map(List list<S>, Function<S,T> f) kunnen maken, en die dan naar alle java-projecten toeslepen waar ik iets aan doe - samen met Tuple<S,T>, guava en ander generiek spul. Maar daar ben je ook wel een keer klaar mee.
Oh, en List implementeert dus ook geen Functor, dat moge duidelijk zijn.
Kotlin is love, Kotlin is life.
Niet zozeer de syntactische sugar, maar gewoon de vele language features zijn erg fijn.
Ben nu erg veel bezig met Kotlin Multiplatform, met vooral de JVM en JS als target. Mooi spul.
Als ik nu weer Java gebruik voelt het alsof ik schuurmiddel asfalt op m’n tandenborstel doe. Niet dat ik Java haat, want dat schijnt nogal populair te zijn. Maar het is gewoon uit een andere tijd en heeft zo’n gigantische installed base dat hun manoeuvreersnelheid gewoon wat anders is. Kotlin is natuurlijk mini vergeleken met Java. Populair zeker, maar het is alsof je Tesla met VAG vergelijkt. Mooie autootjes en lopen vooruit, maar totaal aantal verkopen nog geen fractie van de concurrentie.
Niet zozeer de syntactische sugar, maar gewoon de vele language features zijn erg fijn.
Ben nu erg veel bezig met Kotlin Multiplatform, met vooral de JVM en JS als target. Mooi spul.
Als ik nu weer Java gebruik voelt het alsof ik schuurmiddel asfalt op m’n tandenborstel doe. Niet dat ik Java haat, want dat schijnt nogal populair te zijn. Maar het is gewoon uit een andere tijd en heeft zo’n gigantische installed base dat hun manoeuvreersnelheid gewoon wat anders is. Kotlin is natuurlijk mini vergeleken met Java. Populair zeker, maar het is alsof je Tesla met VAG vergelijkt. Mooie autootjes en lopen vooruit, maar totaal aantal verkopen nog geen fractie van de concurrentie.
[ Voor 7% gewijzigd door armageddon_2k1 op 08-05-2021 12:28 ]
Engineering is like Tetris. Succes disappears and errors accumulate.
Tegelijkertijd moet je je denk ik ook afvragen in hoeverre je dan efficiënt bezig bent. Om het volgende citaat er ook meteen maar even bij te pakken:Giesber schreef op vrijdag 7 mei 2021 @ 12:44:
Al vind ik over het algemeen streams lambda's wel een pak beter leesbaar dan een massa geneste for loops.
Van de Java-afgeleiden (Kotlin, Scala, Groovy) vind ik persoonlijk Kotlin nog niet eens overweldigend aangezien ze je nog ergens binnen een bepaald stramien proberen te laten werken. Als ik kijk naar Groovy en wat daarin mogelijk is, dan begin ik me af te vragen in hoeverre de taal de onderhoudbaarheid van een stuk software bevordert. Dit gevoel krijg ik soms ook bij het lezen van Kotlin en Scala, weliswaar in mindere mate, maar ook Java streams.Koenvh schreef op vrijdag 7 mei 2021 @ 16:47:
Ik vind Kotlin erg leuk, maar ik vind de hoeveelheid syntactische suiker in eerste instantie wel overweldigend.
Waar je met geneste for/while-loops een duidelijk overzicht kunt krijgen van de complexiteit van je code, is dit door gebruik van Java streams een stuk verder door de taal geabsorbeerd. Neem het volgende voorbeeld:
Java:
1
2
3
4
5
6
7
8
9
10
| final List<List<List<String>>> listOflistOfListOfStrings = List.of(List.of(List.of("Hello Tweakers.net"))); for (List<List<String>> listOfListOfStrings : listOflistOfListOfStrings) { for (List<String> listOfStrings : listOfListOfStrings) { for (String str : listOfStrings) { System.out.println(str); } } } |
Dit zou er met een Java stream bijvoorbeeld zo uit zien:
Java:
1
2
3
4
| listOflistOfListOfStrings.stream() .flatMap(List::stream) .flatMap(List::stream) .forEach(System.out::println); |
Nu zijn er natuurlijk een aantal kanttekeningen bij bovenstaand voorbeeld te plaatsen: het bevat verder geen extra complexiteit zoals condities, en de typering en naamgeving verraadt al een groot deel van de complexiteit. Normaliter zou een deel van de generics zijn vervangen door domeinobjecten en zouden mogelijk loops zijn vervangen door methodes. Dit zorgt er dus voor dat de complexiteit verborgen raakt in objecten en methodes, hoewel de leesbaarheid wordt verbeterd. Daarmee valt de complexiteit dus niet meer uit de typering en naamgeving te halen, en zul je zijn aangewezen op je kennis van het domein en de code an sich. Desalniettemin geeft het hopelijk een goed beeld van het gevoel wat ik krijg bij het gebruik van streams.
In 'klassieke' code kun je complexiteit vrij makkelijk achterhalen uit de verspringing van de code: zodra je een conditie toevoegt of een iteratie start, zul je je code moeten laten inspringen. Zodra je streams gaat gebruiken, werk je daar feitelijk omheen door je code netjes onder elkaar te plaatsen in een wat meer 'functionele' opzet.
Het beoordelen van een stuk code op leesbaarheid, kwaliteit, complexiteit, gaat naar mijn inziens een stuk lastiger in de streams-opzet. Je zult uit het gebruik van de methodes die typerend zijn voor streams, zoals mapping en filtering, moeten opmaken wat de complexiteit is. Ik begrijp dat dit een beetje een zwart-wit voorstelling is, aangezien je bij beoordeling van een stuk code altijd de code zelf ook interpreteert, maar het hulpmiddel witruimte is/was voor mij een goed beginpunt.
Bovenstaande gaat voor mijn gevoel ook zeker op voor de huidige beweging die is ingezet met het optioneel maken van de puntkomma en haakjes. Syntaxis waarbij je werkelijk alles in je code kunt rammen, omdat de compilers tegenwoordig slim genoeg zijn geworden, zorgt voor mijn gevoel niet voor een verbetering van de gemiddelde codekwaliteit.
bovenstaand betoog zou natuurlijk een stuk lastiger maar wel mogelijk te lezen zijn geweest als ik de interpunctie die niet altijd noodzakelijk is in de nederlandse taal had weggelaten
Dat klopt zeker wel hoor. Daar zijn ze wel mee bezig maar er zit ook een reden achter; streams zijn lazy evaluated. Dus meerdere map operaties bijvoorbeeld maken niet steeds een nieuwe lijst aan; die collect is 'terminal.bwerg schreef op vrijdag 7 mei 2021 @ 13:10:
Echt ontwijken doe ik het ook niet. Maar elke keer dat ik zo'n trein apen.stream().map(aap -> aap.getBanaan()).collect(Collectors.toList) denk ik wel steeds weer "prachtig" op sarcastische toon.
Nou is de vergelijking met haskell misschien wat flauw omdat vertaling tussen lijsten/collecties en streams vaak niet bestaat in een lazy taal, terwijl het toch wel wat doet in een strikte taal. Maar even klagen kan nooit kwaad.
Maar bijv. Kotlin doet dit al veel mooier (dan heb je de keus tussen lazy en niet-lazy) en Haskell doet dit gewoon onderwater voor je.
https://niels.nu
Ach soms krijg ik ook wel eens te maken met dit soort types. Eclipse. Gebruiken geen streams want is stom. Gewoon lachen, vriendelijk ja knikkenen ondertussen lekker verder werken in Kotlin/IntelliJMugwump schreef op vrijdag 7 mei 2021 @ 13:52:
Ik zou als je Java ook professioneel gebruikt sowieso Eclipse ontwijken.
Java Streams support in IntelliJ is meer dan prima. We hebben nog een fossiel die zweert bij Eclipse in onze organisatie, maar die begint ook heel langzaam te overwegen om toch maar eens over te stappen.
https://niels.nu
Dit is echt niks meer dan gewoon ervaring. Ik ken echt geen enkele ervaren Java dev die jouw streams voorbeeld minder leesbaar zal vinden dan geneste for-loops.timosmit schreef op zaterdag 8 mei 2021 @ 11:34:
Het beoordelen van een stuk code op leesbaarheid, kwaliteit, complexiteit, gaat naar mijn inziens een stuk lastiger in de streams-opzet. Je zult uit het gebruik van de methodes die typerend zijn voor streams, zoals mapping en filtering, moeten opmaken wat de complexiteit is.
Mensen halen wel vaker "leesbaar" en "ik snap het niet" door elkaar. Dat zijn twee hele aparte zaken.
https://niels.nu
Dit. Heb er 2 blog posts over geschreven (voor mensen die het interessant vinden): https://niels.nu/blog/2018/my-move-to-kotlin en https://niels.nu/blog/2021/a-kotlin-retrospective.armageddon_2k1 schreef op zaterdag 8 mei 2021 @ 07:47:
Kotlin is love, Kotlin is life.
Je kunt wel klagen over Java maar het is volgens mij een stuk productiever om dan maar gewoon voor Kotlin of Scala (als je meer op FP wil leunen) te gaan. Groovy zou ik niet aan beginnen; dat is aan het uitsterven.
Herkenbaar. Ik heb gelukkig m'n team kunnen overtuigen om voor Kotlin te gaan, maar onze e2e tests zijn wel Java omdat de test engineer alleen Java 'kan'. Bij nader inzien wel spijt van aangezien dat "Java kunnen" ook niet veel meer is dan de hoeveelheid Kotlin die hij "kan".Als ik nu weer Java gebruik voelt het alsof ik schuurmiddel op m’n tandenborstel doe. Niet dat ik Java haat, want dat schijnt nogal populair te zijn. Maar het is gewoon uit een andere tijd en heeft zo’n gigantische installed base dat hun manoeuvreersnelheid gewoon wat anders is. Kotlin is natuurlijk mini vergeleken met Java. Populair zeker, maar het is alsof je Tesla met VAG vergelijkt. Mooie autootjes en lopen vooruit, maar totaal aantal verkopen nog geen fractie van de concurrentie.
https://niels.nu
Tip: Kotlin Koans.Koenvh schreef op vrijdag 7 mei 2021 @ 16:47:
Ik vind Kotlin erg leuk, maar ik vind de hoeveelheid syntactische suiker in eerste instantie wel overweldigend.
De nieuwe syntax heeft een beetje ervaren Java dev in een dag behoorlijk in de vingers. Heb in zowel m'n huidige team als m'n vorige 2 te maken gehad met mensen die vanaf nul Kotlin kennis kwamen (heb daar o.a. workshops in georganiseerd) en het kost echt geen tijd mensen productief te laten zijn.
En de null-safety is echt een killer features. Samen met alle 'nice to haves' in Kotlin (en dat zijn er nogal wat) maakt het je gewoon productiever.
Begrijp me niet verkeerd; Java gaat ook echt hard tegenwoordig (records zijn fijn bijvoorbeeld en met Loom en valhalla komt er nog meer coole shit aan) maar sinds ik in Kotlin werk is het gewoon best of both worlds; het JVM ecosysteem met een moderne fijne taal.
https://niels.nu
Offtopic, maarre.... Doe je er normaalgesproken liever mayonaise op dan?armageddon_2k1 schreef op zaterdag 8 mei 2021 @ 07:47:
Als ik nu weer Java gebruik voelt het alsof ik schuurmiddel op m’n tandenborstel doe.
Speculoos. Ben ik daar de enige in dan?mcDavid schreef op zaterdag 8 mei 2021 @ 12:22:
[...]
Offtopic, maarre.... Doe je er normaalgesproken liever mayonaise op dan?Tandpasta ís schuurmiddel.
Maareuh... scherp inderdaad. Ik bedoel natuurlijk asfalt.
Engineering is like Tetris. Succes disappears and errors accumulate.
Ik gebruik altijd Jif...mcDavid schreef op zaterdag 8 mei 2021 @ 12:22:
Tandpasta ís schuurmiddel.
https://niels.nu
Je moet wat als parodontax je niet meer je frisse smaak geeft
Meer gewoon: "code completion? Ik copy paste gewoon bestaande code en dan pas ik die aan".Hydra schreef op zaterdag 8 mei 2021 @ 11:49:
[...]
Ach soms krijg ik ook wel eens te maken met dit soort types. Eclipse. Gebruiken geen streams want is stom. Gewoon lachen, vriendelijk ja knikkenen ondertussen lekker verder werken in Kotlin/IntelliJ
Lekker 25 geneste try-catch-finally's en je dan afvragen waarom je die resource leaks zo moeilijk kunt vinden.
"The question of whether a computer can think is no more interesting than the question of whether a submarine can swim" - Edsger Dijkstra
Probleem zit 'm in het "ervaren" gedeelte. Soms is het wel fijn dat een taal minder eigenaardige constructies heeft, want dan kunnen andere mensen ook geen (of minder) rare fratsen uithalen.Hydra schreef op zaterdag 8 mei 2021 @ 11:59:
[...]
Tip: Kotlin Koans.
De nieuwe syntax heeft een beetje ervaren Java dev in een dag behoorlijk in de vingers. Heb in zowel m'n huidige team als m'n vorige 2 te maken gehad met mensen die vanaf nul Kotlin kennis kwamen (heb daar o.a. workshops in georganiseerd) en het kost echt geen tijd mensen productief te laten zijn.
En de null-safety is echt een killer features. Samen met alle 'nice to haves' in Kotlin (en dat zijn er nogal wat) maakt het je gewoon productiever.
Begrijp me niet verkeerd; Java gaat ook echt hard tegenwoordig (records zijn fijn bijvoorbeeld en met Loom en valhalla komt er nog meer coole shit aan) maar sinds ik in Kotlin werk is het gewoon best of both worlds; het JVM ecosysteem met een moderne fijne taal.
🠕 This side up
Ik vind Kotlin daar nogal in meevallen hoor. Welke dingen bedoel je dan precies? Scala is daar m.i. veel erger in; daar zie je vaak dat libraries helemaal een eigen DSL bouwen die je dan ook nog eens moet gaan 'leren'. Kotlin geeft je daar veel minder vrijheid in.Koenvh schreef op zaterdag 8 mei 2021 @ 15:06:
Probleem zit 'm in het "ervaren" gedeelte. Soms is het wel fijn dat een taal minder eigenaardige constructies heeft, want dan kunnen andere mensen ook geen (of minder) rare fratsen uithalen.
https://niels.nu
Ja, en stopte je de binnenste for-loop of dat binnenste statement in een losse functie en weg is je "complexiteit-in-een-oogopslag".timosmit schreef op zaterdag 8 mei 2021 @ 11:34:
Waar je met geneste for/while-loops een duidelijk overzicht kunt krijgen van de complexiteit van je code, is dit door gebruik van Java streams een stuk verder door de taal geabsorbeerd. Neem het volgende voorbeeld:
Java:
1 2 3 4 5 6 7 8 9 10 final List<List<List<String>>> listOflistOfListOfStrings = List.of(List.of(List.of("Hello Tweakers.net"))); for (List<List<String>> listOfListOfStrings : listOflistOfListOfStrings) { for (List<String> listOfStrings : listOfListOfStrings) { for (String str : listOfStrings) { System.out.println(str); } } }
Generieke basisconcepten als maps en flatmaps zul je toch gewoon moeten leren kennen, net zoals for-loops, en dan hoef je daarna nooit meer 'door te klikken' om de complexiteit te achterhalen. Je zult net zo goed moeten weten wat die System.out.println(str); eigenlijk doet om de complexiteit te bepalen.
Altijd alle boilerplate uitschrijven om expliciet te zijn is leuk voor de nieuweling die net een nieuwe taal aan het leren is. Natuurlijk is het ook niet altijd goed om obscure features te gebruiken die niemand snapt/kent, maar als je generieke concepten als streams en maps niet kent doe je als programmeur toch wel iets fout.
[ Voor 12% gewijzigd door bwerg op 08-05-2021 15:23 ]
Heeft geen speciale krachten en is daar erg boos over.
Hydra schreef op zaterdag 8 mei 2021 @ 11:51:
Mensen halen wel vaker "leesbaar" en "ik snap het niet" door elkaar. Dat zijn twee hele aparte zaken.
In mijn geval heeft het niks te maken met 'niet snappen'. Tijdens mijn werk maak ik ook gewoon gebruik van streams zodra de situatie zich daarvoor leent, dus ik ben er ook niet pertinent op tegen. Een stuk code waarin streams worden gebruikt, vind ik ook prima leesbaar. Ik wilde slechts een kanttekening plaatsen bij iets wat ik persoonlijk als nadeel van streams zie. Blijkbaar was dat niet duidelijk uit mijn bericht, dus mijn excuses daarvoor.bwerg schreef op zaterdag 8 mei 2021 @ 15:21:
Generieke basisconcepten als maps en flatmaps zul je toch gewoon moeten leren kennen, net zoals for-loops, en dan hoef je daarna nooit meer 'door te klikken' om de complexiteit te achterhalen. Je zult net zo goed moeten weten wat die System.out.println(str); eigenlijk doet om de complexiteit te bepalen.
Heeft @Firesphere al een helmpje gekocht ?
Maar is de extra type informatie nuttig voor dat stuk code? Voor je .flatMap(List::stream) maakt het helemaal niet uit wat er in de List zit, in een beetje high-level taal zal de compiler dat ook niet eens hoeven te weten.timosmit schreef op zaterdag 8 mei 2021 @ 11:34:
[...]
Tegelijkertijd moet je je denk ik ook afvragen in hoeverre je dan efficiënt bezig bent. Om het volgende citaat er ook meteen maar even bij te pakken:
[...]
Van de Java-afgeleiden (Kotlin, Scala, Groovy) vind ik persoonlijk Kotlin nog niet eens overweldigend aangezien ze je nog ergens binnen een bepaald stramien proberen te laten werken. Als ik kijk naar Groovy en wat daarin mogelijk is, dan begin ik me af te vragen in hoeverre de taal de onderhoudbaarheid van een stuk software bevordert. Dit gevoel krijg ik soms ook bij het lezen van Kotlin en Scala, weliswaar in mindere mate, maar ook Java streams.
Waar je met geneste for/while-loops een duidelijk overzicht kunt krijgen van de complexiteit van je code, is dit door gebruik van Java streams een stuk verder door de taal geabsorbeerd. Neem het volgende voorbeeld:
Java:
1 2 3 4 5 6 7 8 9 10 final List<List<List<String>>> listOflistOfListOfStrings = List.of(List.of(List.of("Hello Tweakers.net"))); for (List<List<String>> listOfListOfStrings : listOflistOfListOfStrings) { for (List<String> listOfStrings : listOfListOfStrings) { for (String str : listOfStrings) { System.out.println(str); } } }
Dit zou er met een Java stream bijvoorbeeld zo uit zien:
Java:
1 2 3 4 listOflistOfListOfStrings.stream() .flatMap(List::stream) .flatMap(List::stream) .forEach(System.out::println);
Nu zijn er natuurlijk een aantal kanttekeningen bij bovenstaand voorbeeld te plaatsen: het bevat verder geen extra complexiteit zoals condities, en de typering en naamgeving verraadt al een groot deel van de complexiteit. Normaliter zou een deel van de generics zijn vervangen door domeinobjecten en zouden mogelijk loops zijn vervangen door methodes. Dit zorgt er dus voor dat de complexiteit verborgen raakt in objecten en methodes, hoewel de leesbaarheid wordt verbeterd. Daarmee valt de complexiteit dus niet meer uit de typering en naamgeving te halen, en zul je zijn aangewezen op je kennis van het domein en de code an sich. Desalniettemin geeft het hopelijk een goed beeld van het gevoel wat ik krijg bij het gebruik van streams.
Maar goed, dit laat ook direct de limitaties van de Java stream zien. Je bent nu een platgeslagen stream van streams aan het bouwen omdat je een functie wilt aanroepen voor elk item in je geneste list. In principe zou je die hele data structuur niet hoeven om te bouwen, maar gewoon die functie aanroepen in een 'geneste' map. Dus een compositie van map met map met map. Haskell voorbeeldje (maar dit kan in elke (ook stricte) functionele taal):
Haskell:
1
2
3
4
5
6
7
8
9
| fmap3 :: (Functor f, Functor g, Functor h) => (a -> b) -> f (g (h a)) -> f (g (h b)) fmap3 = fmap . fmap . fmap list :: [[[Int]]] list = [ [ [1,2],[3,4] ], [ [5,6],[5,6] ] ] main :: IO () main = print $ fmap show list |
Zijn voorbeeld is gewoon extreem gezocht. Als je code hebt met lijsten van strings 3 niveau's diep waarop je dan sysout aan moet roepen, dan heb je ook wel een erg vreemd stuk applicatiecode.RagingPenguin schreef op zaterdag 8 mei 2021 @ 18:51:
Maar goed, dit laat ook direct de limitaties van de Java stream zien. Je bent nu een platgeslagen stream van streams aan het bouwen omdat je een functie wilt aanroepen voor elk item in je geneste list. In principe zou je die hele data structuur niet hoeven om te bouwen, maar gewoon die functie aanroepen in een 'geneste' map. Dus een compositie van map met map met map. Haskell voorbeeldje (maar dit kan in elke (ook stricte) functionele taal):
In het dagelijks leven loop je eigenlijk nooit tegen dat soort limieten aan. Niet dat ik een enorm fan ben van alle ceremonie van Java streams, maar het werkt prima.
https://niels.nu
Waarom niet fmap fmap (fmap fmap fmap)?RagingPenguin schreef op zaterdag 8 mei 2021 @ 18:51:
Haskell:
1 2 fmap3 :: (Functor f, Functor g, Functor h) => (a -> b) -> f (g (h a)) -> f (g (h b)) fmap3 = fmap . fmap . fmap
Ipsa Scientia Potestas Est
NNID: ShinNoNoir
Haakjes zijn voor plebs
Natuurlijk werkt het prima. Maar ook in het orginele en meer realistisch voorbeeldHydra schreef op zaterdag 8 mei 2021 @ 19:19:
[...]
Zijn voorbeeld is gewoon extreem gezocht. Als je code hebt met lijsten van strings 3 niveau's diep waarop je dan sysout aan moet roepen, dan heb je ook wel een erg vreemd stuk applicatiecode.
In het dagelijks leven loop je eigenlijk nooit tegen dat soort limieten aan. Niet dat ik een enorm fan ben van alle ceremonie van Java streams, maar het werkt prima.
Java:
1
| apen.stream().map(aap -> aap.getBanaan()).collect(Collectors.toList) |
Is meer dan de helft van de code boilerplate. Dan heeft bv. Microsoft het met LINQ en C# toch een stuk beter bekeken:
C#:
1
2
3
| apen.Select(aap => aap.getBanaan()); // of als je per se een list moet hebben: apen.Select(aap => aap.getBanaan()).ToList(); |
fmap `fmap` fmap fmap fmap dan?
Ipsa Scientia Potestas Est
NNID: ShinNoNoir
Hey, da's niet waar, hé!
Haakjes zijn voor plebs en lisp-gebruikers.
Ben jij mijn voormalig FP-docent?
Die was er van overtuigd dat de wereld dit soort cryptogrammen nodig had.
Heeft geen speciale krachten en is daar erg boos over.
Gezien ik nooit gefungeerd heb als docent lijkt me de kans klein.bwerg schreef op zaterdag 8 mei 2021 @ 23:20:
[...]
Ben jij mijn voormalig FP-docent?
Die was er van overtuigd dat de wereld dit soort cryptogrammen nodig had.
Heb wel ooit Haskell-practica geassisteerd als studentassistent.
Ipsa Scientia Potestas Est
NNID: ShinNoNoir
Het is tegenwoordig:RagingPenguin schreef op zaterdag 8 mei 2021 @ 20:44:
Natuurlijk werkt het prima. Maar ook in het orginele en meer realistisch voorbeeld
Java:
1 apen.stream().map(aap -> aap.getBanaan()).collect(Collectors.toList)
Java:
1
| apen.stream().map(Aap::getBanaan).toList() |
Als je het nog korter wil, dan kun je beter Kotlin gebruiken
https://niels.nu
Heel veel korter gaat het niet worden met Kotlin. Dat voegt imho ook niet zoveel meer toe.
Engineering is like Tetris. Succes disappears and errors accumulate.
Je hebt de .stream() en de .toList niet nodig, ervanuitgaande dat apen een list is:armageddon_2k1 schreef op zondag 9 mei 2021 @ 08:30:
Heel veel korter gaat het niet worden met Kotlin. Dat voegt imho ook niet zoveel meer toe.
code:
1
| apen.map(Aap::getBanaan) |
Of:
code:
1
| apen.map { it.getBanaan() } |
Dus
[ Voor 6% gewijzigd door Hydra op 09-05-2021 09:50 ]
https://niels.nu
@Hydra
Dan gaan we maar helemaal los (Playground)
Jij hebt 27 chars, ik 10. Toch weer vooruitgang.
Nu ga ik douchen, want ik voel me vies.
Dan gaan we maar helemaal los (Playground)
Kotlin:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
| data class Ape(val name: String, val banana: String) /* For the crazy part */ typealias A = Ape val A.b get() = banana operator fun <T, R> Iterable<T>.invoke(block: (T) -> R) = this.map(block) fun main() { val apes = listOf( Ape("Bokito", "Chiquita"), Ape("Koko", "Organic"), Ape("Harambe", "Costco") ) // Like verbose people println(apes.map { ape -> ape.banana }) // Like normal people println(apes.map { it.banana} ) // Like obsessed people println(apes.map(Ape::banana)) // Like crazy people println(apes(A::b)) } |
Jij hebt 27 chars, ik 10. Toch weer vooruitgang.
Nu ga ik douchen, want ik voel me vies.
[ Voor 83% gewijzigd door armageddon_2k1 op 09-05-2021 14:00 ]
Engineering is like Tetris. Succes disappears and errors accumulate.
armageddon_2k1 schreef op zondag 9 mei 2021 @ 13:51:
@Hydra
Dan gaan we maar helemaal los (Playground)
Kotlin:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 data class Ape(val name: String, val banana: String) /* For the crazy part */ typealias A = Ape val A.b get() = banana operator fun <T, R> Iterable<T>.invoke(block: (T) -> R) = this.map(block) fun main() { val apes = listOf( Ape("Bokito", "Chiquita"), Ape("Koko", "Organic"), Ape("Harambe", "Costco") ) // Like verbose people println(apes.map { ape -> ape.banana }) // Like normal people println(apes.map { it.banana} ) // Like obsessed people println(apes.map(Ape::banana)) // Like crazy people println(apes(A::b)) }
Jij hebt 27 chars, ik 10. Toch weer vooruitgang.
Nu ga ik douchen, want ik voel me vies.
Haskell:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
| data Ape = Ape { name :: String, banana :: String } apes :: [Ape] apes = [ Ape "Bokito" "Chiquita", Ape "Koko" "Organic", Ape "Harambe" "Costco" ] main :: IO () main = do let a = apes let b = banana -- Like verbose people print (fmap (\ape -> banana ape) apes) -- Like less verbose people print $ fmap (\ape -> banana ape) apes -- Like normal people print $ fmap banana apes -- Like crazy people print $ map b a |
Ik bied 7
Het zouden er ook nog 5 kunnen zijn met een let m = map. Dan heb je maar 3 letters voor 3 dingen en twee spaties om ze met elkaar te verbinden. Ik denk dat dat het absolute minimum is wat mogelijk is in een beetje realistische taal. Hetzelfde kan btw ook in F# en ik verwacht in elke taal in de ML-familie (playground).
[ Voor 6% gewijzigd door RagingPenguin op 09-05-2021 16:17 ]
RagingPenguin schreef op zondag 9 mei 2021 @ 14:24:
Haskell:
1 2 -- Like normal people print $ fmap banana apes
Haskell:
1
2
3
| -- Like obscure people who don't mind checking up on precedence of obscure operators print $ banana <$> apes print $ peel . banana <$> apes |
Het gehalte "het is voor de leek niet meer zo goed te lezen" neemt zo wel wat toe.
En hoe zeer ik Haskell ook waardeer, zodra er ook nog <*>, <**>, <<**>> tussendoor komt moet ik het op papier uitschrijven.
[ Voor 29% gewijzigd door bwerg op 09-05-2021 23:18 ]
Heeft geen speciale krachten en is daar erg boos over.
armageddon_2k1 schreef op zondag 9 mei 2021 @ 13:51:
Jij hebt 27 chars, ik 10. Toch weer vooruitgang.
Nu ga ik douchen, want ik voel me vies.
code:
1
2
3
| operator fun List<Ape>.not() = map { it.banana } println(!apes) |
En nu?
[ Voor 6% gewijzigd door Hydra op 10-05-2021 11:11 ]
https://niels.nu
Met allemaal helpers/aliassen e.d. kan je in een taal als C/C++ met macro's het natuurlijk gewoon in 1 character doen als je zo flauw rekent om de extra helpers/aliassen niet mee te tellen
“Build a man a fire, and he'll be warm for a day. Set a man on fire, and he'll be warm for the rest of his life.”
Ja ik kan ook wel een prepocessor maken die bovenstaande in nul karakters doet natuurlijk...Woy schreef op maandag 10 mei 2021 @ 11:14:
Met allemaal helpers/aliassen e.d. kan je in een taal als C/C++ met macro's het natuurlijk gewoon in 1 character doen als je zo flauw rekent om de extra helpers/aliassen niet mee te tellen
https://niels.nu
Batchfile:
1
2
3
| echo Chiquita echo Organic echo Costco |
Of we optimaliseren het gewoon door het handmatig te optimaliseren... Hoe bedoel je dit is niet meer in-scope?
"Doubt—the concern that my views may not be entirely correct—is the true friend of wisdom and (along with empathy, to which it’s related) the greatest enemy of polarization." -- Václav Havel
Wat voor business werken jullie in dat jullie heel de tijd bezig zijn met apen en bananen?
Exact expert nodig?
Het hele devteam van de Apenheul zit hier kennelijk.Crazy D schreef op maandag 10 mei 2021 @ 11:39:
Wat voor business werken jullie in dat jullie heel de tijd bezig zijn met apen en bananen?
"The question of whether a computer can think is no more interesting than the question of whether a submarine can swim" - Edsger Dijkstra
Nou veel van de legacy code kan niet door mensen geschreven zijn dus ik sorteer vast voor op het moment dat ik die developers ontmoet.Crazy D schreef op maandag 10 mei 2021 @ 11:39:
Wat voor business werken jullie in dat jullie heel de tijd bezig zijn met apen en bananen?
https://niels.nu
Da's langer dan de mijneDevWouter schreef op maandag 10 mei 2021 @ 11:30:
Of we optimaliseren het gewoon door het handmatig te optimaliseren...
https://niels.nu
Ik ga vanmiddag beginnen met een versie welke juist het tegenovergestelde gaat doen met een PrimateBananaAccessorFactoryBuilder.
Engineering is like Tetris. Succes disappears and errors accumulate.
Ik mis op z'n minst Abstract, Singleton en Bean nog in die naam!armageddon_2k1 schreef op maandag 10 mei 2021 @ 12:43:
Ik ga vanmiddag beginnen met een versie welke juist het tegenovergestelde gaat doen met een PrimateBananaAccessorFactoryBuilder.
https://niels.nu
Dit topic is gesloten.
Let op:
Dit topic is niet de plaats om te lopen helpdesken. De Coffee Corner is primair bedoeld als uitlaatklep voor iedereen in de Devschuur® en niet als vraagbaak.
Dit topic is niet de plaats om te lopen helpdesken. De Coffee Corner is primair bedoeld als uitlaatklep voor iedereen in de Devschuur® en niet als vraagbaak.