Julegave til kode-folket: Java 7 får closures og parallelisme

Imod forventning vil den kommende Java 7 få closures, extension methods og funktioner på første klasse. Det betyder, at Java ikke er helt død endnu, mener dansk udvikler.

Stik i mod tidligere udmeldinger, ser det nu ud til, at den kommende Java 7 får closures. Det har Suns Java-mand Mark Reinhold meddelt på Devoxx-konferencen, som blev afholdt i Belgien for nylig.

Closures findes i mange sprog og er en måde at benytte en lille blok af kode som parameter. Muligheden findes i mange sprog, som f.eks. Ruby og C#.

Ifølge Mark Reinholds blog kommer følgende med i version 7:

En syntaks til at skrive closures i koden, funktionstyper, konvertering af closures fra objekter med én enkelt metode, og endeligt extension methods. Det sidste kendes fra C# og bruges til at udvide eksisterende klasser med nye metoder.

Der er i øjeblikket tre closure-forslag på bordet, men Mark Reinhold mener, at den endelige udgave bliver noget helt fjerde.

Java - nu lidt mindre død

De nye toner fra Sun giver grund til optimisme, mener udvikler Ole Friis Østergaard fra Trifork:

»Jeg plejer at sige, at Java er død. Men Java er nok ikke helt så død længere.«

Han ser closures som en god tilføjelse til sproget.

»Jeg synes, det er rigtigt godt, for det gør, at det dagligdags arbejde med Java bliver mere smertefrit. I Ruby har man også closures. Det gør, at éns programmer føles anderledes. F.eks. er det nemmere, hvis man har en liste, hvor man vil hive et enkelt element ud, så skal man bruge meget lidt kode, hvis man har closures.«

Det er den funktionelle programmeringsstil, som Ole Friis Østergaaard har i tankerne.

»Jeg kan også godt lide at de får extension methods med i Java 7. Et af problemerne med closures i Java er, at det ikke har været med siden starten, så alle de eksisterende frameworks er ikke lavet til det. Som udgangspunkt har man f.eks. ikke de metoder, man skal have på en liste.«

Parallelisme kræver closures

Ifølge flere kommentatorer er closures kommet på banen i version 7 på grund af parallelisme-frameworket fork-join, som også forventes at komme med i samme omgang. Uden closures ville frameworket kræve 80 nye interfaces i JDK-bibliotekerne, siger Stephen Colebourne, der er ophavsmand til ét af tre aktuelle closure-forslag, til bloggen Artima.

Men Ole Friis Østergaard synes, at parallelisme er en spøjs grund til at tilføje closures til Java.

»Hvis man mener parallelisme seriøst, så kan jeg ikke forstå, at man stadig sidder med Java. Så ville man være hoppet videre til Clojure, Erlang eller noget andet. Jeg er egentligt ret uinteresseret i parallelisme. I den verden, jeg bevæger mig i, er det ikke noget problem.«

Hvis man skriver webapplikationer, er det nemlig webserver, frameworks og databaser, der håndterer parallelismen for programmøren, lyder Ole Friis Østergaards pointe.

»Derfor synes jeg også, at det er pudsigt, at der er så meget i denne her udviklerverden, der fokuserer på det, for jeg tror, det er en minoritet, der har med det at gøre.«

Men i hans øjne er Java er stadig langt efter andre sprog, som eksempelvis C# og Ruby.

JVM'en er stjernen

Et andet budskab fra Mark Reinhold på Devoxx-konferencen var, at det nu er JVM'en, som er stjernen. De mange sprog på platformen skal nu betragtes som lige så gode medlemmer af familien som Java.

»Det er jeg fuldstændig enig i.Jeg har gået og sagt: Java er død, længe leve JVM'en. Hvis man vil ud at prøve nogle nye sprog, så er der et væld af dem, som f.eks. Clojure og Scala, hvor mange af de ting, der kommer i Java 7, allerede er implementeret,« siger Ole Friis Østergaard.

Han benytter selv JRuby i forbindelse med test.

Ifølge Mark Reinhold vil Java 7 blive fastfrosset med hensyn til funktionalitet i juni måned, næste år. Det endelige version kan forventes i slutningen af 2010.

Et kodeeksempel
Closures kan forsimple koden ganske meget. Herunder er vist et eksempel fra BGGA-forslaget, som går ud på at finde studerende med topkarakterer:

01 **double **bestGpa = students.withFilter(isSenior) 02                          .withMapping(selectGpa) 03                          .max(); 04  05 **public class **Student { 06     String name; 07     **int **graduationYear; 08     **double **gpa; 09 } 10  11 **static final **Ops.Predicate isSenior = **new **Ops.Predicate() { 12     **public ****boolean **op(Student s) { 13         **return **s.graduationYear == Student.THIS_YEAR; 14     } 15 }; 16  17 **static final **Ops.ObjectToDouble selectGpa = **new **Ops.ObjectToDouble() { 18     **public ****double **op(Student student) { 19         **return **student.gpa; 20     } 21 };

 
Med closures kan det samme skrives som:

1 **double **bestGpa = students.withFilter({Student s => (s.graduationYear == THIS_YEAR) }) 2                          .withMapping({ Student s => s.gpa }) 3                          .max();
Tips og korrekturforslag til denne historie sendes til tip@version2.dk
Kommentarer (22)
sortSortér kommentarer
  • Ældste først
  • Nyeste først
  • Bedste først
Flemming Frandsen

Biologer har et andet ord for "stabilt" end os software folk, det er "dødt".

Set på den baggrund giver det mere mening at omtale et sprog som dødt selv om det bliver brugt mange steder.

C har f.eks. været stabilt/dødt i mange år, faktisk er det nok den største kvalitet ved C.

  • 0
  • 0
Ole Østergaard

JAOO er jo meget andet end Java. Der er .NET-tracks, proces-tracks og alt muligt om nye sprog og teknologier. Der er selvfølgelig stadig Java, men selve navnet JAOO er måske lidt misvisende den dag i dag fordi der også er så meget andet.

Jeg har kollegaer der sværger til .NET, jeg har kollegaer der har forelsket sig i Clojure, jeg har kollegaer der elsker Java over alt på jorden osv. Sådan skal det have lov at være.

Selvfølgelig er Java ikke "dødt" som i "ingen bruger det" - masser af firmaer bruger det. Hvad jeg mener, er bare at udviklingen af sproget har ligget meget stille i mange år, og de fleste nyskabelser er blevet bremset af JSR-processerne. Derfor er jeg rigtig glad for at se at der endelig sker noget igen.

  • 0
  • 0
Kasper Sørensen

Jeg er sgu træt af folk der bevidst kalder Java dødt for at promovere andre, eksperimenterende sprog. I mine øjne er Java spræl-levende og innovationen på Java EE 6 ser f.eks. ud til at være meget fremadrettet og progressivt. Den store forskel i Java-verdenen er ofte, at det mindre er syntaxen der ændres og mere er API'erne der forbedres og gentænkes.

  • 0
  • 0
Casper Bang

Stakkels Sun, de må være pænt forvirrede. 3+ år med debat og prototypes af closures, for så ikke at medtage closures. Og så nu en kovending igen.

Min personlige holdning er at Sun har været nød til det fordi de er blevet kritiseret kraftigt pga. de relativ små tiltag i Java7 (hvor mange af os kæmper med Date/Calendar for slet ikke at tale om har mareridt omkring BigDecimal?).

Dertil hjælper det nok også at de er forsinkede og har droppet JSR'ere til højre og venstre. Grundet til dette er (ifølge Alex Buckley fra Sun) at JavaFX dræner Sun for rigtig mange resourcer.

  • 0
  • 0
Esben Nielsen

Man kan jo bruge indre klasser, altså skrive (undskyld manglende formatering og compile test):

double bestGpa = students.withFilter(new Ops.Predicate() {
public boolean op(Student s) {
return s.graduationYear == Student.THIS_YEAR;
}
}).withMapping(new Ops.ObjectToDouble() {
public double op(Student student) {
return student.gpa;
}
}).max();

Ja, det er grimmere end clossures; men reelt er det det samme - i modsætning til eksemplet i artiklen, som faktisk laver og gemmer nogle referencer til objekter, som lige så godt kunne smides væk igen.

  • 0
  • 0
Casper Bang

Jeg forstår hvor du vil hen, kode eksemplet er ikke det bedste. Men tillad mig at omformulere. Java er jo i forvejen et Turing komplet sprog så der er IKKE noget du kan gøre med closures som du ikke kan uden. :)
Pointen er at skabe syntaktisk support i sproget der kan bruges i libraries og til at nedbringe boiler-plate generelt, som der jo er rigelig af i Java i forvejen.

Der er frameworks der bruger samme princip, f.eks. lambdaj, men jeg mener ikke det er closures eller lambda funktioner. En closure er per definition noget der binder sig til variabler i det leksikale scope - deri ligger styrken.

  • 0
  • 0
Torben Mogensen Blogger

Selv om eksemplet

[code=java]
double bestGpa = students.withFilter({Student s => (s.graduationYear == THIS_YEAR) }).withMapping({ Student s => s.gpa }).max();
[/code]

er en del kortere end før closures blev brugt, er det stadig en del længere end det tilsvarende i SML:

[code=ocaml]
bestGPA = Max (map (#gpa) (filter (fn s => #graduationYear s = THIS_YEAR) students))
[/code]

Eller Haskell:

[code=haskell]
bestGPA = max [gpa s | s<-students, graduationYear s == THIS_YEAR]
[/code]

  • 0
  • 0
Kasper Sørensen

Jeg fristes til at spørge "og hvad så?". Ja det er sandt at man har læsset en masse special-karakterer og andet skrammel ind i sproget for at spare nogle linier, men det har i mine øjne flere ulemper end fordele:

Selve sproget bliver sværere at lære fordi der er flere konstruktioner. I stedet synes jeg det taler til Javas fordel at antallet af konstruktioner er relativt få - til gengæld er bibliotekerne store. Det er dog meget lettere (IMHO) at lære et bibliotek hvis man kender syntaksen end omvendt.

Det svarer lidt til at vi omdøbte "String" klassen til "St" fordi det fylder færre karakterer og så kunne vi VIRKELIG spare en masse kode. Når jeg (og nærmest alle andre formoder jeg) skal lave en String skriver jeg "St" og taser min autocomplete tast, så hvad er problemet?

Hvis man lærer at bruge autocomplete og anden værktøjsunderstøttelse fornuftigt, så bliver langt det meste "syntax sugar" overflødigt. Bevares der er nye sprog-konstruktioner som virkelig batter (og closures er garanteret en af dem), men den der med at vi skal kunne udtrykke alting på super komprimerede former som stiller krav til syntax-ændringer i sproget mener jeg kun gør det sværere at lære at kode. Og især synes jeg det er unfair at klantre Java for at have en konservativ holdning til at indlemre den slags i sproget.

  • 0
  • 0
Baldur Norddahl

Hvis man altså ser bort fra at der ikke er nogen max funktion som standard. Det er et mærkeligt eksempel, for normalt vil man ikke have en "max" funktion, som jo kun giver mening for datatyper som kan sammenlignes.

I stedet vil man have en fold eller reduce operation.

Et Scala eksempel, som kan køres (er afprøvet):

[code=java]
case class Student(name:String,graduationYear:Int,gpa:Double)
val students = List(
Student("Anders",2009,3.4),
Student("Line",2009,4.5))
val THIS_YEAR = 2009
val bestGPA = students filter
{_.graduationYear == THIS_YEAR} map _.gpa reduceLeft
{(max,value) => if (value>max) value else max}
[/code]

Man kan håbe at Java folkene kommer til fornuft, og bruger navne som Scala. Så bliver Java eksemplet noget i stil med:

[code=java]
double bestGpa = students.filter(
{Student s => (s.graduationYear == THIS_YEAR) }).map(
{Student s => s.gpa }).reduceLeft(
{(int max, int value) => value > max ? value : max});
[/code]

Eller uden brug af ? operatøren, som mange Java programmører betragter som dårlig stil:

[code=java]
double bestGpa = students.filter(
{Student s => (s.graduationYear == THIS_YEAR) }).map(
{Student s => s.gpa }).reduceLeft(
{(int max, int value) =>
if (value > max) return value;
else return max;
});
[/code]

  • 0
  • 0
Baldur Norddahl

Jeg fristes til at spørge "og hvad så?". Ja det er sandt at man har læsset en masse special-karakterer og andet skrammel ind i sproget for at spare nogle linier, men det har i mine øjne flere ulemper end fordele:

Faktisk er den største forskel at SML, Haskel og Scala alle har type udledning. Det vil sige at man ikke behøver angive typer der hvor oversætteren selv kan udregne den korrekte type.

En anden væsentlig forskel er at alt er udtryk, som kan beregnes til en værdi. I Java kan man f.eks. ikke skrive "int x = if (y > 5) 10 else 1". I stedet har man en overflødig ? operator. Eller "List x = for(int i=0; i<10; i++) { i*2 }".

Jeg vil sige at i mange sammenhænge er Javas syntaks ikke så gennemtænkt som den kunne være. Man kan opnå de her ting uden at opfinde "flere" og i stedet bruge mere "generiske" konstruktioner. Det påstås at Scala har færre konstruktioner end Java.

  • 0
  • 0
Ulrik Skyt

Det er rart at kunne glæde sig til julegaverne når man kommer ind i julemåneden. Men jeg synes det er lidt skummelt at omtale noget som julegaver, når gaverne først falder i julen året efter...

  • 0
  • 0
Niki Nicolas Grigoriou

Tak for de mange eksempler på hvordan den samme kode kan skrives med mindst mulige anslag. Vi mangler stort set kun en Perl-version. Jeg synes, at eksemplerne illustreret problemet i introduktion af nye sprog-features ganske godt.

Java har som sprog efter min mening været kendetegnet ved at være simpelt, objektorienteret og meget stabilt. Allerede da Java kom frem blev det kritiseret for ikke have operator-overloading, generics og meget andet. Men fordelen var, at sproget var nemt at forstå og gennemskue.

Ovenstående kode-eksempler illustrerer ganske godt, at nye sprog-features kan spare tegn, men samtidig kan gøre kode sværere at læse og forstå. Hvilket jeg mener er en af de væsentligste kvalitet et sprog bør have.

Af samme grund er jeg ikke ubetinget begejstret for introduktionen af de nye features i Java 7. Men når det skal være, så er introduktion af closures, funktionstyper, konvertering af closures fra objekter med én enkelt metode gode tiltag. Introduktionen af extension methods ser jeg dog, som en ubehagelig overraskelse. Efter min mening en mis-feature i C#, som nu desværre også bliver introduceret i Java :-(

/Niki

  • 0
  • 0
Torben Mogensen Blogger

Kasper skrev:

Selve sproget bliver sværere at lære fordi der er flere konstruktioner. I stedet synes jeg det taler til Javas fordel at antallet af konstruktioner er relativt få - til gengæld er bibliotekerne store.

Jeg er ganske enig i, at man bør holde antallet af sprogkonstruktioner lavt, dog uden at overdrive. Som Einstein sagde: "Keep it as simple as possible, but no simpler". Men her er Java bestemt ikke nogen duks sammenlignet med f.eks. Standard ML eller Scheme. Der er masser af forskellige sprogkonstruktioner, der gør nogenlunde det samme. Som Baldur nævnte, har if()else og ?: konstruktionerne reelt den samme betydning, og for-løkken er blot en specialiseret udgave af while-løkken.
Endvidere er der masser af andre "forkortelser" såsom x+=e, ++x osv.

Det er noget andet når en ny konstruktion gør noget nyt, som kun besværligt kan gøres med de eksisterende konstruktioner. Når først sproget er Turingkomplet, så er ekstra konstruktioner i princippet overflødige, men hvis de gør visse ting meget nemmere eller understøtter programmeringsprincipper såsom [i]separation of concerns[/i], så kan det alligevel være en ide at inkludere dem. Man bør dog så overveje, om man ikke derefter kan fjerne nogle af de tidligere konstruktioner, hvis de viser sig at være instanser af den nye konstruktion. Det sker dog sjældent, da man dermed risikerer at eksisterende programmer skal skrives om. Det skete dog f.eks. ved definitionen af Standard ML 97, hvor de mere komplicerede imperative typer blev erstattet af den simplere [i]value polymorphism[/i] begrænsning.

Baldur skrev:

Jeg vil sige at i mange sammenhænge er Javas syntaks ikke så gennemtænkt som den kunne være.

Bjarne Stroustrup sagde engang, at han synes, at det var mærkeligt at Sun havde valgt C's horrible syntaks til Java, når det var et nyt sprog og ikke en udvidelse til C, sådan som C++ var det.

De fleste grimme ting i Javas syntaks kan føres direkte tilbage til C. Selv de senere udvidelser er søgt holdt i en stil, der ligner det oprindelige sprog, så det er begrænset, hvor meget det bliver forbedret.

  • 0
  • 0
Søren P

Da jeg begyndte med Java mange år tilbage blev jeg ret imponeret over at man turde være så ordrig i et OO sprog at man ligefrem skrev "extends" i stedet for at bruge mere kortfattede tegn og konstruktioner som ligner noget der skal læses af en maskine - det var trods alt normen dengang og er det også i dag.

Java har altid stået som værende et simpelt OO sprog for mig. Det passer godt til mig for jeg er kommet til den opfattelse at jeg selv kun er en gennemsnitlig programmør - der findes sprog som SML som jeg aldrig blev god til på trods af ihærdige studier.

Samtidigt får jeg også lov til at arbejde på projekter med meget store kode baser og her har jeg virkeligt lært at sætte pris på hvor simpelt Java sproget er når man skal overtage kode som har været gennem rigtigt mange programmørers hænder.

Jeg ser stadig Java som et simpelt OO sprog på trods af at der løbende kommer flere koncepter til men jeg har på den anden side også haft tid til at vokse sammen med Java. Hvordan vil en ny programmør se på Java med alle de koncepter der er i Java ala version 7? Jeg tror det er mere tænkeligt at Java kan dø rent udbredelsesmæssigt fordi nye udviklerer ser det som alt for kompliceret. Man ser jo i forvejen frem til pænt mange års studier hvis man vil være habil inden for JavaEEs mest mainstream api'er, frameworks, servere, tools osv ..

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