Java er faktisk helt okay...

En af de centrale påstande i Paul Grahams Beating the Averages er, at man ikke kan tage stilling til hvorvidt et programmeringssprog er godt eller ej før man har styr på Lisp (*). Det har jeg ikke helt (endnu), men jeg vil alligevel vove pelsen med en ikke ret trendy udmelding og afsløre mig som den ret traditionelt indstillede udvikler jeg er: jeg kan godt lide Java.

Det vil sige - jeg kan godt lide teknologien. Hvad jeg mener om ejeren og dennes gøren og laden vil jeg lade stå usagt hen.

Java passer godt i mit kram, fordi det er godt til at konstruere store, serverbaserede systemer, som skal integrere data fra mange forskellige kilder, og som skal videreudvikles og vedligeholdes over lang tid. Jeg har en idé om, at der nok skal være nogen, som ikke helt deler min entusiasme, så ud over de nedenstående mere konkrete eksempler på gode ting i Java kommer der et opfølgende indlæg med mit bud på ting, som er mindre smarte. Funktionsprogrammeringsslænget og dem, som er til dynamisk typing, kan godt varme op med spydighederne :-)

Anyway. Det, som gør, at Java fungerer for mig, er i tilfældig rækkefølge om ting som

  • Langtidsholdbarhed. Sproget og runtimeplatformen videreudvikles, men på bagudkompatibel vis. Jeg sidder til daglig med kode, som snart er 20 år gammel, og som stadig fungerer fint. Okay, der er sjældne undtagelser - jeg er fx stødt på et problem med et ORM-framework fra anno dazumal, som modificerer klassefiler, og som af gode grunde ikke kender til de ændringer i formatet, som kom med Java 7 - men bortset fra eksotika som det kører de gamle ting stadig.

  • God runtimeperformance. Det er sjældent, at det er sproget som sådan, som er den begrænsende faktor hvad runtimeperformance angår. Man kan selvfølgelig finde eksempler på kode, hvor den semantisk ækvivalente udgave i C kører hurtigere eller bruger mindre ram, men det betyder ikke noget i dagligdagen. Og performance bliver stadig bedre, også selv om man ikke genoversætter sin kode - kode oversat for 20 år siden kører også hurtigere på en moderne JVM end det gjorde dengang.

  • Rigt økosystem. Der findes komponenter af høj kvalitet til snart sagt alle formål, og de er let tilgængelige. Udviklingsværktøjerne er fremragende. Skulle man have lyst til at vove sig ud i eksperimenter med andre programmeringssprog findes der adskillige, som kører på JVM'en, og som kan integrere med ens eksisterende kode.

  • Sproglig stringens. Uanset hvad man sætter op af guidelines, krav og regler kan udviklere være meget kreative, så selv om det måske kan lyde lidt småfascistisk er det godt, at sproget er begrænset i sine muligheder for at obfuskere. Java har fx ingen (brugerdefineret) operator-overload, så man kan i rimelig grad regne med, at operatorerne betyder, hvad de altid har gjort. Ting som statisk typing med typeannoteringer, en veldefineret pakkestruktur, en klasse pr. fil og veletablerede konventioner for anvendelse af store/små bogstaver i identifiers gør også, at graden af discoverability (hvad hedder det egentlig på dansk? opdagbarhed?) er høj - det er rimeligt let at finde ud af, hvor og hvordan ting er defineret.

  • Passende abstraktionsniveau. Java har en god balance mellem høj- og lavniveau. Det har fx automatisk hukommelsesstyring med garbage collection, så man slipper for at skulle bruge tid på den slags, men der er på den anden side stadig muligt at manipulere data ned på bitniveau, hvis man skulle have behov for det. Der er enkle mekanismer til at lave parallelprogrammering, men man har samtidig adgang til den store værktøjskasse af synkroniseringsprimitiver o.a.

  • Funktionalitetsmæssig fleksibilitet. Man er ikke bundet til bestemte operativsystemer, persistensmekanismer, netværksprotokoller, concurrency-paradigmer, you name it. Der er ikke ret mange ting, som man ikke kan integrere med i Java.

Jeg er helt med på, at Java bestemt ikke er unikt hvad disse ting angår; meget af det ovenstående gælder formentlig også andre sprog som C#.

(*): En lidt asymmetrisk påstand, i øvrigt - gælder det ikke generelt (og ikke kun for andre sprog vs. Lisp), at det kan være svært at vide, om noget ukendt er et bedre alternativ?

Mikkel Lauritsens billede
Mikkel er CTO i IntraMed, som laver applikationer til håndtering af behandlingsforløb for patienter med kroniske sygdomme.

Kommentarer (59)

Christian Nobel

Og jeg kan rigtig godt lide Pascal, i praksis FreePascal, selv om der er nogen der anser det for "umoderne".

Det kan jeg så godt leve med, da det for mig er vigtigere at lave gode langtidsholdbare løsninger, end en eller anden esoterisk teoridiskussion om hvorvidt man kan vende nogle enkelt bit hurtigere i en eller anden konstruktion som er total irrelevant i forhold til de løsninger der skal bruges i hverdagen (i et lille land, fyldt med små firmaer, som ikke har behov for Pentagon regnekraft).

Jeg kan lide overskueligheden og den stærke typing, og at have en compiler (FPC) som sørger for at jeg ikke får lavet alt for mange kvajerter.

Og taler vi RAD, så er Lazarus faktisk kommet ret langt - og komponentlisten er kilometerlang.

Johnnie Hougaard Nielsen

en klasse pr. fil

Faktisk tillader Java flere klasser pr. source fil, også uden at det er det objektmæssige fællesskab som en indre klasse giver. Nestede klasser kan være handy til småtterier, og er med et IDE ikke "gemt væk".

At der findes standarder som forbyder brug af nestede klasser er så en anden sag.

Jonas Høgh

Okay, du kan ikke lide dynamiske sprog. (Jeg er som udgangspunkt enig især til større forretningssystemer som så vidt jeg fornemme er dit fokus)

Men hvor er dine argumenter for at Java er bedre end funktionelle sprog med langt stærkere typesystemer, det kunne være Haskell, ML/OCaml/F#, eller Scala?

