🠕 This side up
Less alienation, more cooperation.
DTOs zijn een toepassing, maar bijvoorbeeld ook value objects.Sandor_Clegane schreef op zaterdag 15 september 2018 @ 09:12:
Hebben ze DTO's aan de taal toegevoegd?
"The question of whether a computer can think is no more interesting than the question of whether a submarine can swim" - Edsger Dijkstra
Wel leuk om te kijken voor een introductie.
Je krijgt ook een beetje medelijden met hem, maar ik zou waarschijnlijk ook zo voor een grote zaal staan
Zo herkenbaar...
In ieder geval kan ik nog een hoop veranderen aan mijn code
PS
Leuk stukje vind ik dat van die onnodige casts... "Why don't you know its type?! Well... now it knows"
En "don't try to check if something is odd or even like I do, it will hurt"

[ Voor 27% gewijzigd door Lethalis op 15-09-2018 11:18 ]
Ask yourself if you are happy and then you cease to be.
Ik vind F# echt zo'n mooi taaltje. En die data class lijken me redelijk op records alleen kun je die in F# ook weer uitbreiden. Dat is juist zo mooi, er is niet echt een onderscheid.
En het option type is briljant en het result type en async workflows en de discriminated unions en pattern matching en en en en..... na ja je snapt het wel.
Misschien wel mooi omdat het op de JVM draait.
Edit: Ooit ga ik Erlang nog leren, dat wel.
[ Voor 24% gewijzigd door Sandor_Clegane op 15-09-2018 11:43 ]
Less alienation, more cooperation.
Voor mij de reden waarom ik Kotlin nemen over F#:Sandor_Clegane schreef op zaterdag 15 september 2018 @ 11:23:
Hmmm, waarom zou ik Kotlin over F# nemen? Serieuze vraag, geen flamebait ofzo.
Ik vind F# echt zo'n mooi taaltje. En die data class lijken me redelijk op records alleen kun je die in F# ook weer uitbreiden. Dat is juist zo mooi, er is niet echt een onderscheid.
Als Android ontwikkelaar is het veel makkelijker
Als je native Android apps wilt schrijven, dan is F# niet echt een optie.Sandor_Clegane schreef op zaterdag 15 september 2018 @ 11:23:
Hmmm, waarom zou ik Kotlin over F# nemen? Serieuze vraag, geen flamebait ofzo.
Ik vind F# echt zo'n mooi taaltje. En die data class lijken me redelijk op records alleen kun je die in F# ook weer uitbreiden. Dat is juist zo mooi, er is niet echt een onderscheid.
En het option type is briljant en het result type en async workflows en de discriminated unions en pattern matching en en en en..... na ja je snapt het wel.![]()
Misschien wel mooi omdat het op de JVM draait.
Edit: Ooit ga ik Erlang nog leren, dat wel.
Maar ik denk dat je een beetje de verkeerde vraag stelt. Het zijn twee talen in verschillende ecosystemen die een wat meer functionele aanpak kiezen. De vraag is eerder waarom F# in plaats van C of waarom Kotlin in plaats van Java in mijn ogen.
"The question of whether a computer can think is no more interesting than the question of whether a submarine can swim" - Edsger Dijkstra
Omdat Kotlin de beschikking heeft over alle libraries die Java ook heeft en daarnaast overal werkt waar de JVM draait.Sandor_Clegane schreef op zaterdag 15 september 2018 @ 11:23:
Hmmm, waarom zou ik Kotlin over F# nemen? Serieuze vraag, geen flamebait ofzo.
Voor mijn hobbyprojecten thuis - waar alles op Linux draait - betekent dit dat ik een tool in handen heb dat goed ondersteund wordt op dit platform.
F# daarentegen doet het goed op .Net en zou juist op mijn werk - waar het meeste op Windows draait - beter tot zijn recht komen.
Maar eerlijk is eerlijk, Kotlin is vooral interessant omdat Java lang stil gestaan heeft.
De redenen dat ik op mijn werk geen F# gebruik, zijn:
1. Het bij Microsoft vaak een after thought was. Ze hebben eigenlijk pas recent hun commitment aan F# weer laten zien.
2. C# zoveel nieuwe features heeft gekregen, dat de noodzaak om F# te gebruiken vrij klein is.
PS
Ik heb alles al een beetje gemoderniseerd. De BufferedReader wordt nu netjes gesloten met een Kotlin use constructie, en ik gebruik een immutable data class voor de JobDetails en JobResult
Sowieso heb ik zoveel mogelijk var's vervangen door val's.
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 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 package mailer import com.fasterxml.jackson.databind.SerializationFeature import com.fasterxml.jackson.dataformat.xml.XmlMapper import java.nio.file.Files import java.nio.file.Paths import org.apache.commons.mail.DefaultAuthenticator import org.apache.commons.mail.HtmlEmail import java.io.BufferedReader import java.io.InputStreamReader import java.net.InetAddress class MailConfiguration { var server: String = "127.0.0.1" var port: Int = 25 var useSSL: Boolean = false var useCredentials: Boolean = false var username: String? = null var password: String? = null } fun initMailConfiguration(): MailConfiguration { val xmlMapper = XmlMapper() xmlMapper.enable(SerializationFeature.INDENT_OUTPUT) val homePath = Paths.get(System.getProperty("user.home")) val configPath = homePath.resolve("Mailer.Config") if (Files.exists(configPath)) { val result = xmlMapper.readValue(configPath.toFile(), MailConfiguration::class.java) return result } else { var defaultConfiguration = MailConfiguration() xmlMapper.writeValue(configPath.toFile(), defaultConfiguration) return defaultConfiguration } } data class JobDetails ( val mailTo: String, val mailFrom: String, val jobName: String, val arguments: Array<String> ) class JobException(override var message: String) : Exception(message) fun initJobDetails(args: Array<String>): JobDetails { val mailTo = System.getenv("MAILTO") val mailFrom = System.getenv("MAILFROM") val jobName = System.getenv("JOBNAME") if (mailTo == null) throw JobException("MAILTO environment variable not set") if (mailFrom == null) throw JobException("MAILFROM environment variable not set") if (jobName == null) throw JobException("JOBNAME environment variable not set") if (args.count() == 0) throw JobException("Please specify a command") return JobDetails(mailTo, mailFrom, jobName, args) } data class JobResult(val exitCode: Int, val output: String) fun runJob(job: JobDetails): JobResult { val builder = ProcessBuilder(job.arguments.toList()) builder.redirectErrorStream(true) val process = builder.start() val sb = StringBuilder() BufferedReader(InputStreamReader(process.inputStream)).use { reader -> var line = reader.readLine() while (line != null) { sb.append(line) sb.append(System.getProperty("line.separator")) line = reader.readLine() } } process.waitFor() return JobResult(process.exitValue(), sb.toString()) } fun main(args: Array<String>) { try { val cfg = initMailConfiguration() val job = initJobDetails(args) val jobResult = runJob(job) val address = InetAddress.getLocalHost() val description = "${address.hostName}: ${job.jobName} ${if (jobResult.exitCode == 0) "succeeded" else "failed"}" val html = """ <html> <body> <h1>${description}</h1> <pre><code>${jobResult.output}</code></pre> </body> </html> """.trimIndent() // Mail the results val email = HtmlEmail() email.hostName = cfg.server email.setSmtpPort(cfg.port) if (cfg.useSSL) { email.isStartTLSEnabled = true } if (cfg.useCredentials) { email.setAuthenticator(DefaultAuthenticator(cfg.username, cfg.password)) } email.setFrom(job.mailFrom) email.addTo(job.mailTo) email.subject = description email.setHtmlMsg(html) email.send() } catch (ex: Exception) { println(ex.message) } }
[ Voor 77% gewijzigd door Lethalis op 15-09-2018 14:07 ]
Ask yourself if you are happy and then you cease to be.
Bestaan er geen constants? Zoals var server is een constant als je het mij vraagt.Lethalis schreef op zaterdag 15 september 2018 @ 12:15:
[...]
Omdat Kotlin de beschikking heeft over alle libraries die Java ook heeft en daarnaast overal werkt waar de JVM draait.
Voor mijn hobbyprojecten thuis - waar alles op Linux draait - betekent dit dat ik een tool in handen heb dat goed ondersteund wordt op dit platform.
F# daarentegen doet het goed op .Net en zou juist op mijn werk - waar het meeste op Windows draait - beter tot zijn recht komen.
Maar eerlijk is eerlijk, Kotlin is vooral interessant omdat Java lang stil gestaan heeft.
De redenen dat ik op mijn werk geen F# gebruik, zijn:
1. Het bij Microsoft vaak een after thought was. Ze hebben eigenlijk pas recent hun commitment aan F# weer laten zien.
2. C# zoveel nieuwe features heeft gekregen, dat de noodzaak om F# te gebruiken vrij klein is.
PS
Ik heb alles al een beetje gemoderniseerd. De BufferedReader wordt nu netjes gesloten met een Kotlin use constructie, en ik gebruik een immutable data class voor de JobDetails en JobResult
Sowieso heb ik zoveel mogelijk var's vervangen door val's.
[...]
Ja natuurlijk, dat zijn de "val". Het punt met de MailConfiguration class is dat deze met een XML mapper (voor Java) gevuld wordt. Om die reden zijn de properties in dit geval niet read only.Douweegbertje schreef op zaterdag 15 september 2018 @ 14:27:
[...]
Bestaan er geen constants? Zoals var server is een constant als je het mij vraagt.
Kijk je naar de JobDetails en JobResult classes, dan zie je dat dit (inmiddels) immutable objects zijn.
1
2
3
4
5
6
| data class JobDetails ( val mailTo: String, val mailFrom: String, val jobName: String, val arguments: Array<String> ) |
Deze class heeft 1 constructor en kan daarna niet meer gewijzigd worden.
[ Voor 19% gewijzigd door Lethalis op 15-09-2018 14:43 ]
Ask yourself if you are happy and then you cease to be.
"The question of whether a computer can think is no more interesting than the question of whether a submarine can swim" - Edsger Dijkstra
aha op die fietsLethalis schreef op zaterdag 15 september 2018 @ 14:31:
[...]
Ja natuurlijk, dat zijn de "val". Het punt met de MailConfiguration class is dat deze met een XML mapper (voor Java) gevuld wordt. Om die reden zijn de properties in dit geval niet read only.
Kijk je naar de JobDetails en JobResult classes, dan zie je dat dit (inmiddels) immutable objects zijn.
Kotlin:
1 2 3 4 5 6 data class JobDetails ( val mailTo: String, val mailFrom: String, val jobName: String, val arguments: Array<String> )
Deze class heeft 1 constructor en kan daarna niet meer gewijzigd worden.
thanks
Waarom F# ipv C#? Paar redenen: Geen accolades geen ";" alles is immutable bij default. Dat lijkt een stomme reden maar ik moet zeggen dat ik het na een tijdje geweldig ben gaan vinden, weinig boilerplate. De list operators zijn echt geweldig en async workflows zijn gemakkelijker dan async/await in mijn ogen.
F# heeft standaard de mailboxprocessor aan boord waardoor het heel gemakkelijk is om een queue systeem te maken zonder dat je allerlei extra foefjes hoeft uit te halen. Ik gebruik deze redelijk vaak als ik een soort van state machine moet maken. Erlang for dummies zeg maar.
Lightweight types: Je hebt wel klassen, maar het hoeft niet. Records zijn simpel en DUs zijn helemaal mooi om je domain te modelleren. Standaard hebben deze structural equality en nog paar andere handigheidjes aan boord waardoor het niet erg is om veel types te hebben en het ook niet lastig is om deze te maken.
De compiler is geweldig, miept de compiler niet dan heb je grote kans dat je programma gewoon werkt. Dit is in mijn ervaring met C# wel anders. Ik heb al meerdere keren flinke stukken code lopen refactoren zonder problemen wat een stuk gemakkelijker is doordat de compiler constant mee loopt en ook aangeeft wanneer je iets vergeet. Bijvoorbeeld in je patternmatching een mogelijke waarde vergeten.
Source code volgordelijkheid, F# werkt van boven naar onder waardoor het uitmaakt in welke volgorde files staan. Veel mensen vinden dit dom, maar ik heb gemerkt dat het je dwingt lagen aan te houden die je als software developer sowieso vaak aan wilt houden. Bovenaan je Types dan je DB laag etc. etc.
Geen geneuzel met een file per klasse, gewoon types bij types, het kan wel, maar het hoeft niet. En als je Type maar 4 regels is, waarom hem dan in een andere file plempen? Hierdoor is je solution kleiner en, in mijn optiek, gemakkelijker te doorgronden waardoor de "cognitive load" lager is.
De community, Microsoft heeft F# vaak behandeld als stiefkindje maar daar lijkt verandering in te komen. Nou maakt mij dat niet echt veel uit omdat er een goede community is waar veel slimme mensen actief bijdragen aan de taal via F# uservoice en dergelijke. Een mooi voorbeeld hiervan is Fable, Fake, Paket ( nuget on steroids ) en type providers.
Ik weet niet wat het probleem van MS met F# is maar ik had altijd het idee dat ze het niet zo op prijs stelden dat er een andere taal was die geavanceerder was dan C#, dat trokken ze slecht leek het. Generics in C# komen ook bij Don Syme vandaan, de maken van F#.
De REPL is geweldig, gewoon code selecteren ALT + Enter en het staat in een interactieve sessie. Hoe vaak ik dit wel niet gebruik om even te testen of een functie doet wat ik wil zonder dat ik mijn hele programma hoef te compileren. Kan wel wat slicker ( geen intellisense in FSI
Draait op .Net dus alle libraries die met .Net werken werken ook met F#. Met .Net core draait het ook prima multiplatform. Ze hadden beter al die energie in Mono kunnen stoppen naar mijn mening maar dat is weer een ander verhaal.
Met Xamarin kun je in principe prima Android en Ios applicaties bouwen, zelfs met Fable en React Native werkt dit, dus ook dit zit wel goed denk ik. Komt nog eens bij dat de F# community een van de eersten waren die het model van Elm hebben overgenomen om applicaties te bouwen, Model View Update, waar ik ook wel een toekomst voor zie. Ik vind het een mooie en simpele manier om over applicaties en state te redeneren, wat vaak lastig is. Omdat alles in F# immutable is leent deze zich daar enorm goed voor.
Geen null! Dit is echt zo fijn, alles moet juist geïnitialiseerd worden ander compileert je programma niet eens. Dit tezamen met het option type geeft je de mogelijkheid om hele robuuste code te schrijven wat ook nog eens goed leesbaar is.
1
2
3
4
5
6
7
| type Foo = { Bar: string option } let bla = { Bar = Some "Tekst"} if bla.Bar.IsSome then printfn "%s" bla.Bar.Value else printfn "Niks!" |
En dan nog wel een paar dingen.
Wat me vooral stoort aan OO talen is dat je vaak langer bezig bent om uit te vogelen HOE je code moet schrijven dan dat je daadwerkelijk code aan het schrijven bent. En dan bedoel ik vooral het geneuzel over architectuur en dergelijke. Komt nog eens bij dat er flink ge-cargocult wordt en dan is het feestje compleet.
Dit laatste is wel gechargeerd maar is wel iets wat me steeds meer stoort.
@Lethalis ik compileer mijn F# project direct naar Raspbian, werkt goed en ook Visual Studio Code op Linux is goed te doen met F#, helemaal met Ionide.
[ Voor 5% gewijzigd door Sandor_Clegane op 15-09-2018 16:19 ]
Less alienation, more cooperation.
Ik denk dat adoptie onder developers gewoon vaak de bottleneck is. Er zijn heel veel developers die maar met het veel moeite enigszins acceptabele OO code kunnen schrijven, laat staan dat ze het hele functionele paradigma er ook nog bij moeten leren.
Het enige waar ik in OO talen nog wel eens wat moeite mee heb is wat meer geavanceerd gebruik van generics.
Cargo cult zie je inderdaad heel veel. Mensen die per se een ORM of DI frameworkje in willen zetten, maar niet snappen waarom. Altijd maar blind alles waar Sonar zegt opvolgen.
Maar is dat specifiek inherent aan OO talen of is dat gewoon het gevolg van de populariteit van die talen en dat veel developers vaak niet echt snappen wat ze doen?
Het eerste wat ik vraag als ik code review is waarom bepaalde ontwerpkeuzes zijn gemaakt en daar volgt niet zelden een antwoord in de trant van "dat doe ik altijd zo" op.
"The question of whether a computer can think is no more interesting than the question of whether a submarine can swim" - Edsger Dijkstra
Geldt daar dan niet hetzelfde voor als voor C#?Sandor_Clegane schreef op zaterdag 15 september 2018 @ 16:02:
@Lethalis ik compileer mijn F# project direct naar Raspbian, werkt goed en ook Visual Studio Code op Linux is goed te doen met F#, helemaal met Ionide.
Neem een Synology NAS die Mono 4.6 draait, en dus maar .Net standard 1.0 ondersteunt (wellicht met moeite 1.6 maar dat terzijde).
Als ik dan direct op die NAS iets wil draaien (dus niet in Docker) dan kom ik in de problemen als ik .Net Standard 2.0 target en nodig heb (voor bijvoorbeeld System.Net.Mail).
De workaround zou dan zijn om de full CLR, bijvoorbeeld .Net 4.5 te targetten.
Maar omdat ik geen Windows draai, heb ik niet de juiste compilation / distribution pack daarvoor.
En dan wordt het nasty...
Er is dus een verschil tussen "werken op Linux" en "volledig ondersteund worden door zo ongeveer alles dat Linux draait".
Op diezelfde Synology installeer ik via de package manager Java 8 en dan doen mijn Kotlin programma's het out of the box daar op.
Hetzelfde geldt voor Python. Dat doet het echt overal en is vaak standaard al geïnstalleerd.
Ask yourself if you are happy and then you cease to be.
Één van de redenen dat Java zich traag ontwikkelt is omdat er heel veel waarde aan backwards compatibility wordt gehecht.
"The question of whether a computer can think is no more interesting than the question of whether a submarine can swim" - Edsger Dijkstra
Okee Python 3 moet je soms apart installerenMugwump schreef op zaterdag 15 september 2018 @ 17:38:
Python doet het overal? Ik hoor toch regelmatig mensen vloeken over het feit dat er twee echt gescheiden versies zijn waarbij 3 niet backwards compatibele is.
Één van de redenen dat Java zich traag ontwikkelt is omdat er heel veel waarde aan backwards compatibility wordt gehecht.
Wil ik ergens Mono 5.4 installeren dan mag ik het zelf gaan compileren...
Ask yourself if you are happy and then you cease to be.
Diezelfde backwards compatibility van is ook een nadeel, waardoor Java nu krakemikkige Generics (type erasure..) en Closures (scope? welke scope?) heeft.Mugwump schreef op zaterdag 15 september 2018 @ 17:38:
Één van de redenen dat Java zich traag ontwikkelt is omdat er heel veel waarde aan backwards compatibility wordt gehecht.
Er waren meerdere replies, dus ik dacht, kom laat ik eens wat uitweiden.Mugwump schreef op zaterdag 15 september 2018 @ 17:14:
Je hoeft mij niet te overtuigen van de voordelen van F# boven C# hoor.
Ik denk dat adoptie onder developers gewoon vaak de bottleneck is. Er zijn heel veel developers die maar met het veel moeite enigszins acceptabele OO code kunnen schrijven, laat staan dat ze het hele functionele paradigma er ook nog bij moeten leren.
Het functionele paradigma ken ik verder ook niet zo heel goed, ik ben ook niet echt een superslimme ontwikkelaar of zo. Ik vind het gewoon lekker werken.
Gewoon imperatieve code in F# vind ik al overzichtelijk.
Tja system.mail enzo is ruk, maar dat is meer Microsoft die alles weer opnieuw wilt doen waardoor wel alles nieuw is maar je onder de streep minder features hebt. Ook dat alles nu een losse module is ala NPM......
Less alienation, more cooperation.
Klopt, ik zou ook geen tegenstander zijn om daar eens afscheid van te nemen. Maar ja, die enorme stabiliteit is wel een voorname reden voor de populariteit in de Enterprise wereld.ThomasG schreef op zaterdag 15 september 2018 @ 17:49:
[...]
Diezelfde backwards compatibility van is ook een nadeel, waardoor Java nu krakemikkige Generics (type erasure..) en Closures (scope? welke scope?) heeft.
In het voorjaar was ik nog op JaxLondon met een paneldiscussie over de nieuwe release cyclus en daar zaten heel wat mensen in de zaal die elk half jaar een nieuwe versie veel te vaak vonden.
"The question of whether a computer can think is no more interesting than the question of whether a submarine can swim" - Edsger Dijkstra
Probleem met die snelle releases is vaak dat het tijd kost om iets onder de knie te krijgen, is er elk half jaar wat nieuws dan is het best lastig om ergens "goed" in te worden.Mugwump schreef op zaterdag 15 september 2018 @ 18:15:
[...]
Klopt, ik zou ook geen tegenstander zijn om daar eens afscheid van te nemen. Maar ja, die enorme stabiliteit is wel een voorname reden voor de populariteit in de Enterprise wereld.
In het voorjaar was ik nog op JaxLondon met een paneldiscussie over de nieuwe release cyclus en daar zaten heel wat mensen in de zaal die elk half jaar een nieuwe versie veel te vaak vonden.
Less alienation, more cooperation.
Uiteindelijk krijg je ze juist geleidelijker. Niet zelden zijn het features die al min of meer via third party libraries of frameworks beschikbaar waren.Sandor_Clegane schreef op zaterdag 15 september 2018 @ 19:04:
[...]
Probleem met die snelle releases is vaak dat het tijd kost om iets onder de knie te krijgen, is er elk half jaar wat nieuws dan is het best lastig om ergens "goed" in te worden.
En niet elke nieuwe feature is zo fors als bijvoorbeeld de streams API geïntroduceerd in Java 8.
Één van de voornaamste features in Java 10 is bijvoorbeeld variable type inference oftewel het "var" keyword. C# introduceerde dat ongeveer 11 jaar geleden.
"The question of whether a computer can think is no more interesting than the question of whether a submarine can swim" - Edsger Dijkstra
Je kan gewoon de Mono repo toevoegen op Debian installaties, heb je altijd de nieuwe.Lethalis schreef op zaterdag 15 september 2018 @ 17:44:
[...]
Okee Python 3 moet je soms apart installerenMaar het is wel altijd beschikbaar.
Wil ik ergens Mono 5.4 installeren dan mag ik het zelf gaan compileren...
Less alienation, more cooperation.
En het var keyword is ook een minefield, sommige zweren erbij anderen vinden het onleesbaar.....Mugwump schreef op zaterdag 15 september 2018 @ 19:14:
[...]
Uiteindelijk krijg je ze juist geleidelijker. Niet zelden zijn het features die al min of meer via third party libraries of frameworks beschikbaar waren.
En niet elke nieuwe feature is zo fors als bijvoorbeeld de streams API geïntroduceerd in Java 8.
Één van de voornaamste features in Java 10 is bijvoorbeeld variable type inference oftewel het "var" keyword. C# introduceerde dat ongeveer 11 jaar geleden.
Type inference is geweldig, behalve als het niet werkt.
Less alienation, more cooperation.
Die update cyclus kan vrij makkelijk gevolgd worden in kleine projecten, maar de grote Enterprise systemen gaan en stuk moeilijker en kosten veel meer tijd om de werking ervan te blijven garanderen.
En de type inference is in Java gelukkig beperkt tot de scope in methods en niet bv fields.
let the past be the past.
Net als in C# dus.SPee schreef op zaterdag 15 september 2018 @ 19:43:
En de type inference is in Java gelukkig beperkt tot de scope in methods en niet bv fields.
Ik zweer overigens bij var, ik gebruik het overal waar het kan.
Behalve hierbij:
1
2
3
4
5
6
7
8
9
10
| string something; if(someCondition) { something = GetValueForSomethingUnderNormalCircumstances(); } else { something = GetTheAlternativeValue(); } |
Nou zou ik dit ook kunnen vervarren door die if/else te herschrijven naar een ternary operator, maar dat vind ik al snel onleesbaar worden. Dat doe ik alleen maar als de check kort is en de waarde constant is.
We are shaping the future
Als je een ternary over drie regels uitsmeert is hij toch gewoon prima leesbaar?Alex) schreef op zaterdag 15 september 2018 @ 19:50:
[...]
Net als in C# dus.
Ik zweer overigens bij var, ik gebruik het overal waar het kan.
Behalve hierbij:
C#:
1 2 3 4 5 6 7 8 9 10 string something; if(someCondition) { something = GetValueForSomethingUnderNormalCircumstances(); } else { something = GetTheAlternativeValue(); }
Nou zou ik dit ook kunnen vervarren door die if/else te herschrijven naar een ternary operator, maar dat vind ik al snel onleesbaar worden. Dat doe ik alleen maar als de check kort is en de waarde constant is.
"The question of whether a computer can think is no more interesting than the question of whether a submarine can swim" - Edsger Dijkstra
Dat kan zeker, maar dan vind ik het al snel onduidelijk worden. Dan schrijf ik net zo lief een if/else.Mugwump schreef op zaterdag 15 september 2018 @ 19:56:
[...]
Als je een ternary over drie regels uitsmeert is hij toch gewoon prima leesbaar?
We are shaping the future
Een beetje de expert vs junior in het project.
let the past be the past.
We are shaping the future
Het probleem van var is dat je soms gewoon niet meer eenvoudig kunt zien wat het nu voor type is, vooral als het gechained is. Er zijn situaties waarbij var een betere optie is dan het type uitschrijven. Maar om het overal waar het kan te vervangen door var vind ik gewoonweg slecht. Vooral omdat ik mijn variabelen altijd andersom typ (ik typ het rechterdeel, en de IDE complete het linker deel; en het kan refactoren als het deteceert dat rechts vaker gebruikt wordt), vind ik var een kleine use-case hebben.Sandor_Clegane schreef op zaterdag 15 september 2018 @ 19:39:
[...]
En het var keyword is ook een minefield, sommige zweren erbij anderen vinden het onleesbaar.....
Type inference is geweldig, behalve als het niet werkt.
Pas als je te maken krijgt met expliciete interface-implementaties kan var je af en toe in de weg zitten.
We are shaping the future
Mja, dat lijkt me niet echt een reden om taalfeatures links te laten liggen.SPee schreef op zaterdag 15 september 2018 @ 20:00:
Tja, er zijn veel ontwikkelaars die daar problemen mee hebben.
Een beetje de expert vs junior in het project.
Allerhande design patterns maken code ook moeilijker te bevatten / aan te passen voor juniors, maar dat is ook geen reden om dan maar een grote procedurele brei te fabriceren.
"The question of whether a computer can think is no more interesting than the question of whether a submarine can swim" - Edsger Dijkstra
Dat is een nogal slap argument, want met diezelfde logica heb je met een beetje IDE var dus helemaal niet nodig. Het enige voordeel ervan is dat je minder hoeft te typen, maar dat is met een goede IDE toch al het geval. Ik vind de nadelen van var niet opwegen tegen de marginale voordelen.Alex) schreef op zaterdag 15 september 2018 @ 20:10:
Schrijf jij je code met Notepad ofzo? Een beetje IDE kan prima inferren wat voor type iets heeft en autosuggest je op dat moment de juiste dingen.
Pas als je te maken krijgt met expliciete interface-implementaties kan var je af en toe in de weg zitten.
Less alienation, more cooperation.
Dacht van de week ook nog even snel een typo in een field te fixen, alleen even niet bij nagedacht dat de naam gebruikt werd bij automatische json (de) serialization. Was toch wel blij met mijn regressietesten.
"The question of whether a computer can think is no more interesting than the question of whether a submarine can swim" - Edsger Dijkstra
Ik verkies var boven expliciete types om een heel stomme reden, het oogt wat netter:
1
2
3
| var bar = 1; var baz = "hallo"; var foo = FooFactory.GetFoo(); |
Ik ben ook zo iemand die regelmatig CodeMaid loslaat op files zodat alles netjes gesorteerd is
Qua language features waar ik van houd:
- null-coalescing (var bar = BarClass.GetBar() ?? new Bar();)
- null-conditional (var bar = localBarClass?.Children.FirstOrDefault(x => x.Name == "Kees")?.Something)
Vooral die laatste scheelt heel veel expliciet uitgeschreven null-checks, terwijl het hetzelfde doet.
We are shaping the future
"The question of whether a computer can think is no more interesting than the question of whether a submarine can swim" - Edsger Dijkstra
Json Type provider plus trygetvalue.Mugwump schreef op zaterdag 15 september 2018 @ 20:34:
Null-conditional is echt wel een ideaal concept inderdaad. Met name wanneer er meerdere niveaus zijn. Wel eens een project gehad waarbij het kernmodel soms wel 10 niveaus diep ging waar werkelijk alles null kon zijn van lijsten tot elementen in lijsten en ga zo maar door (brakke jsondeserialization uit slecht gevulde MongDb). Dat leverde elke release wel weer de nodige nullpointers op.
Less alienation, more cooperation.
Ja ik weet ook wel hoe je fatsoenlijke deserialization zou kunnen bewerkstelligen, maar dit was een draak van een codebase waar minimaal vijftig man aan had gewerkt met veel duplication, accidental complexity en ga zo maar door.Sandor_Clegane schreef op zaterdag 15 september 2018 @ 20:43:
[...]
Json Type provider plus trygetvalue.Problem solved
"The question of whether a computer can think is no more interesting than the question of whether a submarine can swim" - Edsger Dijkstra
Het was meer tongue in cheek vanwege de F# posts hierboven.Mugwump schreef op zaterdag 15 september 2018 @ 21:01:
[...]
Ja ik weet ook wel hoe je fatsoenlijke deserialization zou kunnen bewerkstelligen, maar dit was een draak van een codebase waar minimaal vijftig man aan had gewerkt met veel duplication, accidental complexity en ga zo maar door.
Less alienation, more cooperation.
Idd, waar de junior probeert zijn code zo kort mogelijk op te schrijven, kiest de senior ervoor het juist zo leesbaar mogelijk te maken.SPee schreef op zaterdag 15 september 2018 @ 20:00:
Tja, er zijn veel ontwikkelaars die daar problemen mee hebben.
Een beetje de expert vs junior in het project.
Meestal spendeer je immers 3x zoveel tijd aan code lezen dan aan code typen. Als je daar bij het typen alvast rekening mee houdt, verdien je dat dus 3x terug.
wat een vies woord trouwens, "expert"... Alsof je ooit klaar bent met leren?
Ik heb zelf het afgelopen jaar bijna exclusief aan PHP/JS gewerkt en dan specifieker Node 6 waardoor je de meeste nieuwe ES2015+ features niet kan gebruiken. En iets als C# is ook al weer tijden geleden zelfs.
Maar om op wat andere discussies terug te komen: Ik gebruik zelf bij mijn ouders thuis een Logitech Illuminated geval (het oude, niet-draadloze model); lekker stil en lekker typen. Inmiddels thuis wel een mechanisch ding, de pricewatch: Razer BlackWidow Chroma V2 [Orange Switch] (Qwerty US). Heerlijk typen, geweldig.
Overigens, mag ik jullie vragen wat jullie de goede punten van zsh boven bash vinden? Ik kon zo snel eigenlijk alleen git-integratie vinden en wat andere kleine dingetjes, maar niets wereldschokkends eigenlijk. En bash is al hemels vergeleken bij windows cmd
2x Dell UP2716D | R9 7950X | 128GB RAM | 980 Pro 2TB x2 | RTX2070 Super
.oisyn: Windows is net zo slecht in commandline als Linux in GUI
Probeert de junior dat? In mijn ogen moet je het verschil junior - senior toch meer zoeken in de drie stadia die Robert C. Martin beschreef in Clean Architecture. Ken ze niet helemaal exact, maar grofweg waren het deze drie:mcDavid schreef op zaterdag 15 september 2018 @ 22:20:
[...]
Idd, waar de junior probeert zijn code zo kort mogelijk op te schrijven, kiest de senior ervoor het juist zo leesbaar mogelijk te maken.
Meestal spendeer je immers 3x zoveel tijd aan code lezen dan aan code typen. Als je daar bij het typen alvast rekening mee houdt, verdien je dat dus 3x terug.
wat een vies woord trouwens, "expert"... Alsof je ooit klaar bent met leren?
- Write code that works
- Write code that performs
- Write code that is understandable and maintainable
Leesbaarheid heeft ook heel erg te maken met naamgeving. Heb nog een leuk klusje liggen om een deelproject volledig te herschrijven nadat één van de meest incompetente developers met 15 jaar ervaring die ik ooit ben tegengekomen daar een enorm potje van heeft gemaakt. Zelden zoveel methode, class en package names gezien die totaal niet beschrijven wat er gedaan wordt.
"The question of whether a computer can think is no more interesting than the question of whether a submarine can swim" - Edsger Dijkstra
Mugwump schreef op zaterdag 15 september 2018 @ 22:51:
Heb nog een leuk klusje liggen om een deelproject volledig te herschrijven nadat één van de meest incompetente developers met 15 jaar ervaring die ik ooit ben tegengekomen daar een enorm potje van heeft gemaakt. Zelden zoveel methode, class en package names gezien die totaal niet beschrijven wat er gedaan wordt.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
| public abstract class Kees : IKees { public bar Hallo() { return HalloImpl(); } public Ibaz HeyHoi() { return new bazWrapperImpl(Hallo()); } protected abstract bar HalloImpl(); } |
Zoiets?
We are shaping the future
Jij leest code louter met je IDE ofzo? Je bekijkt nooit diffs, opent nooit eens een bestandje buiten het project, etc.?Alex) schreef op zaterdag 15 september 2018 @ 20:10:
Schrijf jij je code met Notepad ofzo? Een beetje IDE kan prima inferren wat voor type iets heeft en autosuggest je op dat moment de juiste dingen.
[ Voor 12% gewijzigd door .oisyn op 16-09-2018 02:48 ]
Give a man a game and he'll have fun for a day. Teach a man to make games and he'll never have fun again.
Als ik code lees interesseert het me niet wat het type van een variabele precies is. Dat maak ik wel op uit de context, of de naam van de variabele.
Als dat niet te doen is heb ik een refactorklusje te pakken.
We are shaping the future
Ik wil geenszins pleiten voor het niet gebruiken van type inference, maar je gaat hier een beetje te kort door de bocht imho met opmerkingen als "je IDE laat dat wel zien". Ik wil code ook uit context en zonder IDE kunnen lezen.
Give a man a game and he'll have fun for a day. Teach a man to make games and he'll never have fun again.
We are shaping the future
Dus wat doe je als je XML of JSON naar een class wilt mappen?
In mijn Kotlin voorbeeld gebruik ik nog vars voor de MailConfiguration class omdat deze wordt gevuld vanuit een XML bestand met een XmlMapper.
How to fix it?
Je hebt dan eigenlijk een mapper nodig die een soort constructor injection doet.
[ Voor 10% gewijzigd door Lethalis op 16-09-2018 08:48 ]
Ask yourself if you are happy and then you cease to be.
Als de check te lang is (ik neem aan someCondition in je voorbeeld), dan kun je toch een verklarende variabele introduceren?Alex) schreef op zaterdag 15 september 2018 @ 19:50:
[...]
Net als in C# dus.
Ik zweer overigens bij var, ik gebruik het overal waar het kan.
Behalve hierbij:
C#:
1 2 3 4 5 6 7 8 9 10 string something; if(someCondition) { something = GetValueForSomethingUnderNormalCircumstances(); } else { something = GetTheAlternativeValue(); }
Nou zou ik dit ook kunnen vervarren door die if/else te herschrijven naar een ternary operator, maar dat vind ik al snel onleesbaar worden. Dat doe ik alleen maar als de check kort is en de waarde constant is.
Ipsa Scientia Potestas Est
NNID: ShinNoNoir
Bijna, het zit echt vol met vage lagen met de naam 'handler', 'wrapper', 'service' en meer van dat soort zaken die eigenlijk niets anders doen dan pass-through, er is letterlijk een 'ReturnValue' object dat die hele keten wordt doorgeduwd en ga zo maar door. Veel methoden hebben dus ook zo ongeveer de signatureAlex) schreef op zondag 16 september 2018 @ 01:42:
[...]
C#:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 public abstract class Kees : IKees { public bar Hallo() { return HalloImpl(); } public Ibaz HeyHoi() { return new bazWrapperImpl(Hallo()); } protected abstract bar HalloImpl(); }
Zoiets?
1
| public ReturnValue DoSomething(string parameter) |
Voor het gemak is er één groot viewmodel gemaakt voor alles en één controller, views zitten vol met inline CSS en javascript en ga zo maar door.
Dit is echt het op één na slechtste stukje code dat ik ooit onder ogen heb gehad, maar de slechtste was dan ook een "applicatie" die bestond uit 6000 regels procedurele code met echt letterlijk myVariable1 t/m myVariable627.
Je hebt niet 'eigen een mapper nodig die een soort constructor injection doet', je hebt een mapper nodig die constructor injection doet.Lethalis schreef op zondag 16 september 2018 @ 07:56:
Om het nog even over functional programming te hebben en immutability... Hoe lossen jullie het mapping probleem op?
Dus wat doe je als je XML of JSON naar een class wilt mappen?
In mijn Kotlin voorbeeld gebruik ik nog vars voor de MailConfiguration class omdat deze wordt gevuld vanuit een XML bestand met een XmlMapper.
How to fix it?
Je hebt dan eigenlijk een mapper nodig die een soort constructor injection doet.
Newtonsoft in C# probeert bijvoorbeeld automatisch de beschikbare constructor te gebruiken als er geen no-args constructor is.
[ Voor 23% gewijzigd door Mugwump op 16-09-2018 10:10 ]
"The question of whether a computer can think is no more interesting than the question of whether a submarine can swim" - Edsger Dijkstra
Less alienation, more cooperation.
Dat klinkt dan weer erg als "vals spelen". Het hele idee is dat de class immutable is.Sandor_Clegane schreef op zondag 16 september 2018 @ 10:37:
Of je moet iets hebben als [<CLIMutable>] in Kotlin.
De "Oh dit is lastig, ach met een grote hamer en beitel lukt het ook" aanpak.
Ask yourself if you are happy and then you cease to be.
Newtonsoft heeft het niet nodig, maar het bestaat wel. En CLI mutable betekend mutable voor de CLR, niet voor je programma.Lethalis schreef op zondag 16 september 2018 @ 10:54:
[...]
Dat klinkt dan weer erg als "vals spelen". Het hele idee is dat de class immutable is.
De "Oh dit is lastig, ach met een grote hamer en beitel lukt het ook" aanpak.
Less alienation, more cooperation.
Betekent het niet "mutable voor alle .Net libraries waar ik deze class aan geef" ?Sandor_Clegane schreef op zondag 16 september 2018 @ 11:06:
[...]
Newtonsoft heeft het niet nodig, maar het bestaat wel. En CLI mutable betekend mutable voor de CLR, niet voor je programma.
Dus dat het alleen voor F# code immutable is?
Het grote voordeel van immutability is juist dat je zeker weet dat je nooit onverwachte side effects krijgt.
Ask yourself if you are happy and then you cease to be.
Volgens mij betekend het alleen maar dat er een default constructor wordt aangemaakt en heeft het verder niet te maken met immutabillity voor andere talen. En deze constructor kan alleen maar aangeroepen worden intern in de CLR, een laag dieper zeg maar.Lethalis schreef op zondag 16 september 2018 @ 11:15:
[...]
Betekent het niet "mutable voor alle .Net libraries waar ik deze class aan geef" ?
Dus dat het alleen voor F# code immutable is?
Het grote voordeel van immutability is juist dat je zeker weet dat je nooit onverwachte side effects krijgt.
Less alienation, more cooperation.
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!
Gevalletje cybersecurityhackhoaxmevrouw?
"The question of whether a computer can think is no more interesting than the question of whether a submarine can swim" - Edsger Dijkstra
Tsja, ik wou dit gaan testen...Sandor_Clegane schreef op zondag 16 september 2018 @ 12:07:
[...]
Volgens mij betekend het alleen maar dat er een default constructor wordt aangemaakt en heeft het verder niet te maken met immutabillity voor andere talen. En deze constructor kan alleen maar aangeroepen worden intern in de CLR, een laag dieper zeg maar.
Dus ik maak eerst een .NET Core library aan met "dotnet new lib" en dat gaat prima.
Vervolgens wil ik een F# project aanmaken met "dotnet new console -lang f#" en dan krijg ik NuGet errors.
1
2
3
4
| [marc@nemo TestApp]$ dotnet restore Restoring packages for /home/marc/Projects/wonky/TestApp/TestApp.fsproj... /usr/share/dotnet/sdk/2.1.4/NuGet.targets(103,5): error : Unable to load the service index for source https://api.nuget.org/v3/index.json. [/home/marc/Projects/wonky/TestApp/TestApp.fsproj] /usr/share/dotnet/sdk/2.1.4/NuGet.targets(103,5): error : Response status code does not indicate success: 504 (Gateway Timeout). [/home/marc/Projects/wonky/TestApp/TestApp.fsproj] |
Hetzelfde als ik inlog op mijn werk en met Visual Studio een F# project maak... werkt niet (allemaal mooie uitroeptekens bij de Dependencies en SDK etc).
Gaat weer lekker... goed begin. En ik weet zeker dat het op mijn werk PC heeft gewerkt, want daar heb ik een aantal maanden geleden nog met F# gespeeld.
Bij een 504 (Gateway Timeout) denk ik aan een probleem bij Microsoft... maar het stomme is dat ik wel C# projecten kan restoren van NuGet.
[update]
Anyhoo... het is mij gelukt met een bestaand F# project (waar geen restore nodig is):
De C# library:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
| using System; using System.Reflection; namespace TestSideEffects { public class WonkyStuff { public void PrintObjectEx(Object item) { Type t = item.GetType(); PropertyInfo[] props = t.GetProperties(); foreach (var prop in props) { if (prop.PropertyType == typeof(string)) { string value = (string)prop.GetValue(item); prop.SetValue(item, value.ToUpper()); } } } } } |
De F# code:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
| open System open TestSideEffects [<CLIMutable>] type Car = { Brand : string; Model : string } [<EntryPoint>] let main argv = let car = { Brand = "Toyota"; Model = "Auris" } let ws = new WonkyStuff() ws.PrintObjectEx car Console.WriteLine car.Brand |
Dit geeft dus "TOYOTA" en dat noemen we een major side effect
[ Voor 34% gewijzigd door Lethalis op 16-09-2018 15:16 ]
Ask yourself if you are happy and then you cease to be.
Wiens naam niet genoemd mag worden omdat er anders nog steeds types zijn zonder adblocker, die vervolgens nog weken tegen
Even de toon van je post daargelaten, ik heb de spec eens gelezen en blijkbaar zijn er dan ook default setters en getters, deze worden in F# verborgen maar zijn voor andere talen wel beschikbaar. Dat wist ik niet.
Aan de ene kant is dat jammer, aan de andere kant zijn er serialisers die niet CLIMutable hoeven te hebben. Komt bij dat als het zo'n issue is je je API zo kunt maken dat de CLIMutable types eerst gewrapped worden voordat ze F# verlaten.
Aan de andere kant, het probleem is dat een taal waarin alles mutable is ook records van F# mutable kunnen zijn als ze een bepaald attribuut meekrijgen. Tja, het is wat het is zeg maar.
Ik zie het issue niet zo als je er verantwoordelijk mee om gaat, en sideeffects heb je bijna altijd als je je programma iets nuttigs wilt laten doen. IO en het updaten van een DB zijn ook sideeffects.
Less alienation, more cooperation.
Mja ik raak nogal gefrustreerd als dingen niet werkenSandor_Clegane schreef op zondag 16 september 2018 @ 19:17:
[...]
Even de toon van je post daargelaten, ik heb de spec eens gelezen en blijkbaar zijn er dan ook default setters en getters, deze worden in F# verborgen maar zijn voor andere talen wel beschikbaar. Dat wist ik niet.
Werkt "dotnet new console -lang f#" momenteel wel bij jou overigens?
Maar goed, dat je niet zonder side effects kunt begrijp ik. Wat echter wel belangrijk is dat jij als programmeur bepaalt wanneer deze optreden. Met CLIMutable kun je daar niet meer van op aan.
Ask yourself if you are happy and then you cease to be.
Lijkt allemaal te werken:
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
27
28
29
30
31
32
33
| user@hephaestus:~/development/projects/marc$ dotnet new console -lang F# The template "Console Application" was created successfully. Processing post-creation actions... Running 'dotnet restore' on /home/user/development/projects/marc/marc.fsproj... Restoring packages for /home/user/development/projects/marc/marc.fsproj... Generating MSBuild file /home/user/development/projects/marc/obj/marc.fsproj.nuget.g.props. Generating MSBuild file /home/user/development/projects/marc/obj/marc.fsproj.nuget.g.targets. Restore completed in 165.14 ms for /home/user/development/projects/marc/marc.fsproj. Restore succeeded. Info: user@hephaestus:~/development/projects/marc$ dotnet --info .NET Command Line Tools (2.1.201) Product Information: Version: 2.1.201 Commit SHA-1 hash: 7932dc6179 Runtime Environment: OS Name: ubuntu OS Version: 18.04 OS Platform: Linux RID: ubuntu.18.04-x64 Base Path: /usr/share/dotnet/sdk/2.1.201/ Microsoft .NET Core Shared Framework Host Version : 2.0.7 Build : 2d61d0b043915bc948ebf98836fefe9ba942be11 |
Tja, als je met Reflection in de weer bent dan is er van alles mogelijk, maak je API oppervlak dan zo dat er alleen "echte" F# objecten de lijn over gaan. Of gebruik gewoon F#.
[ Voor 20% gewijzigd door Sandor_Clegane op 16-09-2018 19:39 ]
Less alienation, more cooperation.
Yep, bij mij nu ook.Sandor_Clegane schreef op zondag 16 september 2018 @ 19:37:
Lijkt allemaal te werken...
Apart dat het alleen F# betrof. Blijkbaar staan die packages echt op een andere server.
Ask yourself if you are happy and then you cease to be.
Cool, mag je nu iets voor mij doen.Lethalis schreef op zondag 16 september 2018 @ 20:00:
[...]
Yep, bij mij nu ook.
Apart dat het alleen F# betrof. Blijkbaar staan die packages echt op een andere server.
Welke versies van .Net core kun je installeren? Het lijkt erop dat mijn Ubuntu de nieuwe versies niet laat zien. Wil ik nu net 2.1.300 hebben maar die is er alleen in preview terwijl op de site van MS ze het al over 2.1.400 hebben.
Man die versies zijn echt een draak met DotNet core.
1
2
3
4
5
6
7
| user@hephaestus:~/development/projects/server$ sudo apt install dotnet- dotnet-host dotnet-hostfxr-2.1.0-rc1 dotnet-runtime-2.1 dotnet-sdk-2.1.200 dotnet-hostfxr-1.1.9 dotnet-hosting-2.0.7 dotnet-runtime-2.1.0-preview2-26406-04 dotnet-sdk-2.1.201 dotnet-hostfxr-2.0.7 dotnet-hosting-2.0.8 dotnet-runtime-2.1.0-rc1 dotnet-sdk-2.1.202 dotnet-hostfxr-2.0.9 dotnet-hosting-2.0.9 dotnet-runtime-deps-2.1 dotnet-sdk-2.1.300-preview2-008533 dotnet-hostfxr-2.1 dotnet-runtime-2.0.7 dotnet-sdk-2.1 dotnet-sdk-2.1.300-rc1-008673 dotnet-hostfxr-2.1.0-preview2-26406-04 dotnet-runtime-2.0.9 dotnet-sdk-2.1.105 dotnet-sharedframework-microsoft.netcore.app-1.1.9 |
Of ik zie iets over het hoofd.
Edit: Blijkbaar als je dotnet.sdk.2.1 installeert pakt hij de laatste versie........ Wat nu dus 2.1.402 is....... Duidelijk......
[ Voor 3% gewijzigd door Sandor_Clegane op 16-09-2018 20:34 ]
Less alienation, more cooperation.
🠕 This side up
Zit op zich wel wat in ja. Zou er misschien nog een stadium bijvoegen voor code die getest (of iig testbaar) en redelijkerwijs bug/exploit vrij is. Als in, iig de basics zoals SQL injection moet toch wel gecoverd zijn, dat gaat nog iets verder dan "code that works" (en gaat nog verrot vaak fout als ik de mensen die bij ons sollicitaties afhandelen mag geloven).Mugwump schreef op zaterdag 15 september 2018 @ 22:51:
[...]
Probeert de junior dat? In mijn ogen moet je het verschil junior - senior toch meer zoeken in de drie stadia die Robert C. Martin beschreef in Clean Architecture. Ken ze niet helemaal exact, maar grofweg waren het deze drie:Als je dan kijkt naar het verschil junior - senior, dan is een junior doorgaans al dolblij als hij in het eerste slaagt, terwijl dat voor de senior vaak pas het begin is. Ik merk dat ook in mijn eigen werkwijze. Ik prototype even snel iets dat werkt en ben vervolgens nog drie keer zo veel tijd kwijt om te zorgen dat criteria twee en drie ook vervuld worden.
- Write code that works
- Write code that performs
- Write code that is understandable and maintainable
Leesbaarheid heeft ook heel erg te maken met naamgeving. Heb nog een leuk klusje liggen om een deelproject volledig te herschrijven nadat één van de meest incompetente developers met 15 jaar ervaring die ik ooit ben tegengekomen daar een enorm potje van heeft gemaakt. Zelden zoveel methode, class en package names gezien die totaal niet beschrijven wat er gedaan wordt.
Daarnaast vallen de eerste twee stadia naar mijn mening meer in het hobbysegment, van iemand die professioneel software ontwikkelt, verwacht je toch dat dàt op zijn minst wel goed zit. Ook als het een junior betreft.
Ik zie een senior meer als iemand die het inzicht heeft om architecturele beslissingen te maken, die goed te kunnen onderbouwen en anderen daarin kan coachen.
Iemand die dus zelfstandig werkt en daardoor ook anderen kan aansturen en begeleiden.
En dat hoeft dus niet eens te betekenen dat je in technisch opzicht geweldig bent...
Maar bij ons op de zaak is dat uiteindelijk wel hoe je doorgroeit.
Ik ben vooral techneut, maar als ik echt "senior" wil worden dan moet ik alle ins en outs van de bedrijfsprocessen van onze klanten kennen en dus volop met ze mee kunnen denken.
In mijn geval betekent dat bijvoorbeeld ook dat ik financiële kennis moet hebben. Dingen zoals "hoe voeren klanten in onze branche meestal hun boekhouding? En welke uitdagingen komen ze daarbij tegen?"
Hetzelfde geldt voor logistieke processen en voorraadadministratie. Ga zo maar door.
Kun je die dingen niet zelf, dan moet er altijd iemand tussen zitten die dan dus eigenlijk de "senior" is.
Ik denk er daarom soms dus serieus aan om een opleiding Bedrijfsadministratie of Bedrijfskunde te volgen. En eventueel een tijdje bij onze klanten mee te lopen...
Ask yourself if you are happy and then you cease to be.
Probleem is vaak dat we in nederland techneuten wat minder hoog aanslaan. Je hebt bijvoorbeeld geen Senior Technical Fellow ofzo.
Less alienation, more cooperation.
Exact expert nodig?
Ik denk eerder dat het dan gewoon verschillende banen/functies zijn, maar (strict genomen fout) dezelfde naam hebben.Crazy D schreef op maandag 17 september 2018 @ 08:30:
Ik denk dat het afhangt van je business. Senior zal bij het ene bedrijf zijn dat je technisch "de beste" bent, en ook anderen kunt aansturen. Bij andere bedrijven zal dat inhouden dat je vooral ook kennis van wat je klanten doen moet hebben.
Het probleem in jouw situatie is dat je een programmeur bent, maar de taken van een consultant en architect doet. In jouw geval wordt je dan dus ook geen "Senior Software Engineer", maar een "Senior Consultant", oid. En dan moet je inderdaad andere dingen goed kunnen.Lethalis schreef op maandag 17 september 2018 @ 07:18:
Wat ik in jullie "senior" verhaal mis, is branchespecifieke vakkennis en de vaardigheid om zelfstandig met de klant problemen op te lossen.
Iemand die dus zelfstandig werkt en daardoor ook anderen kan aansturen en begeleiden.
En dat hoeft dus niet eens te betekenen dat je in technisch opzicht geweldig bent...
Maar bij ons op de zaak is dat uiteindelijk wel hoe je doorgroeit.
Ik ben vooral techneut, maar als ik echt "senior" wil worden dan moet ik alle ins en outs van de bedrijfsprocessen van onze klanten kennen en dus volop met ze mee kunnen denken.
In mijn geval betekent dat bijvoorbeeld ook dat ik financiële kennis moet hebben. Dingen zoals "hoe voeren klanten in onze branche meestal hun boekhouding? En welke uitdagingen komen ze daarbij tegen?"
Hetzelfde geldt voor logistieke processen en voorraadadministratie. Ga zo maar door.
Kun je die dingen niet zelf, dan moet er altijd iemand tussen zitten die dan dus eigenlijk de "senior" is.
Ik denk er daarom soms dus serieus aan om een opleiding Bedrijfsadministratie of Bedrijfskunde te volgen. En eventueel een tijdje bij onze klanten mee te lopen...
[ Voor 61% gewijzigd door ThomasG op 17-09-2018 09:38 ]
En bij sommige bedrijven doen ze de titel alleen op leeftijd, en niet om kennis/ervaringCrazy D schreef op maandag 17 september 2018 @ 08:30:
Ik denk dat het afhangt van je business. Senior zal bij het ene bedrijf zijn dat je technisch "de beste" bent, en ook anderen kunt aansturen. Bij andere bedrijven zal dat inhouden dat je vooral ook kennis van wat je klanten doen moet hebben.

