Javas chefarkitekt: Sådan bliver Java 8 mere moderne – på en konservativ måde

GOTO: Det er ikke let at putte nye tricks ind i Java, som stadig skal være bagudkompatibel, forklarede Oracles chefarkitekt for Java. Men med Java 8 kommer der blandt andet lambda-udtryk, der længe har været efterspurgt af udviklerne.
Illustration: Jesper Kildebogaard

Efter mange års udvikling og problemløsning har Oracle fået puttet nye funktioner ind i Java – men det er ikke en let kamp, fortalte Brian Goetz, chefarkitekt for Java hos Oracle, da han tirsdag morgen gik på scenen til udviklerkonferencen Goto i Aarhus.

»Der er en konstant uenighed om, hvor meget, der skal ændres, og hvor hurtigt det skal ske. Vi bliver hadet fra begge sider. Men vi har en meget lav tolerance for ændringer, der ikke er kompatible. Vi vil ikke ødelægge folks kode. Og vi vil ikke gå efter, hvad der er moderne lige nu, i jagten på nye, cool ting,« sagde han.

Læs også: »Nu bliver Java langt om længe et moderne sprog«

I Java 8, som kommer på gaden engang til foråret, kommer der nye muligheder, der trækker Java i en mere funktionel retning.

»Listen over nye features er faktisk ret kort. Men de vil til gengæld have stor betydning for produktiviteten hos Java-udviklerne. Der var mange ting, vi kunne have tilføjet, men vi valgte at satse på nogle få, der så har stor effekt,« forklarede Brian Goetz.

Punkt 1 på den korte liste over vigtige ændringer er, at Java 8 får lambda-udtryk (expressions).

»Det er endelig blevet tid til lambda-udtryk. Det vil gøre det muligt at udvikle mere kraftfulde biblioteker. Koden bliver lettere at læse, og der vil være færre fejl,« lød det fra Brian Goetz.

Spørgsmålet var så, hvordan syntaksen skulle bygges op – og det havde affødt uendelig meget debat, sagde Java-chefarkitekten.

»Det er det, udviklere gør – det var ren ’bike-shedding’ (at diskutere en konkret, men generelt uvæsentlig del af problemet, red.). Vi endte med at stå med mange forskellige løsninger, hvor den ene ikke var mere Java-agtig end den anden, og så endte vi med en syntaks, der også bliver brugt i andre sprog,« forklarede han.

Den typiske, lidt utaknemmelige reaktion på nyheden om lambda-udtryk, har været: Hvorfor skulle det tage så lang tid? Men der er mange detaljer, der skal på plads, når der bliver ændret i Java, og det stadig skal være bagudkompatibelt, sagde Brian Goetz.

Et blidt, funktionelt puf

I forlængelse af lambda-mulighederne får Java 8 også default metoder, der tidligere også har været kaldt defender-metoder eller virtual extension-metoder. Og generelt bliver Java drejet i retning af de funktionelle sprog, der er blevet så populære på det seneste. Det skal dog ske stille og roligt, for ellers bliver Java-udviklerne forskrækkede, vurderede Brian Goetz.

»Vi giver folk et blidt puf i retning af en mere funktionel stil. Vi bruger ikke f-ordet så meget, for det skræmmer folk, men langsomt vil folk se, at det er nemmere at arbejde på den måde, og så vil folks dovenhed sørge for, at de går den vej,« sagde han.

De nye muligheder i Java 8 er dog kun et skridt på vejen i sprogets løbende udvikling, understregede han. For eksempel er det blevet mere tydeligt, nu hvor Java bliver lidt mere funktionelt, at der mangler nogle tricks, for eksempel tuples, som de funktionelle sprog er født med.

»Vores næste store mål er value types. Men det vil tage noget tid. Java vil ikke have tuples om 1-2 år – det vil være for ambitiøst,« sagde chefarkitekten, som også lige måtte vise en Oracle-standardbesked om, at den slags forudsigelser kan ændre sig og ikke er nagelfaste.

Den overordnede historie om de ændringer, der kommer nu med Java 8, er, at Java er fuld af liv og tilpasser sig nye krav til programmeringen – men i et stille og roligt tempo.

»Med en stor nok indsats, er det muligt at lære en gammel hund nye tricks. For få år siden troede mange, at Java var et overstået kapitel. At alt godt har en ende, og den slags. Men jeg synes, vi har vist, at det ikke er tilfældet, og at vi kan udvikle Java, uden at bryde med kompabiliteten og med vores principper for Java,« sagde Brian Goetz

Han kiggede også lidt tilbage i tiden til Javas fødsel i 1990’erne, hvor sproget var ’cutting edge’.

»I 1992-1995 var C dominerende, og det var temmelig desillusionerende for mange, for der var helt klart brug for noget bedre. Det var meget lowlevel. Mange af de features, man valgte at tage med i Java dengang, var meget vovede. Garbage collection og JIT (just-in-time, red.) var meget store satsninger, som lykkedes – men det var ikke oplagt, at de ville det,« forklarede han.