Det er nok korrekt at intet andet økosystem er stærkere end JVM'ens, men det kan du jo heldigvis også tilgå fra Scala.

Disse sprog kan give dig ting som:
- Elimination af 80% af boilerplate som Java er fyldt med.
- Klasser af fejl der kan elimineres på oversættelsestidspunktet pga det bedre typesystem, fx null-helvedet.
- Meget nemmere concurrency pga immutability (nej, man kan ikke kalde Java god til concurrency, der er måske under 1% af udviklere der kan skrive et korrekt større program med monitorer og delt mutable tilstand)
- Pattern matching og discriminated unions, som er en væsentlig bedre måde at løse mange af de problemer som i Java ender i bloatede klassehierarkier, visitors, osv.
- Bedre fejlhåndtering gennem fx Either-monaden end den goto-suppe som exceptions ofte degenererer til i praksis.

Så givet at du gerne vil blive på JVM, hvad er argumentet for ikke at skrive dit næste nye projekt i Scala?

Niels Gustav Westphal Serup

Lad det være registreret i internettets evige database at jeg, Niels, d. 29. januar 2016 har erklæret følgende:

Java er skam okay.

Men altså, kun så længe at jeg ikke selv skal kode i det. Eller læse kode skrevet i det. Men det er da fint nok.

Palle Simonsen

En af de centrale påstande i Paul Grahams Beating the Averages er, at man ikke kan tage stilling til hvorvidt et programmeringssprog er godt eller ej før man har styr på Lisp (*)

Det kan jo kun glæde en gammel LISP programmør at læse :)

Ud af de mange elementer i LISP vil jeg fremhæve:

  1. Funktionel programmering
  2. Simpel syntax
  3. First order language

Funktionel programmering er mere en programmeringsstil og ikke nødvendigvis begrænset til funktionelle sprog. Der kan dog være sprogbaserede begrænsinger på hvilke data man kan opererer på.

Simpel syntax er unikt for LISP - basalt set er syntaksen s-expressions med regler for symboler og enkelte primitive og komplekse datatyper.

First order language betyder at funktioner og data på væsentlige områder er ligestillede og ikke kan skelnes - (if (=a 42) 'the-answer 'not-the-answer) er på samme tid et eksekverbart udtryk og data (s-expression). Dette bruges i mange sammenhænge, de mest banale at undgå de unaturligt store hierarkier i objectorienterede programmer implementeret med et 2 order language.

Java er som sådan et simpel nok sprog - J2EE med dets mange leverandør leverede og hjemmegjorte rammeværk kræver sin person at mestre -respekt for det!

Troels Henriksen

Python er det u-anstødelige sprog som man godt kan acceptere! Java er blevet for komplekst og for grimt, omend transplantationen af lambda-udtryk gik noget bedre end man håbede på. Man kan blot se på hvor galt det gik da man sløset sømmede anonyme metoder fast på Pascal, men det er jo heldigvis ikke et problem meget længere (fordi Pascal er døende, forstås).

Spørgsmål til bloggeren: Har du kigget på Erlang? Udover at typerne er dynamiske, så lader det til at opfylde mange andre af de kriterier du går op i - og det er endnu ældre end Java.

Jeg har et reelt kritikpunkt hvor jeg synes din subjektive holdning er objektivt forkert:

der er på den anden side stadig muligt at manipulere data ned på bitniveau, hvis man skulle have behov for det

Nej! Java har ikke unsigned heltal, hvilket man med en datalogisk fagterm kalder "super gøjseren". Hvis man ikke har unsigned, så er man nødt til at simulere dem ved at bruge den næste større signed heltalstype og afslutte hver beregning med modulus. Det gør det langsomt og notationelt besværligt at implementere algoritmer der laver bitfedteri, såsom f.eks. kryptografiske algoritmer.

Mikkel Lauritsen Blogger

Faktisk tillader Java flere klasser pr. source fil, også uden at det er det objektmæssige fællesskab som en indre klasse giver.

Korrekt - jeg tillod mig at være lidt løsagtig, fordi indlægget allerede var rigeligt langt i forvejen.

Selv om man ser bort fra indre klasser kan man kan godt have mere end en klasse i samme fil; bare højest en af dem er public. Jeg skulle nok i stedet have skrevet, at konventionen siger, at der kun er en klasse pr. fil.

Christian Nobel

Man kan blot se på hvor galt det gik da man sløset sømmede anonyme metoder fast på Pascal, men det er jo heldigvis ikke et problem meget længere (fordi Pascal er døende, forstås).

Prøv lige at være korrekt - det blev sømmet på Delphi, men de findes ikke i FreePascal.

Og så er det ret trættende at høre på dit "Pascal er døende", når det faktisk går den anden vej ifølge Tiobe!

Baldur Norddahl

Nej! Java har ikke unsigned heltal, hvilket man med en datalogisk fagterm kalder "super gøjseren". Hvis man ikke har unsigned, så er man nødt til at simulere dem ved at bruge den næste større signed heltalstype og afslutte hver beregning med modulus. Det gør det langsomt og notationelt besværligt at implementere algoritmer der laver bitfedteri, såsom f.eks. kryptografiske algoritmer.

Nej, du lader bare som om at Javas signed er unsigned. Det fungerer med de fleste binære operatører. Den kan ske at du nogle steder i din kode er nødt til eksempelvis at skrive -1 i stedet for 0xFFFFFFFF men det er som regel til at leve med.

Du kan også skifte til Scala, hvor der findes makroimplementering af unsigned, som laver alle de nødvendige omskrivninger compile time.

Torben Mogensen Blogger

En af de centrale påstande i Paul Grahams Beating the Averages er, at man ikke kan tage stilling til hvorvidt et programmeringssprog er godt eller ej før man har styr på Lisp.

Jeg vil udvide det til Standard ML, inklusive modulsystemet. LISP er en udmærket start, men det har mange af de egenskaber, som Mikkel ikke kan lide, f.eks. dynamiske typer. SML har et mere statisk typesystem end Java (hvor f.eks. arrays kræver køretidscheck fordi typesystemet ikke er sundt), og kan endda udlede typerne selv, så du slipper for en masser boilerplate. Og SML har ikke LISPs fikse ide om, at al data skal konstrueres med CONS, hvilket kun er en smule over det abstraktionsniveau, hvor al data skal udtrykkes med binære tal. Og modulsystemet i SML er stadig et af de mest gennemtænkte, der findes.