De reden waarom ik niet luister naar zo'n titel: ik ben gewoon een Software Engineer; geen Senior/Medior/Junior.
Nice. Dit:
1
2
3
4
5
6
7
8
| BufferedReader(InputStreamReader(process.inputStream)).use { reader -> var line = reader.readLine() while (line != null) { sb.append(line) sb.append(System.getProperty("line.separator")) line = reader.readLine() } } |
Kun je volgens mij ook schrijven als:
1
| val text = process.inputStream.bufferedReader().readText() |
Kotlin heeft ook constants hoor:Lethalis schreef op zaterdag 15 september 2018 @ 14:31:
Ja natuurlijk, dat zijn de "val". Het punt met de MailConfiguration class is dat deze met een XML mapper (voor Java) gevuld wordt. Om die reden zijn de properties in dit geval niet read only.
1
| const val BASE_URL = "http://localhost:8080/" |
[ Voor 31% gewijzigd door Hydra op 17-09-2018 11:03 ]
https://niels.nu
[ Voor 3% gewijzigd door TheNephilim op 17-09-2018 12:09 ]
SPQ Standard Package/Packing/Pack QuantityTheNephilim schreef op maandag 17 september 2018 @ 11:52:
Wat is de *Engelse* definitie van het aantal items in een verpakking? Bijv. hoeveel kratten er op een pallet gaan, of hoeveel pakken laminaat erin een doos (oid.) gaan?
[ Voor 6% gewijzigd door Harrie_ op 17-09-2018 12:22 ]
Hoeder van het Noord-Meierijse dialect
Welke library gebruik jij eigenlijk voor het mappen van XML naar een Kotlin data class die immutable is?
Of gebruik je voor het mappen gewone classes met vars?
Ask yourself if you are happy and then you cease to be.
Performance is wel een pittig onderwerp in een beetje complex systeem hoor. Ik zou niet van elke junior verwachten dat ze alle nuances op dat vlak onder de knie hebben. Naast fundamentele zaken als het feit dat 50 synchrone calls naar externe systemen serieel uitvoeren waarschijnlijk niet de meest optimale methode is, zijn er ook heel veel zaken die je toch veelal proefondervindelijk (lees: door load / performance testen) zult moeten toetsen.mcDavid schreef op zondag 16 september 2018 @ 22:31:
[...]
Zit op zich wel wat in ja. Zou er misschien nog een stadium bijvoegen voor code die getest (of iig testbaar) en redelijkerwijs bug/exploit vrij is. Als in, iig de basics zoals SQL injection moet toch wel gecoverd zijn, dat gaat nog iets verder dan "code that works" (en gaat nog verrot vaak fout als ik de mensen die bij ons sollicitaties afhandelen mag geloven).
Daarnaast vallen de eerste twee stadia naar mijn mening meer in het hobbysegment, van iemand die professioneel software ontwikkelt, verwacht je toch dat dàt op zijn minst wel goed zit. Ook als het een junior betreft.
Ik zie 'architecturele beslissingen maken' dan ook niet als een apart onderdeel van het proces. Software developers en software architects of solution architects als gescheiden rollen zien is in mijn ogen nooit wenselijk.Ik zie een senior meer als iemand die het inzicht heeft om architecturele beslissingen te maken, die goed te kunnen onderbouwen en anderen daarin kan coachen.
Juist ook het onderhoudbaar en beheersbaar houden van code is ook grotendeels een architectureel vraagstuk. Geleidelijke uitbreiding leidt vaak toch tot herziening van concepten en structuren om het geheel overzichtelijk en werkbaar te houden.
Onlangs nog met een 'software architect' van een dozenschuiver gewerkt. Die man schreef echt de slechtste code die ik ooit gezien had, maar erger nog was dat hij nooit kon verklaren waarom hij bepaalde 'ontwerpkeuzes' had gemaakt.
"The question of whether a computer can think is no more interesting than the question of whether a submarine can swim" - Edsger Dijkstra
Werkt Jackson niet? Ik heb het zelf nog niet voor XML gebruikt maar Jackson Databind werkt prima met zowel JSON als YAML. Wel de Kotlin plugin erin hangen zodat 'ie met data classes om kan gaan.Lethalis schreef op maandag 17 september 2018 @ 13:20:
Welke library gebruik jij eigenlijk voor het mappen van XML naar een Kotlin data class die immutable is?
Of gebruik je voor het mappen gewone classes met vars?
Dat is een van de grootste problemen van ons vak. Mensen die vooral senior zijn in jaren maar niet in skills die ook geen management skills hebben en dan maar 'architect' gemaakt worden. En dat heeft dan de technische 'leiding' over de architectuur.Mugwump schreef op maandag 17 september 2018 @ 13:24:
Onlangs nog met een 'software architect' van een dozenschuiver gewerkt. Die man schreef echt de slechtste code die ik ooit gezien had, maar erger nog was dat hij nooit kon verklaren waarom hij bepaalde 'ontwerpkeuzes' had gemaakt.
Vooral bij de overheid zie je dat veel. En je dan maar afvragen waarom zoveel van die projecten mislukken.
[ Voor 42% gewijzigd door Hydra op 17-09-2018 13:55 ]
https://niels.nu
De Kotlin plugin is inderdaad wat ik misteHydra schreef op maandag 17 september 2018 @ 13:53:
[...]
Werkt Jackson niet? Ik heb het zelf nog niet voor XML gebruikt maar Jackson Databind werkt prima met zowel JSON als YAML. Wel de Kotlin plugin erin hangen zodat 'ie met data classes om kan gaan.
1
2
3
4
5
6
7
8
9
10
11
12
13
| data class MailConfiguration ( val server: String, val port: Int, val useSSL: Boolean, val useCredentials: Boolean, val username: String?, val password: String? ) val xmlMapper = XmlMapper() xmlMapper.registerModule(KotlinModule()) val result = xmlMapper.readValue<MailConfiguration>(configPath.toFile()) |
Dit werkt
[ Voor 3% gewijzigd door Lethalis op 17-09-2018 14:39 ]
Ask yourself if you are happy and then you cease to be.
https://arstechnica.com/g...ime-off-to-learn-empathy/
"The question of whether a computer can think is no more interesting than the question of whether a submarine can swim" - Edsger Dijkstra
En er is een CoC, ben benieuwd.Mugwump schreef op dinsdag 18 september 2018 @ 21:46:
Linus Torvalds gaat een cursus empathie volgen en betuigt spijt voor zijn woede-uitbarstingen tegenover andere developers:
https://arstechnica.com/g...ime-off-to-learn-empathy/
(was er wel een van conflict, maar nu dus een van conduct)
[ Voor 8% gewijzigd door gekkie op 18-09-2018 21:58 ]
Wazig verhaal... Vraag me af wat hier aan vooraf is gegaan.Mugwump schreef op dinsdag 18 september 2018 @ 21:46:
Linus Torvalds gaat een cursus empathie volgen en betuigt spijt voor zijn woede-uitbarstingen tegenover andere developers:
https://arstechnica.com/g...ime-off-to-learn-empathy/
Ask yourself if you are happy and then you cease to be.
Vandaag ben ik begonnen met het leren van scripting. Ik heb nog niet zo heel erg veel ervaring, en wil ook niet, na zelf al rondgekeken te hebben op Google en diverse fora, voor ieder wissewasje een topic openen en daarom kwam ik met het idee dat het wellicht leuk is om een topic te openen voor kleine vraagjes, waar newbies zoals ik korte vraagjes kunnen stellen. Zie het als het 'kleine opleidingscentrum'.
Als iemand ervaring heeft met vbScript en mij een heel klein dingetje kan uitleggen via DM, graag!
Uiteraard heb ik al op Google gekeken, maar daar kom ik alleen maar voorbeelden tegen die voor mij niet revelant zijn. Juist voor dit soort kleine vraagjes zou zo'n topic handig zijn.
[ Voor 3% gewijzigd door D3F op 18-09-2018 23:44 ]
Gewoon een nieuw topic openen met daarin jouw stukje code. En daarbij aangeven wat er niet werkt en wat je geprobeerd had om het werkend te krijgen en niet is gelukt.D3F schreef op dinsdag 18 september 2018 @ 23:44:
Als iemand ervaring heeft met vbScript en mij een heel klein dingetje kan uitleggen via DM, graag!
Uiteraard heb ik al op Google gekeken, maar daar kom ik alleen maar voorbeelden tegen die voor mij niet revelant zijn. Juist voor dit soort kleine vraagjes zou zo'n topic handig zijn.
Speel ook Balls Connect en Repeat
Misschien zit ik er volledig naast maar is empathie bij uitstek niet iets wat je niet kunt leren maar gewoon moet hebben?Linus Torvalds apologizes for years of being a jerk, takes time off to learn empathy
Hoeder van het Noord-Meierijse dialect
Redelijk wel, maar je kan wel leren hoe je hoort te reageren op bepaalde situaties.Harrie_ schreef op woensdag 19 september 2018 @ 09:36:
M.b.t. Linus Torvalds:
[...]
Misschien zit ik er volledig naast maar is empathie bij uitstek niet iets wat je niet kunt leren maar gewoon moet hebben?
Ok maar dan leer je dus eigenlijk empathie fakenhackerhater schreef op woensdag 19 september 2018 @ 09:54:
[...]
Redelijk wel, maar je kan wel leren hoe je hoort te reageren op bepaalde situaties.
Collega: "mijn vrouw ligt op sterven"
Linus: *boeiend!*
Linus: *herinner cursus*
Linus: "oeh wat erg, ik heb er begrip voor als je werk nu niet 100% is"
Hoeder van het Noord-Meierijse dialect
Nee tuurlijk niet. Empathie is niet anders dan ruimtelijk inzicht of muzikaliteit. Ja je kunt er een talent voor hebben of niet, maar met voldoende oefening kan iedereen zich op zijn minst een basisniveau eigen maken.Harrie_ schreef op woensdag 19 september 2018 @ 09:36:
M.b.t. Linus Torvalds:
[...]
Misschien zit ik er volledig naast maar is empathie bij uitstek niet iets wat je niet kunt leren maar gewoon moet hebben?
...en wat is daar het probleem mee, als het eindresultaat het zelfde is?Harrie_ schreef op woensdag 19 september 2018 @ 09:57:
[...]
Ok maar dan leer je dus eigenlijk empathie faken![]()
Collega: "mijn vrouw ligt op sterven"
Linus: *boeiend!*
Linus: *herinner cursus*
Linus: "oeh wat erg, ik heb er begrip voor als je werk nu niet 100% is"
[ Voor 30% gewijzigd door mcDavid op 19-09-2018 09:59 ]
Klopt, maar de andere partij merkt het niet echt of het natuurlijk is of een aangeleerd truukje.Harrie_ schreef op woensdag 19 september 2018 @ 09:57:
[...]
Ok maar dan leer je dus eigenlijk empathie faken![]()
Collega: "mijn vrouw ligt op sterven"
Linus: *boeiend!*
Linus: *herinner cursus*
Linus: "oeh wat erg, ik heb er begrip voor als je werk nu niet 100% is"
En het scheelt flink in hoe je gezien wordt.
Het is niet iets waar je gewoon een cursus en een examen voor doet om een certificaatje in ontvangst te nemen als je dat bedoelt.Harrie_ schreef op woensdag 19 september 2018 @ 09:36:
M.b.t. Linus Torvalds:
[...]
Misschien zit ik er volledig naast maar is empathie bij uitstek niet iets wat je niet kunt leren maar gewoon moet hebben?
Maar er zijn wel allerhande technieken die mensen bewuster maken van het effect van hun handelen op andere mensen. Dan krijg je dan zo'n acteur voor je die jouw gedrag gaat spiegelen zodat je je hopelijk enigszins bewust wordt van de impact van jouw gedrag op anderen.
Digitale communicatie heeft ook vaak een beperkend effect op empathie omdat juist alle emotie die je bij fysiek contact wel hebt achterwege blijft. Het mensenlijk brein is niet echt ingesteld om zinnen in hoofdletters hetzelfde te interpreteren als iemand die daadwerkelijk tegen je staat te schreeuwen bijvoorbeeld.
"The question of whether a computer can think is no more interesting than the question of whether a submarine can swim" - Edsger Dijkstra
Meneer Torvalds hoeft helemaal geen empathie te faken. Het zou al enorm schelen als hij zich simpelweg zakelijk opstelt en mensen niet op de man aanvalt.Harrie_ schreef op woensdag 19 september 2018 @ 09:57:
[...]
Ok maar dan leer je dus eigenlijk empathie faken![]()
Collega: "mijn vrouw ligt op sterven"
Linus: *boeiend!*
Linus: *herinner cursus*
Linus: "oeh wat erg, ik heb er begrip voor als je werk nu niet 100% is"
Dus in plaats van te zeggen dat iemand zijn ouders beter een abortus hadden kunnen plegen, gewoon melden dat je die kernel patch niet accepteert, omdat hij bijvoorbeeld teveel syscalls teweeg brengt.
En klaar. Niet natrappen.
Dat is alles...
Ask yourself if you are happy and then you cease to be.
Dat is alles ...
Look, runners deal in discomfort. After you get past a certain point, that’s all there really is. There is no finesse here.
Dus jij vindt dat het niet mogelijk is om mensen aan te leren zakelijk te reageren? Of richting programmeren: een nette programmeerstijl aan te houden? Het is slechts een kwestie van leren herkennen wat er niet in orde is, en leren hoe dat af te vangen is.kenneth schreef op woensdag 19 september 2018 @ 10:59:
Natuurlijk. En verkoudheid is op te lossen door simpelweg te stoppen met hoesten, niezen en te veel slijm produceren.
Dat is alles ...
De vergelijking met een verkoudheid raakt echt kant noch wal.
Het is ook geschreven communicatie, dus in principe kun je gewoon even nadenken voordat je op versturen drukt.Lethalis schreef op woensdag 19 september 2018 @ 10:55:
[...]
Meneer Torvalds hoeft helemaal geen empathie te faken. Het zou al enorm schelen als hij zich simpelweg zakelijk opstelt en mensen niet op de man aanvalt.
Dus in plaats van te zeggen dat iemand zijn ouders beter een abortus hadden kunnen plegen, gewoon melden dat je die kernel patch niet accepteert, omdat hij bijvoorbeeld teveel syscalls teweeg brengt.
En klaar. Niet natrappen.
Dat is alles...
Mijn handen hebben ook vaak genoeg gejeukt om iemand bij een klant eens even goed de waarheid te zeggen. Genoeg incompetente mensen bij klanten waarbij je als externe of leverancier alle gaten voor dicht loopt, maar die opeens op hoge poten verhaal komen halen als je één keer een klein foutje maakt.
"The question of whether a computer can think is no more interesting than the question of whether a submarine can swim" - Edsger Dijkstra
Ik denk zeker dat het te leren is. Het is het bagatelliseren waar ik een probleem mee heb. "Simpelweg", "en klaar", "dat is alles".dcm360 schreef op woensdag 19 september 2018 @ 11:37:
[...]
Dus jij vindt dat het niet mogelijk is om mensen aan te leren zakelijk te reageren? Of richting programmeren: een nette programmeerstijl aan te houden? Het is slechts een kwestie van leren herkennen wat er niet in orde is, en leren hoe dat af te vangen is.
De vergelijking met een verkoudheid raakt echt kant noch wal.
Het is een serieus probleem, vergt veel moed om te erkennen, veel inspanning om op te lossen. Het is alleen simpel voor mensen voor wie het überhaupt geen (groot) probleem is.
Look, runners deal in discomfort. After you get past a certain point, that’s all there really is. There is no finesse here.
DAAR BEN IK HET DUS NIET MEE EENS!Mugwump schreef op woensdag 19 september 2018 @ 10:11:
Het mensenlijk brein is niet echt ingesteld om zinnen in hoofdletters hetzelfde te interpreteren als iemand die daadwerkelijk tegen je staat te schreeuwen bijvoorbeeld.
Het heeft weinig effect om mensen gewoon een trucje te leren, ze moeten inzien waarom ze dat moeten doen.dcm360 schreef op woensdag 19 september 2018 @ 11:37:
[...]
Dus jij vindt dat het niet mogelijk is om mensen aan te leren zakelijk te reageren? Of richting programmeren: een nette programmeerstijl aan te houden? Het is slechts een kwestie van leren herkennen wat er niet in orde is, en leren hoe dat af te vangen is.
[ Voor 42% gewijzigd door .oisyn op 19-09-2018 12:02 ]
Give a man a game and he'll have fun for a day. Teach a man to make games and he'll never have fun again.
Het inzicht waarom het moet lijkt er al wel te zijn door deze stap al te nemen. Afgezien daarvan heb ik denk ik minder problemen met iemand die zonder inzicht fatsoenlijk communiceert dan iemand die zonder inzicht nog steeds als een randdebiel overkomt. Het inzicht kan alsnog komen over een wat langere periode (er zit namelijk een beloning aan fatsoenlijke communicatie: het lokt fatsoenlijke communicatie terug uit), en ook als dat niet het geval is scheelt het op zijn minst nog steeds voor de buitenwereld..oisyn schreef op woensdag 19 september 2018 @ 12:00:
[...]
Het heeft weinig effect om mensen gewoon een trucje te leren, ze moeten inzien waarom ze dat moeten doen.
Give a man a game and he'll have fun for a day. Teach a man to make games and he'll never have fun again.
Dit topic is gesloten.
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.