Selvom Java var ’vovet’, var det samtidigt konservativt fra fødslen af, og nemt at gå til for udviklerne. Tanken var, at det skulle være et ’arbejder-sprog’, et, der får opgaven løst uden fine fornemmelser.

»Det var ikke bare en masse funktioner, som James Gosling (Javas skaber, red.) så puttede i en stor sæk. Alt det risikable var ’over vandlinjen’, og under vandlinjen var Java meget konservativt og sikkert. Så udviklerne fik alle de nye funktioner, de ønskede sig, men i et sprog, der lignede noget, de kendte,« sagde Brian Goetz.

At det på den måde lykkedes at få ’solgt’ Java til udviklerne, ved at pakke de nye ting ind i velkendte rammer, var helt afgørende for Javas udbredelse. I dag arbejder ni millioner udviklere verden over med Java, og både indbyggertal og økonomien i Java-udvikling svarer i grove træk til Sverige, lød meldingen.

»Det var alle Jedi mind tricks moder. Hvis du skal lokke folk over, skal du snyde dem en lille smule. Og tricket her var fantastisk succesfuldt,« sagde Brian Goetz.

Tips og korrekturforslag til denne historie sendes til tip@version2.dk
Kommentarer (32)
sortSortér kommentarer
  • Ældste først
  • Nyeste først
  • Bedste først
Casper Paulsen

Må nu sige jeg er glad for at der findes alternativer til Java, når vi snakker programmeringssprog til JVM. Med den fart Oracle har og den bagudkompabilitet, der skal være tilstede, så går der jo alt for lang tid med at komme op på niveau med andre sprog.

Som en side note, så check Scala ud.

  • 1
  • 0
Baldur Norddahl

Man kan implementere en generisk tuple klasse på 10 linjer java kode. Hvorfor er det en stor ting? Det mærkelige er at alle skal implementere deres egen tuple i stedet for at det er noget der bare er til rådighed i java.util.

  • 0
  • 0
Jesper S. Møller

Nu er det jo ikke bare spørgsmål om at have en dum Pair<T1,T2> klasse -- når man snakker om tupler og understøttelse af dem er det jo for at have en konstruktion af arten:

Tuple<> t1 = (57, "Syvoghalvtres");

og tilsvarende konstruktioner til at pille dem ad:
(int i, String s) = t1;

Det kan man ikke løse igennem libraries.

  • 4
  • 0
Baldur Norddahl

Nu er det jo ikke bare spørgsmål om at have en dum Pair<T1,T2> klasse

Det er bare syntaktisk sukker. Den egentlige funktionalitet er der, nemlig evnen til at have en generisk tuple klasse der håndterer typer. Vi kan sammenligne med alternativet som Nikolaj angiver:

// pre java generics kode:  
Object[] foo = new Object[] {57,"Syvoghalvtres"};  
Integer a = (Integer) foo[0];  
String b = (String) foo[1];

Og så med tuples:

Tuple<Integer,String> foo =   
  new Tuple<Integer,String>(57,"Syvoghalvtres");  
Integer a = foo.a; // ingen type cast nødvendig  
String b = foo.b;

Tuple er som sagt blot 10 linjers kode, men fordi den ikke findes som standard, så ser vi tonsvis af kode hvor programmøren vælger at returnere en Object[] som løsning på at kunne returnere to værdier fra en funktion.

  • 1
  • 0
Nikolaj Brinch Jørgensen

Tuple er som sagt blot 10 linjers kode, men fordi den ikke findes som standard, så ser vi tonsvis af kode hvor programmøren vælger at returnere en Object[] som løsning på at kunne returnere to værdier fra en funktion.


Ja for en 2-tuple, men så skal vi lige have alle de andre med 3-tuple osv. Og det er rigtigt at Object[] ikke holder vand, da den kan indeholde uendeligt mange elementer (indtil maskinen der afvikler siger stop) - not a property of tuples.
Lad os få rigtige tupler. Syntaktisk sukker, tja men det skal der altså med i moderne sprog, vi gider ikke skrive al den kode, der er bare fejl i den, og det værste er, at nogen kopiere den rundt, så den er der mange gange.

  • 0
  • 0
Jesper S. Møller

Tuple er som sagt blot 10 linjers kode, men fordi den ikke findes som standard, så ser vi tonsvis af kode hvor programmøren vælger at returnere en Object[] som løsning på at kunne returnere to værdier fra en funktion.

Jeg tror ikke du forstår hvor jeg eller Brian Goetz vil hen.

Du viser et pair, alle kan lave sådan én, og at bruges Guavas er en no-brainer, eller man kan 10 linjer lave en Tuple1, Tuple2, Tuple3, etc. hvis man virkelig vil.

Men det er først når man har en elegant tupel-constructor og "destructor" (som i mit eksempel før) at det kan give mere stærk og læselig kode. Og det kræver grammatikændringer m.m. i et sprog som allerede er småbøvlet at parse, hvis det skal være bagudkompatibelt med to trillioner af linjer Java-kode, der findes derude.