Dertil kommer, at SML faktisk ikke er noget kompliceret sprog: Grammatikken er kortfattet sammenlignet med f.eks. Javas, og sprogets semantik er formelt beskrevet i en tynd bog.

SML mangler dog det enorme økosystem, som Java har. Det er nok den væsentligste grund til ikke at bruge SML til næsten alt. Men hvis du vælger F#, har du et sprog, der har taget mange gode ting fra SML (men desværre forurenet det med grimme ting fra C# og O'Caml), og som har et økosystem, der kan sammenlignes med Javas.

Jonas Høgh

I øvrigt vil jeg mene at argumentet om at en klasse per fil er en feature er meget langt ude i hampen. Hvis man ikke kan få sine udviklere til at overholde en simpel tommelfingerregel omkring hvad der er rimelig filstørrelse så har man enten et tillidsproblem eller nogle decideret dårligt kvalificerede folk. Til gengæld er det så umuligt at erklære fx et interface med én metode og to korte implementeringer i den samme fil, selvom de fint kan være på et halvt skærmbillede.

Jonas Høgh

Men hvis du vælger F#, har du et sprog, der har taget mange gode ting fra SML (men desværre forurenet det med grimme ting fra C# og O'Caml), og som har et økosystem, der kan sammenlignes med Javas.

Hvis man ikke kan lide hybrid OO/FP sprog findes der også en Haskell-klon, der kører på JVM:

https://github.com/Frege/frege

Baldur Norddahl

Hvis vi skal være pedantiske (og det skal vi jo, det er et IT-debatforum) så er en binær operator en med to operander, du tænker vist på en bitvis operator.

Point take. For lige at illustrere med kode (i Scala syntax med det er det samme i Java):

scala> val b: Byte = (128+64).toByte
b: Byte = -64

scala> println(b.toInt & 255)
192

scala> val b2 = ((b.toInt & 255)/3).toByte
b2: Byte = 64

Ja beregningerne foregår i dette tilfælde i næste større type (typisk int eller long) men CPU overheadet ved dette er minimalt. Der er ingen problemer i at gemme data som unsigned i en signed type. Det er lidt klodset men virker.

I Scala kan man også bare bruge Spire https://github.com/non/spire hvorefter unsigned typer kan bruges direkte i din kode.

Troels Henriksen

Ja beregningerne foregår i dette tilfælde i næste større type (typisk int eller long) men CPU overheadet ved dette er minimalt. Der er ingen problemer i at gemme data som unsigned i en signed type. Det er lidt klodset men virker.

Jeg har netop erfaret en faktor-fem ydelsesforbedring ved at bruge unsigned typer i stedet for netop det der. Jeg omskrev først en implementering af IDEA-blokcifferet fra Java til C (lidt mere kompliceret end som så, men de yderligere detaljer er irrelevante). Java-koden (maltrakteret her) var skrevet som Java nu er, med dette cast-trick, og det var mit første udkast til C-koden også. Senere lavede jeg en rimeligt triviel omskrivning hvor jeg brugte unsigned typer i stedet, og programmet gik fra at bruge 293ms på at kryptere 8MB, til at bruge 61ms. Jeg havde ikke selv regnet med at forskellen ville være så stor, i hvert fald ikke på en 64-bit CPU. Mit gæt er at de mange casts og modulusoperationer forhindrer C-oversætterens optimeringsfunktioner i at virke optimalt; f.eks. ville det ikke undre mig om vektorisering (som er en absolut nødvendighed for at udnytte moderne processorer energieffektivt) blev ødelagt. Men jeg indrømmer gerne at jeg ikke har inspiceret assemblykoden endnu, så jeg kan tage fejl.

Baldur Norddahl

Java er nok bare et dårligt valg uanset hvad, hvis du er ude i at det er vigtigt om en division foregår som 32 bit eller 64 bit operation.

De fleste performance kritiske funktioner i Javas standardbibliotek er implementeret uden for sproget. Eksempelvis Zip bruges meget i Java (blandt andet er JAR bare ZIP filer) men zlib algoritmen er taget ind fra et C bibliotek.

Der er mange andre anvendelser hvor det ikke er et stort problem og hvor det er nyttigt at kunne bruge unsigned typer. Og det kan man så, på en lidt klodset måde.

Troels Henriksen

Det var ikke Java-koden jeg benchmarkede, men derimod C-kode skrevet i Java-stil med simulering af unsigned via brug af signed typer. Min påstand var at denne simulering rent faktisk er dyrere end man går og tror. Det er derved både nemmere at læse kode der bruger unsigned typer når der menes unsigned beregninger, men også hurtigere, så hvorfor burde det ikke være understøttet? Det eneste problem er hvis man har et sprog i C-stilen, der automatisk konverterer frem og tilbage baseret på brugen - det bliver hurtigt noget værre rod.

Baldur Norddahl

så hvorfor burde det ikke være understøttet

Det kan jeg ikke svare på. Jeg konstaterer bare at det ikke er et større problem i de fleste Java programmer og at man kan arbejde sig uden om det, når det er nødvendigt. At division og multiplikation ikke performer en til en i forhold til hvis sproget havde understøttelse er hellere ikke det helt store handikap i og med at der er så meget i Java der ikke performer på det niveau. Og endelig så kan udviklerne af JVM'en implementere algoritmer der genkender mønstret og optimerer til unsigned operationer - men det har de sikkert ikke gjort, da jeg tvivler meget på at det giver noget for ret mange Java programmer.

Troels Henriksen

Jeg blev nysgerrig omkring ydelsesforskellen og prøvede at afvikle IDEA med de to fremgangsmåder (signed versus simuleret signed) på en GPU (GTX 780 Ti) via OpenCL. Her er forskellen noget mindre - med simuleret signed kan de 8MB krypteres (og dekrypteres) på 6,6ms, hvor det tager 6,4ms med rigtige signed typer. Jeg tror forskellen ligger i at GPU-programmeringsmodellen garanterer vektorisering nærmest uanset hvor dumt man koder, så der er ingen oversætter man kan komme til at forvirre.

Palle Simonsen

LISPs fikse ide om, at al data skal konstrueres med CONS

Det ved du vist selv ikke er korrekt :)

;;; En simpel liste  
(return (list   
    (foo-a val-1 val-3)  
    (foo-b val-2 (foo-a val-4))  
     'a-symbol   
     "a string"   
    #'a-function))  
   
;;; Og en struct  
(return (make-person   
   :f-name "Karl"   
   :s-name "Koder"))  
   
;;; Osv.

I gamle dage havde man kun CONS, COND, CAR og CDR plus det løse - men det er meeget længe siden.

Min anke mod ML og F# etc. er den noget mere verbose syntax og i min verden går det helt galt, når whitespace som <CR> og <TAB> bliver en del af sproget.

Jeg medgiver at statisk typecheck kan redde en fra nogle som regel banale fejl . Commonlisp har indført mulighed med proclaim, declaim og declare, som bla. bruges for at give compileren mulighed for at lave mere effektiv kode, men også kan give fejl og warnings - compileren er selvfølgelig bare en funktion.

(defun add (x y)  
  (declare integer x y)  
  (+ x y))  
   
Lispprompt=> ADD  
   
(compile 'add)  
   
Lispprompt=> <compiled function #'ADD>
Mikkel Lauritsen Blogger

Men hvor er dine argumenter for at Java er bedre end funktionelle sprog med langt stærkere typesystemer, det kunne være Haskell, ML/OCaml/F#, eller Scala?

De er der ikke. Jeg har bare sagt, at jeg synes, at Java er godt til mit formål - jeg har på intet tidspunkt sagt, at det er optimalt. Og jeg er stærkt interesseret i at blive klogere.

  • Elimination af 80% af boilerplate som Java er fyldt med.

Netop sådan noget som gettere og settere, som folk har set sig meget sure på, har jeg ikke så meget imod. De bliver alligevel autogenererede af IDE'et, så de tager ingen tid at skrive, og de kan generelt totalt ignoreres. Ja, det var muligvis bedre uden, men de er ingen katastrofe.

  • Meget nemmere concurrency pga immutability (nej, man kan ikke kalde Java god til concurrency, der er måske under 1% af udviklere der kan skrive et korrekt større program med monitorer og delt mutable tilstand)

Man kan også lave immutable klasser i Java. Det er noget af det gode ved sproget - hvis man kan holde styr på andre synkroniseringsparadigmer kan man betjene sig af dem, og ellers kan man gøre som i andre mere begrænsede sprog.

  • Pattern matching og discriminated unions, som er en væsentlig bedre måde at løse mange af de problemer som i Java ender i bloatede klassehierarkier, visitors, osv.

Netop den her er jeg i tvivl om. Jeg er 100% enig i, at algebraiske typer er supersmarte, men det sker bare meget sjældent, at jeg sidder og tænker, at jeg kunne løse problemer meget smartere med dem. Og ja, det er selvfølgelig klart en konsekvens af det problemdomæne jeg beskæftiger mig med.

Så nej, jeg forholder mig ikke til FP - det er gemt til et senere blogindlæg :-)

Christian Nobel

Du må da være den eneste i verden der tager TIOBE Programming Community index for andet end indholdsløs underholdning?

Der gik egentlig længere lang tid før den kommentar blev fyret af end jeg havde regnet med.

Men siden du så er så fantastisk bedre vidende, så kan du vel også henvise til noget indholdsfyldt information der kan fortælle om fordeling af programmeringssprog?

Mikkel Lauritsen Blogger

Spørgsmål til bloggeren: Har du kigget på Erlang? Udover at typerne er dynamiske, så lader det til at opfylde mange andre af de kriterier du går op i - og det er endnu ældre end Java.

Som nævnt i en kommentar ovenfor, så har det ikke været mit ærinde at påstå, at Java er det ultimative sprog - og ja, Erlang er interessant. Om ikke andet må man nødvendigvis holde af et sprog, som er opkaldt efter en dansk matematiker.

Jeg har et reelt kritikpunkt hvor jeg synes din subjektive holdning er objektivt forkert:

der er på den anden side stadig muligt at manipulere data ned på bitniveau, hvis man skulle have behov for det

Nej! Java har ikke unsigned heltal

Arh... Jeg er ikke enig i, at manglen på fortegnsløse heltal betyder, at man ikke man lave bitfedteri. Jeg har lige skrevet noget kode i Java til at håndtere pakkede integers (data fra medicinsk måleudstyr FWIW), og det gik fint. Man kan sagtens gøre den slags uden at være hæmmet af manglen på unsigned integers, og ellers bliver man godt hjulpet af >>>-operatoren (unsigned shift right) og ting som Integer- og Long-klasserne, som stiller funktionalitet til rådighed til at lave rotate, reverse, FFS, NLZ osv.

Allan Ebdrup Blogger

Jeg læste et blogindlæg for noget tid siden der fik mig til at tænke: Jeg vil ændre min opførsel.

Blogindlæget, som jeg desværre ikke kan finde igen, handlede om at have respekt for andres teknologivalg. Du har selvfølgelig dine egne preferencer, og kan også argumenter for dem. Men grundlæggende må man have respekt for, at der er mennekser der skaber resultater med teknologier du ikke har megen fidus til. Resultaterne tæller.

Jeg har selv gjort lidt grin med Java i en af mine foredrag om Node.js (JavaScript). Det var dumt, det vil jeg holde op med.

Det er egentlig ret tragisk at jeg, som har elsket JavaScript siden start-nullerne, og har skulle høre på hvor forfærdeligt et sprog, mange syntes det var/er. Jeg mobber de andre sprog - når nu endelig JavaScript er blevet så populært, at nogen vil komme og høre et foredrag om det. Den mobbede bliver til mobberen.

Undskyld til de personer der skulle lægge ryg til den ene slide, der var dårlig stil.

Mit nye mantra er: Elsk de sprog du har lyst til, og jeg respektere enhver der kan skabe flotte resultater - ligegyldigt hvilket programmeringssprog, database eller anden teknologi du bruger.

Niels Gustav Westphal Serup

Se, det er jo interessant - har du mod på at komme med et konkret eksempel på hvad det er, som ligger til grund for din modvilje mod Java?

Okay, nu kommer det frem.

Du har ret i at jeg var en tand for vag i mine (subtile) påstande.

Sandheden: Jeg kan ikke lide Java, fordi jeg aldrig har lært at bruge et Interactive Development Environment (også kaldt "IDE"). Jeg kan kun finde ud af at bruge Emacs, og Java kræver i realiteten så meget boilerplate-kode at man kun har lyst til at kode det i et tilpas Java-fokuseret tekstredigeringsprogram.

Så i sidste ende koder jeg ikke Java, fordi jeg er alt for dårlig til at bruge moderne teknologier!

Christian Nobel

Mit nye mantra er: Elsk de sprog du har lyst til, og jeg respektere enhver der kan skabe flotte resultater - ligegyldigt hvilket programmeringssprog, database eller anden teknologi du bruger.

Præcis.

Som jeg tidligere har skrevet, så synes jeg at eksempelvis JavaScript er besværligt, dels fordi det er case sensitive, dels fordi jeg godt kan lide compilerede sprog (da compileren så kan afhjælpe nogen af mine dummefejl) - men det betyder ikke at jeg på nogen måde har belæg (endsige vidende) for at udtale mig om hvorvidt JavaScript er dårligt ud fra en datalogisk betragtning, og som det værktøj der nu engang er til rådighed hvis man vil lave noget client-side web, så er det jo ret akademiske at tale om andet i det spil.

Omvendt, så er det nok ikke nogen hemmelighed at jeg er glad for FreePascal/Lazarus, og det kan så godt være det ikke er så fint, og nogen anser det for døende, men for mig er det et rigtig godt værktøj til at udføre de opgaver jeg vil - og jeg anser mig selv for håndværker i dette spil.

Sjovt nok lever Pascal og Lazarus så meget at der er et stort community, så jeg stort set altid kan finde svar på de problemer jeg løber ind i.

Og så er selve kodningen som regel bare en lille del at et virkelig verdens projekt.

Baldur Norddahl

Aha, så enten kan man forlade sig på tro eller urbane myter, eller også kan man lade en form for opgørelse, uagtet hvad ens fordomme byder en, være en form for indikator.

Jeg ved godt hvad jeg trods alt selv anser for mest seriøst.

TIOBE bruger en metode som er så uvidenskabelig at den ikke er en indikator for noget som helst. Det at jeg ikke kender andre opgørelser der er bedre kan ikke ændre på at TIOBE er random crap.

Derfor er konklusionen at der ikke findes en rangering af programmeringssprog som kan bruges. Og det undre egentlig ikke, da vi næppe kan blive enige om kriterierne for hvordan sprog skal rangeres foruden at data ikke kan fremskaffes.

Troels Henriksen

Blogindlæget, som jeg desværre ikke kan finde igen, handlede om at have respekt for andres teknologivalg. Du har selvfølgelig dine egne preferencer, og kan også argumenter for dem. Men grundlæggende må man have respekt for, at der er mennekser der skaber resultater med teknologier du ikke har megen fidus til. Resultaterne tæller.

Jeg synes ikke der er nogen her, der ikke har respekt for andres teknologivalg, i hvert fald ikke jeg. Jeg har sådan set også respekt for teknologierne som sådan, så meget som man kan have respekt (eller nogen anden følelse) for et abstrakt koncept. Der er vel ingen der reelt har følelser for valg af programmeringssprog eller deslige?

Selvfølgelig kan man producere gode resultater i hvadsomhelst, men jeg synes ikke det er så konstruktivt at starte debatten der. Derimod er det interessant at tage forskellige teknologier, sætte dem på kanten, slå dem sammen for at se hvad der falder ud, og på alle måder udfordre dem, sig selv, og hinanden, for at finde ud af hvilke idéer der er gode, og hvilke der er mindre gode. Det handler om at blive dygtigere, få spredt gode idéer, og få inspiration til nye påfund!

Her når vi så til noget der gør mig lidt trist: Nemlig at mange programmører ikke har set specielt mange forskellige arter af programmeringssprog. Der er enormt mange interessante og spændende idéer der går en forbi, hvis man kun fokuserer på sprog der er umiddelbart anvendelige. Der er nok ikke mange programmer jeg vil anbefale man skriver i APL, men der er stadigvæk gode idéer og stof til eftertanke. Funktionsprogrammering ligeså - selv hvis man af praktisk nødvendighed ikke kan forlade sit objektorienterede sprog, så er der mange idéer man kan tage med, og det kan hjælpe på ens ræsonneringsevne, at man lærer at tænke og designed med de funktionelle koncepter i et sprog der er lavet til det, før man så er nødt til at lave en lidt mere kluntet implementering af idéen i ens arbejdssprog.

Selv Pascal, som jeg mest ynder at snakke om fordi det tilsyneladende gør visse debatører så vrede, har afarter med potentielt interessante idéer. For tiden læser jeg Per Brinch Hansens The Architecture of Concurrent Programs fra 1977, hvori han definerer sproget Concurrent Pascal, et sprog der har indbygget funktionalitet til at lette samtidighedsprogrammering, og lade oversætteren tjekke at man ikke kvajer sig. Concurrent Pascal's model med monitors er ikke nødvendigvis den bedste løsning - Actor-modellen som inkarneret i sprog som Erlang og Go er en anden måde at gøre det på - men det er godt at kende så mange kneb som muligt, især hvis de ligger et stykke fra den måde man ellers programmerer til dagligt.

Programmeringssprog har ikke følelser, og de kan godt tåle at man taler hårdt om dem. (Undtagen INTERCAL, hvis oversætters stolthed man skal pleje ved at skrive PLEASE et passende antal gange.)

Palle Simonsen

@Troels ++2
@Live and let live tråden ++2

Som gammel i gårde kan jeg kun anbefale andre at afprøve flere sprog og ikke mindst flere programmeringsparadigmer. Så bliver det langt lettere at finde et velegnet værktøj eller i en snæver vending slå skruer i med den svensknøgle, man har fået udleveret :) - Som andre siger, respekt til dem der kan frembringe programmer, der rent faktisk købes / bruges derude, uanset værktøj og ståsted og/eller kan bringe en god forståelse af forskellige måder for 'computational thinking' til de nye i faget med deres valg af værktøjer.

@Christian nævner noget om community og det er en stor hjælp i det daglige praktiske arbejde at man f.eks. på stackexchange o.lign kan finde hints eller færdige løsninger på mere eller indre indviklede problemer.

@Niels har selv brugt vi og Emacs tidligere, men nu bruger jeg sublime, en gulb build chain og xcode eller javac til oversættelse. De Java programmører jeg kender, bruger forskellige værktøjer til at producerer og debugge med eller uden IDE men i stort set 100 % af tilfældende med en ANT build chain. Jeg er sikker på at de herinde, der er mere vidende om moderne Java, kan give dig nogle gode 'pointers' til at komme igang.

Christian Nobel

Her når vi så til noget der gør mig lidt trist: Nemlig at mange programmører ikke har set specielt mange forskellige arter af programmeringssprog. Der er enormt mange interessante og spændende idéer der går en forbi, hvis man kun fokuserer på sprog der er umiddelbart anvendelige.

Se det er nok her vi går helt galt af hinanden.

For du ønsker at ophæve programmering til en videnskab og et mål i sig selv.

Jeg anser dette ud fra en mere prosaisk tilgangsvinkel, nemlig at programmering er en del af udvikling, og til denne udvikling vælger jeg de værktøjer der passer mig bedst, og som jeg kan lave de bedste produkter med.

Altså, for mig er programmering kun en del af en håndværk, og når jeg så skal lave en totalentreprise, så indgår der måske nogle discipliner, men ikke nødvendigvis alle.

Og skal jeg hænge skabet op, så er jeg sådan set ligeglad med om hvorvidt jeg kunne skrue skruerne i 0,2 sekund hurtigere hvis de havde en lidt anden stigning, hvis jeg skulle bruge 2 timer på at akademisere det, og skabet efterfølgende oven i købet hænger skævt.

Christian Nobel
Troels Henriksen

Se det er nok her vi går helt galt af hinanden.

For du ønsker at ophæve programmering til en videnskab og et mål i sig selv.

Jeg anser dette ud fra en mere prosaisk tilgangsvinkel, nemlig at programmering er en del af udvikling, og til denne udvikling vælger jeg de værktøjer der passer mig bedst, og som jeg kan lave de bedste produkter med.

Jeg tror du misforstår mig - jeg mener alt hvad jeg skrev udelukkende med henblik på at skrive bedre programmel. Hvis man begynder at se på programmeringssprog som kunstværker, så gælder der helt andre metrikker. At lære nye idéer er noget man skal gøre fordi ens kode bliver bedre. Det kan godt være min titel er PhD-studerende, men mit daglige job (såvel som mine hobbyprojekter) omhandler vedligeholdelse af rimeligt omfattende programmer. Mit forskningsprojekt er primært centreret omkring et monstrum af en optimerende oversætter på over 35000SLOC Haskell, og det hverken skrives eller vedligeholdes uden et hvis fokus på det praktiske håndværk... men mit praktiske håndværk er altså blevet bedre, af at lære f.eks. funktionsprogrammering.

Jn Madsen

er jeg her,- men jeg får lidt bekræftet mine fordomme.

Jeg kommer fra telekommunikation og netværk,- Linux og programmering er kun"nice to know".

Jeg bliver tit forbløffet over tonen når man bevæger sig i forum's mellem Linux/BSD folk og programmører.
En tråd starter altid pænt,- 5-10 kommentarer senere kaster alle med mudder og alle pisser på alle.

Den eneste Linux dist jeg gider at røre ved er Ubuntu (det kunne også have været RedHat),- resten er lavet af hysteriske typer med tynde arme og store ego'er.
Ubuntu virker som et rimeligt professionelt produkt, hvis der opdages et sikkerhedshul, så er der nok nogen på arbejde der fikser det.

Programmering,- jeg leger lidt med Python og Haskell,- jeg er ikke så god, men man bliver godt nok træt i hovedet af alle de narcissistiske og nedladende kommentarer i forum's og tråde.

Google er et godt værktøj når der skal ansættes/indledes samarbejde,- man ser lidt hvordan folk er når facaden smides.

Baldur Norddahl

Men alligevel så er der nogen der er kloge nok til at udråbe at hint eller dette er døende, men de kan ikke redegøre for det - ikke sagligt imo!

Det var ikke mig. Hvis du som aktiv bruger og kendskab til miljøet siger at det går godt, så er der ikke grundlag for at betvivle det.

At en udefrakommende udråber noget han ikke bruger som døende, tja. Computersprog er en religion så det må vi vist alle tåle.

Mikkel Lauritsen Blogger

Jeg kan ikke lide Java, fordi jeg aldrig har lært at bruge et Interactive Development Environment (også kaldt "IDE"). Jeg kan kun finde ud af at bruge Emacs, og Java kræver i realiteten så meget boilerplate-kode at man kun har lyst til at kode det i et tilpas Java-fokuseret tekstredigeringsprogram.

Hvis ikke man har lyst til at bruge et IDE, så er jeg med på, at Java ikke er så sjovt at have med at gøre, fordi man fravælger mange af de gode ting, som sproget muliggør.

Generelt kan et godt IDE i vidt omfang kan skrive meget af koden helt automatisk. Simpel syntaks som parenteser, anførselstegn osv. er oplagte, ligeså generering af gettere og settere, men nogen gange kan jeg blive helt benovet over hvor god autocomplete-funktionaliteten er til at gætte, hvad jeg gerne vil. <Ctrl>+<Space> skriver det hele (næsten) af sig selv.

Mekanismerne til at navigere rundt i koden er også særdeles nytting, og der, hvor det virkelig gør en forskel, er refaktoring. Ændring af klassehierarkier og metodesignaturer, omskrivning af deludtryk til metodekald og al den slags gøres på tværs af hele ens projekt med et enkelt tastetryk.

IntelliJ IDEA, som jeg bruger, kan i øvrigt gøres ret Emacs-agtig.

Mikkel Lauritsen Blogger

Blogindlæget, som jeg desværre ikke kan finde igen, handlede om at have respekt for andres teknologivalg. Du har selvfølgelig dine egne preferencer, og kan også argumenter for dem. Men grundlæggende må man have respekt for, at der er mennekser der skaber resultater med teknologier du ikke har megen fidus til. Resultaterne tæller.

Jeg håber meget, at "Du" skal forstås mere generelt end som en henvisning til mit blogindlæg - jeg har holdt mig helt fra at omtale andre sprog end Java, og jeg har i hvert fald ikke haft til hensigt at nedgøre andres valg; kun at forklare, hvorfor en bestemt teknologi (indtil videre) fungerer godt i den situation jeg befinder mig i.

Så fuld respekt for andre herfra. Min intention er, at vi kan blive kollektivt klogere på hvor godt/skidt forskellige sprog fungerer, og især på, hvad forudsætningerne for det er. Jeg er ikke selv født med at bruge Java som primært sprog, og før eller siden skal jeg også videre.

Allan Ebdrup Blogger
Jonas Høgh

De er der ikke. Jeg har bare sagt, at jeg synes, at Java er godt til mit formål - jeg har på intet tidspunkt sagt, at det er optimalt. Og jeg er stærkt interesseret i at blive klogere.


Fair nok, jeg læste måske mere ind i at du startede med dit Paul Graham-citat end du mente med det. Jeg synes det virker lidt underligt at dit indlæg reelt handler måske 75% om kvaliteter ved platformen JVM og kun subsidiært om kvaliteter ved Java som sprog. Du kan jo efterhånden vælge snart sagt ethvert type sprog at køre på JVM (fx Clojure hvis du vil gå hr. Graham i bedene og lege Lisp), så jeg synes det giver mere mening at se platformvalg og sprogvalg som uafhængige beslutninger. Og for sprogvalgets vedkommende synes jeg der er mange af alternativerne, der ser mere attraktive ud end Java. Ser frem til at læse dit næste blogindlæg :-)