Åh, og understøttelse i pattern-matching vil også være godt. (Og så er vi jo tilbage ved ML...)

  • 2
  • 0
Baldur Norddahl

Hvis i vil have rigtige Tuples, så skift til Scala. Pattern matching og tuple constructor er ikke the java way.

I min verden er vi kommet langt hvis vi med en totalt triviel tilføjelse til standard biblioteket kan få alverdens java programmører til at holde op med at returnere Object[].

PS.: Man behøver ikke en Tuple3: Tuple<String,Tuple<Int,Double>>

  • 2
  • 0
Jesper S. Møller

Tak, jeg bruger Scala og Groovy når det passer bedre. Og somme tider Java 1.4.2 (!!)

PS.: Man behøver ikke en Tuple3: Tuple<String,Tuple<Int,Double>>

Yikes, det er jo værre end at definere en bette klasse med tre public final felter til at holde værdien, ikke mindst fra GC og JIT synspunkt.

Tror vi skal "agree to disagree" om udviklingen af Java sproget, og håbe at folk kan få produktivitetsforbedringer ud af Java 8 som det foreligger.

  • 2
  • 0
Baldur Norddahl

Og det er endnu pænere med

val (a,b,c) = tuple

scala> case class ::[A,B](a: A, b: B)  
defined class $colon$colon  
   
scala> val tuple = ::(42,::("bar",5.7))  
tuple: ::[Int,::[java.lang.String,Double]] = ::(42,::(bar,5.7))  
   
scala> val (a :: b :: c) = tuple  
a: Int = 42  
b: java.lang.String = bar  
c: Double = 5.7

Men den slags kommer aldrig til Java og det er egentlig også ok. Vi har allerede Scala til dem der vil så langt.

  • 0
  • 0
Baldur Norddahl

Nu også med implicit klasser:

scala> case class ::[A,B](a: A, b: B)  
defined class $colon$colon  
   
scala> implicit class Init[B](b: B)   
  { def ::[A](a: A) = new ::(a,b) }  
defined class Init  
   
scala> val tuple = 42 :: "bar" :: 5.7  
tuple: ::[Int,::[String,Double]] = ::(42,::(bar,5.7))  
   
scala> val (a :: b :: c) = tuple  
a: Int = 42  
b: String = bar  
c: Double = 5.7

Case class, implicit class og pattern matching - hmm ikke just noget der kommer i Java næste år.

  • 0
  • 0
Jesper S. Møller

[quote]
Og somme tider Java 1.4.2

Vist ikke lige fordi det som sprog passer bedre. Det er kun runtime begrænsninger går jeg ud fra?
[/quote]
Jo, det er korrekt, konkret er det Eclipse's Java-oversætter: Der er for mange, der afhænger af det projekt, til at nogen 'tør' opgradere til at kræve Java 5+, og hvis vi gjorde ville vi sikkert stadig rode med arrays direkte af RAM/performancehensyn. Det er ikke fordi jeg foretrækker Java 1.4...

  • 0
  • 0
Nikolaj Brinch Jørgensen

Selvfølgelig er det mere effektivt at lave en Tuple3, men mit problem er løst blot de gider lægge en Tuple2 ind i java.util.


Scala laver faktisk Tuple2, Tuple3 osv. under the covers, det er blot syntaktisk sukker i Scala. Derfor er der også support for op til Tuple22, og så ikke længere (22, what an odd number - men måske ham der skrev klasserne kunne nå 22 inden frokost).

  • 0
  • 0
Nikolaj Brinch Jørgensen

Selvfølgelig er det mere effektivt at lave en Tuple3, men mit problem er løst blot de gider lægge en Tuple2 ind i java.util.


Scala laver faktisk Tuple2, Tuple3 osv. under the covers, det er blot syntaktisk sukker i Scala. Derfor er der også support for op til Tuple22, og så ikke længere (22, what an odd number - men måske ham der skrev klasserne kunne nå 22 inden frokost).

  • 0
  • 0
Jesper Louis Andersen

Alverdens funktionelle sprog skelner skarpt mellem lister og tupler.

Rent teknisk, så gør Scheme nok ikke. Den halvkanoniske måde at lave en tuple på er det samme som at lave en liste. Du kommer først i problemer hvis du enten har et statisk typesystem[0] eller hvis du vil pakke data tættere grundet effektivitet.

[0] Vel nok et statisk typesystem uden dependent types.

  • 0
  • 0
Baldur Norddahl
  • 0
  • 0
Morten Wegelbye Nissen

Jeg har svært ved at se behovet.
Giver noget.a, noget.b mening? imho giver det de samme problemer som resultset[72] vs resultset["someOddProperty"].
Jeg har til dato ikke set nogen ordentligt generisk implementation. getLeft, getRight dur ikke. getKey, getValue er det nærmeste jeg har set, men det er så tæt på Map.Entry.....

Nææææ... jeg fortrækker kode der er til at læse :) - og det tager mig ikke lang tid at lave en bean der holder netop det der er brug for.

  • 0
  • 0
Log ind eller Opret konto for at kommentere