Netop sådan noget som gettere og settere, som folk har set sig meget sure på, har jeg ikke så meget imod. De bliver alligevel autogenererede af IDE'et, så de tager ingen tid at skrive, og de kan generelt totalt ignoreres. Ja, det var muligvis bedre uden, men de er ingen katastrofe.

Det er sandt nok, men jeg synes det løber op, især når man skal læse andres kode, og skal finde frem til den del af høstakken, som rent faktisk har værdi at læse. Rigtig slemt bliver det hvis forfatteren har været "kreativ" og gemt fælder i boilerplate-koden, fx en getter med side-effekter, men okay, det er ikke sprogets skyld.

Prøv i øvrigt at sammenligne syntaksen i C# 6.0 med Javas og tænk på hvor mange quick wins der er i forhold til ting som auto properties og expression bodies. Min største kæphest her er dog at hverken Java eller C# fritager dig fra at skrive omkring 42 linier boilerplate, når du bare gerne vil have en simpel type med en fornuftig implementering af equals og hashcode. I F# eller Scala kommer det ud af boksen med en one-liner.

Man kan også lave immutable klasser i Java. Det er noget af det gode ved sproget - hvis man kan holde styr på andre synkroniseringsparadigmer kan man betjene sig af dem, og ellers kan man gøre som i andre mere begrænsede sprog.

Det kan man sagtens, men jeg tænker man nemt bliver hæmmet af at rigtig mange ting på platformen er designet omkring mutability. Jeg skal ikke udråbe mig til nogen ekspert i concurrency, specielt ikke i Java, men jeg vil mene at der igen skulle være fordele at høste ved at skifte til et af de andre sprog.

Netop den her er jeg i tvivl om. Jeg er 100% enig i, at algebraiske typer er supersmarte, men det sker bare meget sjældent, at jeg sidder og tænker, at jeg kunne løse problemer meget smartere med dem. Og ja, det er selvfølgelig klart en konsekvens af det problemdomæne jeg beskæftiger mig med.

Jeg er ikke helt med på hvorfor de ikke skulle være smarte i dit domæne, men jeg synes du skulle gøre dig selv den tjeneste bare at prøve at emulere pattern matching i Java. Selvom det er noget klodset og begrænset, synes jeg ofte det kan være enklere end de klassiske OO-tilgange. Se fx denne artikel: http://blog.higher-order.com/blog/2009/08/21/structural-pattern-matching...

Peter Holm Jensen

Alt det du skriver om Java, kan jeg kun give dig ret i, bortset fra at jeg ville vælge Python for at få det opfyldt........

Det skal siges at enten programmere jeg meget processor/maskinnært og så er det altid c/c++(/asm) eller også er det relativt videnskabeligt hvor der skal produceres nogle regnestykker/signalbehandling/databasegymnastik/plots og så er python universelt, og gør man bare en lille anstrengelse, er det faktisk let at holde ens ad hock scripts rimeligt struktureret (så de også kan forståes ugen efter de er skriblet) , målt op i mod f.eks. scilab/matlab/basic m.fl.

Christian Lynbech

Jeg medgiver at statisk typecheck kan redde en fra nogle som regel banale fejl .

Det er korrekt, men i praksis er det ganske underordnet. Tager vi simple typesystemer som f.eks. det i C så er klassen af fejl som type-systemet finder/forhindrer noget som alligevel ikke ville have kostet mange minutter at rette. De fejle der kan forsinke et projekt i uger og måneder er sådan som indekser der lidt ved siden eller store data-strukturer der pludselig og uforklarligt ændrer sig og det hjælper (simple) type-systemer ikke på.

Man kunne så tænke at det jo ikke skader, selvom gevinsten reelt er begrænset, men her er man jo så oppe imod at et statisk type-system er noget der skal vedligeholdes for alle positioner hele tiden, så hvis ikke der er en væsentlig gevinst så taber man mere end man vinder. Jeg har ikke selv arbejdet i de avancerede typede sprog som Haskell eller ML til at kunne sige om det forbedrer business casen nok til at den bliver positiv.

Palle Simonsen

De fejle der kan forsinke et projekt i uger og måneder er sådan som indekser der lidt ved siden eller store data-strukturer der pludselig og uforklarligt ændrer sig og det hjælper (simple) type-systemer ikke på

Fejl indeksering kan ikke rigtig ske uopdaget i LISP selvom man skulle finde på noget ala:

(dotimes (i (length some-array)
(svref some-array i+1))

Derimod kan datastrukturer der ændres ved sideeffekter sagtens ændres uforklarligt med mindre, selvfølgelig, man prøver at beskytte dem i en (defpackage ...) fil. :)

Mikkel Lauritsen Blogger

Beklager det sene svar; arbejdsramt...

Jeg synes det virker lidt underligt at dit indlæg reelt handler måske 75% om kvaliteter ved platformen JVM og kun subsidiært om kvaliteter ved Java som sprog.

God pointe, som jeg nok burde have haft med. Ja, bortset fra det med sproglig stringens og tildels det med abstraktionsniveau er det mest relateret til JVM'en og ikke sproget som sådan. Lige netop den med stringensen er så ret vigtig, fordi jeg oplever, at det gør koden lettere at forstå (og dermed vedligeholde) at der er snævre rammer.

I og med at meget af koden, som jeg roder med til daglig, er ret gammel, er det selvfølgelig også begrænset, hvor mange af de nyere sprog den oprindeligt kunne have været skrevet i :-)

I F# eller Scala kommer det ud af boksen med en one-liner.


Case classes? Ja, hvis de passer til ens model ser de umiddelbart fikse ud. Mit IDE kan i øvrigt autogenerere hashCode() og equals().

Baldur Norddahl

Mit IDE kan i øvrigt autogenerere hashCode() og equals().

Men husker den også at opdatere de metoder, når du laver ændringer, samt forhindre at du laver mutable state, hvilket jo invaliderer en hashCode?

Alt det autogenereret kode er noget du lever med fordi det er nødvendigt. Det er ikke smart. Det smarte er at det er noget oversætteren klarer automatisk.

Case classes laver i øvrigt også en copy constructor samt en toString implementering.

Mikkel Lauritsen Blogger

Alt det autogenereret kode er noget du lever med fordi det er nødvendigt. Det er ikke smart. Det smarte er at det er noget oversætteren klarer automatisk.

Enig. Jeg siger ikke, at Java er den smarteste løsning på den slags udfordringer - det ville også være mærkeligt, hvis ikke man på nogen punkter var blevet klogere i de 9 år mellem Java og Scala.

Min pointe er, at mange af de ting, som folk fremhæver som værende meget store fordele ved andre sprog frem for Java, ikke er noget, som jeg spilder meget tid på at håndtere i det daglige. Det er sjældent, at jeg har behov for at skrue i den del af applikationerne, og boilerplate-koden er (i sagens natur) ret velforstået, så det ender med at være småting i forhold til øvrige arbejdsopgaver.

Hvis jeg ikke lavede andet end sidde og skrive klasser med equals(), hashCode() osv. ville min holdning nok se anderledes ud.

Jonas Høgh

Hvis jeg ikke lavede andet end sidde og skrive klasser med equals(), hashCode() osv. ville min holdning nok se anderledes ud.

Jeg har aldrig arbejdet med en Java/C# kodebase, der ikke til en vis grad led af Primitive Obsession fordi det er så besværligt at lave simple typer.

Det betyder at din hjerne konstant skal bruge kapacitet på ting som at afkode hvilken af de to heltallige metodeparametre, som er varenummeret, og hvilken som er styktallet.

Christian Lynbech

Det var ikke for at skyde på Lisp (jeg er selv en af de troende) men mere at illustrere det futile i at stole på simple type-systemer som noget der reelt bibringer noget produktivitet.

Ideen om at programmøren er programmets største fjende og at man fra sproget og projektet skal gøre alt hvad man kan for indhegne disse håbløse vildbasser og forhindre dem i at gøre noget forkert, har jeg altid haft det svært med.

Føler man ikke man kan stole på sine programmører er det nok snarere programmørerne der er noget galt med end sproget eller processerne eller IDEet.

Henrik Eiriksson

Personligt vurderer jeg et programmeringssprog ud fra dets mekanismer til fejlhåndtering.

Java's checked-exception tvang er upopulær, men jeg synes selv at det er bedste der er sket for programmering. Ever.

Performance er sekundært - for hvad nytte gør et program hvis det kan fejle 5 gange hurtigere? Gerne i et loop.

Min baggrund ligger i udvikling af serverside systemer. Jeg vil helst ikke være #1 på sysadmin's speed-dial. Sysadmin skal helst glemme mig. Derfor min kærlighed til checked-exceptions, logging og tests. Java gør det godt dér, methinks.
Java kode er verbose, ja; men også gennemskuelig. Det betaler sig ifm. debugging & refactoring.

Husk på hvilken legacy Java blev født af. Sun. Unix. Servere. Stabilitet.

Andre, med fokus på f.eks. frontend kode - som har en brugers udelte opmærksomhed - ser muligvis ikke nødvendigheden af dyb exception-handling, idet der sidder et menneske til manuelt at håndtere det, eller i værste fald: blot acceptere at der opstod en exception.

Jonas Høgh

Java's checked-exception tvang er upopulær, men jeg synes selv at det er bedste der er sket for programmering.


Sammenlignet med hvad? Et PHP-program, der spytter et par eder ud i HTML-outputtet og triller lykkeligt videre, selvom det er fejlet? Et tussegammelt C-API, der bruger returkoder til at signalere fejl, og hvor alt kan ske hvis man glemmer at checke koden?

Der findes bedre måder at håndtere fejl i de fleste funktionelle sprog. Prøv fx at se Scott Wlaschins talk om "Railway Oriented Programming" for en introduktion, der er forståelig uden FP-baggrund: http://fsharpforfunandprofit.com/rop/

Log ind eller opret en konto for at skrive kommentarer