mboost-dp1

Sun

Kritik af implementation af closures i Java

- Via Version2 - , redigeret af Net_Srak , indsendt af arne_v

I december sidste år blev det klart, at Java version 7 vil implementere closures, og i den forbindelse oplyste Mark Reinhold, at man hos Sun (Oracle) ikke ville vælge et af de tre forslag til implementation, der var fremme, men udvikle en ny.

Det er nu blevet til, at closures skal benyttes i Java via den såkaldte “Strawman-syntaks”, der er ifølge Version2 er valgt på baggrund af et kommende parallelisme-bibliotek, idet operationer så kan afvikles på flere processorkerner samtidig.

Valget er dog allerede kommet under kritik, blandt andet fra danske David Heinemeier Hansson, der opfandt Rails, som mener, syntaksen er alt for støjfyldt.

Kritikken følger i kølvandet på de mange års debat, der har været hidtil, om hvordan closures bør implementeres i Java.





Gå til bund
Gravatar #1 - Windcape
22. jun. 2010 07:11
Det var da godt nok en afskyelig syntaks. Hvorfor er det at JCP ikke bare har valgt at dublikere C#?

Det virker så latterligt at man vælger sådan en dårlig syntaks, fuld af støj, og strong-typed argumenter, som slet ikke burde være nødvendige, da man allerede ved hvad typerne skal være.

Kritikken følger i kølvandet på de mange års debat, der har været hidtil, om hvordan closures bør implementeres i Java.
Og om Java overhovedet skulle have closures, fordi visse personligheder foretrak det som et purt sprog, og mente at flere features gjorde sproget dårligere.

Fjolser, alle sammen.

Hvis man ikke kan se pointen med closures og lambda, så må det være fordi man ikke forstår dem, eller aldrig har brugt dem.

Det giver så meget mere elegant kode, som er nemmere at forstå, maintaine, og har færre chancer for fejl.
Gravatar #2 - Windcape
22. jun. 2010 07:16
Er der forresten nogen som ved om Java 7 så får et yield[1] statement?

Ellers bliver det meget klodset at skulle implementere sine egne extensions med en lambda selector, og retunere en brugbar iterator.

[1] http://msdn.microsoft.com/en-us/library/9k7k7cf0(VS.80).aspx
Gravatar #3 - onepixel
22. jun. 2010 07:25
Jeg har kun ét ord til jer: Scala

http://www.scala-lang.org/

Scala er til dem, som ikke gider skrive kode som:

ArrayList<String> lst = new ArrayList<String>();

Det er lidt ligesom at høre en Rasmus Seebach sang...
Gravatar #4 - onetreehell
22. jun. 2010 07:28
Windcape (1) skrev:
Det var da godt nok en afskyelig syntaks. Hvorfor er det at JCP ikke bare har valgt at duplikere C#?

Det siger du jo altid når nogen snakker om java...

Jeg synes det ser fornuftigt nok ud, men jeg har ikke kigget nærmere på de mere komplicerede udtryk...
  class CountingSorter {
/* @Shared ? */ int count = 0;
void sort(List<String> data) {
// Field 'count' is in scope, so the lambda expression may use it
Collections.sort(data,
#(String a, String b) { CountingSorter.this.count++; return a.length()-b.length(); });
}
}


Hvis folk gerne vil udenom version2
Gravatar #5 - Faergemeister
22. jun. 2010 08:09
Og hvem er det der har så meget jord i hovedet at de tager David Heinemeier Hansson seriøst at any rate? Hans meninger kan jo kortes ned til smuk kode >>>>>> performance.
Gravatar #6 - cryo
22. jun. 2010 08:13
Windcape (1) skrev:
Det virker så latterligt at man vælger sådan en dårlig syntaks, fuld af støj, og strong-typed argumenter, som slet ikke burde være nødvendige, da man allerede ved hvad typerne skal være.


Nu er det ikke alle som synes fuldt infererede typer er fedt i modsætning til manifest (ikke "strong-typed") typning. Men i C# kan du så i det mindste selv vælge.

Windcape (1) skrev:
Fjolser, alle sammen.

Hvis man ikke kan se pointen med closures og lambda, så må det være fordi man ikke forstår dem, eller aldrig har brugt dem.

Det giver så meget mere elegant kode, som er nemmere at forstå, maintaine, og har færre chancer for fejl.


Det må så være din mening; jeg tror der er mange der ikke er enige i det (omend jeg selv er), så at kalde dem for fjolser er måske lidt i overkanten. Det er ikke alle der kan lide at blande forskellige paradigmer i samme sprog.
Gravatar #7 - Windcape
22. jun. 2010 08:15
onetreehell (4) skrev:
Det siger du jo altid når nogen snakker om java...
Måske fordi det faktisk ret tit giver mening?

Men Haskell eller Scala er også et bud, men nu er C#s fordel jo bare at det minder meget om Java, og er strong-typed, så det ville netop give mening.

onetreehell (4) skrev:
Jeg synes det ser fornuftigt nok ud, men jeg har ikke kigget nærmere på de mere komplicerede udtryk..
Din kode kan skrives så simpelt her i C#:


int count = 0;
var sorted = data.OrderBy(x => { count++; return x.Length; })


Og så har du performance fordelene af at du faktisk får en iterator tilbage, samt ikke modificere dit nuværende dataset.

Begge dele er mere typisk for funktionel programmering, og sikre bedre og mindre fejlfyldt kode.
Gravatar #8 - Windcape
22. jun. 2010 08:17
cryo (6) skrev:
Det er ikke alle der kan lide at blande forskellige paradigmer i samme sprog.
Hvilket sprog er ikke multi-paradigm i dag?
Gravatar #9 - mathiass
22. jun. 2010 08:38
Windcape (1) skrev:
Det var da godt nok en afskyelig syntaks. Hvorfor er det at JCP ikke bare har valgt at dublikere C#?
Det virker så latterligt at man vælger sådan en dårlig syntaks, fuld af støj, og strong-typed argumenter, som slet ikke burde være nødvendige, da man allerede ved hvad typerne skal være.
Mit bud er at det er fordi typer er en noget mere kompliceret størrelse i Java i forhold til C# på grund af de noget mere udtryksfulde generics. I Java kan generiske argumenttyper være infereret, mens de i C# ligger fast givet objektets type. Det vil sige at man ikke har en konkret type at tildele funktionen på samme måde som i C#. Hurtigt Java 5 eksempel (uden lambda):


E <E> m(E a1, E a2) {
...
}

...
String s;
Integer i;
m(s,i); //<-- Her skal typen for E infereres ud fra String og Integer

Typen af E bliver noget i retningen af [m = Comparable<m> & Serializable], altså en rekursiv type for returværdien.

Jeg ved ikke hvordan man kunne bygge det sammen med de infererede funktionstyper, som du foreslår, men jeg kan garantere at det ikke er trivielt at løfte den nuværende inferens til at omfatte funktioner.
Gravatar #10 - Windcape
22. jun. 2010 08:46
#9

Men compileren kan jo godt håndtere metode overloads, så det virker jo lidt underligt?

I dit eksempel burde følgende virke:


m.<String>("foo", "bar");
m.<Integer>(42, 1337);


Hvor at tilsvarende i C# er det ikke nødvendigt med type-angivelse på metoderne.

Men hvis det var overloads, ville det jo virke, det er lidt underligt.
Gravatar #11 - mathiass
22. jun. 2010 08:52
Windcape (10) skrev:
Men compileren kan jo godt håndtere metode overloads, så det virker jo lidt underligt?
Hmm, det har ikke så meget med overloads at gøre.

Windcape (10) skrev:
I dit eksempel burde følgende virke:

Ja, det gør det bestemt også, men

m("foo", 42)

virker også. Og det virker også uden at du skal fortælle compileren explicit hvad E er. Det infereres fra typen af de konkrete argumenter.

Jeg mener bare at hvis du også skal til at inferere hvad typen af de konkrete argumenter er, så bliver det lidt indviklet. Hvis man så fylder inferens af funktionstyper ind over også, så tror jeg at man har nået en kompleksitet på type-inferensen som man gerne vil undgå.
Gravatar #12 - Windcape
22. jun. 2010 08:54
mathiass (11) skrev:
virker også.
Hvordan kan det virke at give 2 forskellige typer, når begge parameter skal have samme type?

Jeg vidste godt generics i Java var dårligt implementeret, men så dårligt?
Gravatar #13 - T-Hawk
22. jun. 2010 09:01
Windcape (12) skrev:
Hvordan kan det virke at give 2 forskellige typer, når begge parameter skal have samme type?

Fordi både String og Integer extender Comparable<E>, og derfor kan anses som samme type.

Hvilket mathiass også skrev:
mathiass (9) skrev:
Typen af E bliver noget i retningen af [m = Comparable<m> & Serializable], altså en rekursiv type for returværdien.

Gravatar #14 - mathiass
22. jun. 2010 09:01
Windcape (12) skrev:
Hvordan kan det virke at give 2 forskellige typer, når begge parameter skal have samme type?

Det har de da også! De har faktisk flere fælles typer. Blandt andet har de begge to typen Objekt, men som skrevet i #9, så har de altså også en mere præcis type, som dog er rekursiv.

Windcape (12) skrev:
Jeg vidste godt generics i Java var dårligt implementeret, men så dårligt?

Det er bestemt ikke dårligt implementeret. Det kan bare mere end C#. Mit eksempel type-checker kun, hvis body af metoden virker for enhver tildeling af konkret type for E, så der er ingenting galt med type-systemet som sådan. Jeg er også overbevist om at det godt kan lade sig gøre at tilføje funktionstyper (uden sub-type relation) til det, men prisen for det som du kalder lidt pænere syntax vil skulle betales med at mange programmører nok vil have svært ved at forstå hvad der foregår når de ikke skriver typen.
Gravatar #15 - Windcape
22. jun. 2010 09:06
#14

Men i C# skulle det gøres ved hjælp af en constraint.


T m<T>(T a1, T a2)
where T : IComparable


eller bedre


T m<T>(T a1, T a2)
where T : IComparable<T>


Hvor vi her sikre at vi faktisk kan sammenligne de 2 typer.

Det kan dog også gøres ved at angive det direkte:


m<IComparable>("foo", 42);


mathiass (14) skrev:
men prisen for det som du kalder lidt pænere syntax vil skulle betales med at mange programmører nok vil have svært ved at forstå hvad der foregår når de ikke skriver typen.
Det fungere da ellers fint for samtlige andre sprog der har lambda understøttelse.

Java bliver det første hvor man altid skal angive typer på alting.
Gravatar #16 - mathiass
22. jun. 2010 09:13
#15: Nej, det er ikke det samme. Hvis du skriver sådan, så lægger du dig fast på at typen skal extende IComparable. Det gør jeg ikke i mit Java eksempel, det viser sig bare at være tilfældet i den kaldende kode. Dit C# eksempel ser sådan ud i Java:

T <T extends Comparable<T>> m(T a1, T a2) {
...
}

I Java vil T også i dette tilfælde blive infereret til den mest præcise type i den kaldende kode, så for et konkret kald til m vil typen af T være mere præcis end at den bare extender Comparable<T>.
Gravatar #17 - Windcape
22. jun. 2010 09:20
#16

Men jeg kan stadigvæk ikke se hvorfor man skal angive typer, til f.eks. eksemplet fra #4


void Sort(List<String> data) {
final int count = 0;
Collections.sort(data, #(String a, String b) {
count++;
return a.length() - b.length();
});
}


Fordi her ved vi jo allerede at typen af a og b vil være String, og så burde det jo ikke være nødvendigt at type-angive.
Gravatar #18 - mathiass
22. jun. 2010 09:25
#17: Selvfølgelig kan du altid finde special-cases hvor typen er åbenlys at inferere, men hvis du ikke behandler det generelle tilfælde, så vil sproget have en type-inferens som kan fejle i nogle tilfælde, så du selv skal skrive en korrekt type. Det er altså noget bras.
Gravatar #19 - Windcape
22. jun. 2010 09:28
#18

Det virker da ellers altid perfekt i C#. Og haskell, og Scala, og F#, og ML, og og og...

Gravatar #20 - mathiass
22. jun. 2010 09:29
Det fungere da ellers fint for samtlige andre sprog der har lambda understøttelse.
Java bliver det første hvor man altid skal angive typer på alting.
Jeg siger egentlig heller ikke at jeg er imod det. Jeg siger bare at jeg ikke lige kan se hvordan det kan laves på en fornuftig måde, og det tror jeg faktisk heller ikke at du kan.
Gravatar #21 - Windcape
22. jun. 2010 09:30
#20

Dvs. du mener ikke Microsoft har gjort det fornuftigt i C#, eller mener du at det ikke er muligt i Java uden at omskrive hele deres implementing af Generics?
Gravatar #22 - mathiass
22. jun. 2010 09:32
Jeg vil påstå at alle de funktionelle sprog som du nævner har en kompleksitet i deres type-inferens som ville være meget uheldig at indføre i et sprog som Java. Det er også sprog der type-mæssigt er fundamentalt forskellige fra Java på rigtig mange måde.
Det eneste som giver mening at sammenligne med er C# og min indvending er også bare at generiske typer er meget mere komplicerede i Java end i C# og derfor lader den løsning sig ikke bare overføre.
Gravatar #23 - mathiass
22. jun. 2010 09:35
#21: Nej, jeg tror ikke rigtigt at du forstår hvad jeg skriver. Jeg forstår ikke rigtig hvorfor du taler om implementation. Der er tale om to forskellige generics koncepter. Microsoft har lavet en fin løsning i C#, men den lader sig ikke umiddelbart overføre, som jeg ser det.
Jeg mener bestemt ikke at Java's generics skal laves om.
Gravatar #24 - Windcape
22. jun. 2010 09:38
#23

Rent teoretisk kan de jo have nok så fine koncepter, men pragmatisk set gør de det samme.

Jeg har aldrig oplevet noget specielt ved Java's generics, udover at det er et hack oven på sproget, så der mangler en helt masse features.

Hvad er argumentet for ikke at gøre det ligesom i C#? Jeg kan virkelig ikke se det.

Derudover kommer checked exceptions til at se virkelig virkelig grimt ud i closures. Det virker somon at JCP bare har besluttet sig for at de skulle have disse her features, og slet ikke tænkt ind hvordan man designer det bedst ind i selve syntaksen og sproget.

Ligesom man gjorde med generics (type-boxing sucks!)
Gravatar #25 - mathiass
22. jun. 2010 09:46
Windcape (24) skrev:
Rent teoretisk kan de jo have nok så fine koncepter, men pragmatisk set gør de det samme.
Hmm, nej de gør ej. To ret store forskelle er manglen på runtime information i Java og på wildcards i C#. Det sidste definerer et subtype-forhold i Javas generics, som gør det noget mere udtryksfuldt end C#.

Min holdning til checked exceptions er at det fundamentalt set var en dårlig ide. Men nu har vi det, og så må nye features også virke med det. Man kan jo lade være med at bruge det.
Gravatar #26 - Windcape
22. jun. 2010 09:48
mathiass (25) skrev:
wildcards i C#.
dynamic?


var data = new List<dynamic>();
data.Add("foo");
data.Add(42);
data.Add("bar");

var strings = data.OfType<string>();


Til resten er der generic type-constraints.
Gravatar #27 - Ildhesten
22. jun. 2010 09:51
#24 At generics er et hack oven på sproget vil jeg meget gerne høre belæg for. Så vidt jeg husker var der noget rimeligt seriøst forskningsarbejde involveret, for at finde en fornuftig løsning.
Gravatar #28 - ksb
22. jun. 2010 09:54
#24

Der hvor det hele står og falder i denne diskussion er jo at C#'s generics ikke er lige så udtryksfulde som javas.
Om du som individ nogensinde har haft brug for dette skal jeg ikke kunne udtale mig om, jeg ved at jeg personligt aldrig har(men har haft implementeret en delmængde af en Javakompiler i Java og har i den forbindelse læst op på generics i mange flere detaljer end noget menneske nogensinde burde tvinges til!)
Som sådan kan man (som tidligere udtalt) på nuværende tidspunkt i Java "overlade mere til compiler/runtime" end man kan i C#.

At du så syntes det havde været bedre at Java havde implementeret på samme måde som C# er så hvad det er. Personligt er jeg glad for at verden ikke er generisk :-D
Gravatar #29 - Windcape
22. jun. 2010 09:59
ksb (28) skrev:
Som sådan kan man (som tidligere udtalt) på nuværende tidspunkt i Java "overlade mere til compiler/runtime"
Og så alligevel ikke når det kommer til closures og lambda :p

Et tegn på at deres løsning ikke er særlig god!
Gravatar #30 - krainert
22. jun. 2010 10:02
@Arne: Hvad er din egen mening?

#27: Vi kan vist hurtigt blive enige om, at den praktiske implementation af generics i Java er fejlbarlig, men arbejdsbyrden i fuldstændigt at omskrive JVM (eller hvad ellers måtte være nødvendigt for at opnå den ideelle understøttelse) er formentligt for stor til at vurderes ønskelig at gennemføre.

Ærligt talt ved jeg snart ikke, hvad jeg selv skal sige... Jeg kan ikke se, hvordan closures er kompatibelt med OOP i sin reneste form (som Java nu engang forsøger at lægge sig op ad), men der må siges at være gode argumenter for deres indførsel alligevel. Dog kan jeg, som mange andre herinde, overhovedet ikke forstå, hvorfor vi er endt med netop Straw-Man, for den virker da yderst gyselig. Så vidt jeg kan se, er forslaget her:
http://mail.openjdk.java.net/pipermail/lambda-dev/...
EDIT: Ignorer linket; det fremgår også af kildeartiklen.

Kender nogen årsagen til valget?
Gravatar #31 - mathiass
22. jun. 2010 10:13
Windcape (26) skrev:
dynamic?

Øh, nej. dynamic er mangel på en type og tilhørende mangel på typecheck. Det har intet med wildcards at gøre.
Gravatar #32 - Windcape
22. jun. 2010 10:14
krainert (30) skrev:
Jeg kan ikke se, hvordan closures er kompatibelt med OOP i sin reneste form
Det er de vel heller ikke. Det er for at få mere funktionel programmering ind i et allerede multi-paradigm sprog.

krainert (30) skrev:
som Java nu engang forsøger at lægge sig op ad
Forsøgte. Det er vist endeligt ved at komme videre.

Det giver slet ikke mening at tvinge folk til at skrive kode som:


List<User> adults = new List<User>();
for (User user : users)
{
if (user.getAge() > 18) { adults.Add(user); }
}


I stedet for


var adults = users.Where(user => user.Age > 18);


Både fordi at det sidste er mere clean-code, men også fordi det er bedre performance.
Gravatar #33 - Windcape
22. jun. 2010 10:15
mathiass (31) skrev:
Windcape (26) skrev:
dynamic?

Øh, nej. dynamic er mangel på en type og tilhørende mangel på typecheck. Det har intet med wildcards at gøre.
Hvis jeg kigger på http://java.sun.com/docs/books/tutorial/extra/gene...

Så kan jeg ikke se noget jeg ikke kan i C# 4.0

Kan du præcisere hvad du mener?
Gravatar #34 - mathiass
22. jun. 2010 10:16
Windcape (29) skrev:
Og så alligevel ikke når det kommer til closures og lambda :p
Jo, hvis det kan lade sig gøre på en meningsfuld måde i forhold til resten af sproget. Det er lidt svært at tage stilling til en løsning som ikke findes.
Gravatar #35 - Ildhesten
22. jun. 2010 10:16
#30 Så vidt jeg husker laver compileren type erasure sådan at JVM'en ikke skal bekymre sig om generics. Så det argument holder vist ikke.
Gravatar #36 - mathiass
22. jun. 2010 10:18
Windcape (33) skrev:
mathiass (31) skrev:
Windcape (26) skrev:
dynamic?

Øh, nej. dynamic er mangel på en type og tilhørende mangel på typecheck. Det har intet med wildcards at gøre.
Hvis jeg kigger på http://java.sun.com/docs/books/tutorial/extra/gene...

Så kan jeg ikke se noget jeg ikke kan i C# 4.0

Kan du præcisere hvad du mener?
Jeg mener at dynamic ikke er en type i almindelig forstand, fordi 1)den bliver ikke checket af type-checkeren og 2)der er ingen garanti for at brugen af den ikke resulterer i en typefejl på runtime. Den adskiller sig i øvrigt fra wildcards på begge måder.
Gravatar #37 - mathiass
22. jun. 2010 10:20
Ildhesten (35) skrev:
#30 Så vidt jeg husker laver compileren type erasure sådan at JVM'en ikke skal bekymre sig om generics. Så det argument holder vist ikke
Det er ikke så relevant i forhold til Java sproget. Lambda'er vil også blive omskrevet til (formodentlig) en "anonym" klasse i byte code og køre som sådan på JVM'en.
Gravatar #38 - mathiass
22. jun. 2010 10:21
men også fordi det er bedre performance.
Hvorfor skulle lambda-funktioner i sig selv dog give bedre performance end en for-løkke?
Gravatar #39 - Windcape
22. jun. 2010 10:22
mathiass (36) skrev:
Den adskiller sig i øvrigt fra wildcards på begge måder.
Jeg vil gerne have du forklare hvad du mener Wildcards er så.

Fordi sådan som jeg læser det, er det det samme som at bruge object eller dynamic som type.

Derudover så ved compileren godt hvilken type et dynamisk variabel har.

dynamic test = "foo";
typeof(test) // System.String
test = 42;
typeof(test) // System.Int32
Gravatar #40 - Windcape
22. jun. 2010 10:23
mathiass (38) skrev:
Hvorfor skulle lambda-funktioner i sig selv dog give bedre performance end en for-løkke?
Fordi det retunere en iterator, så det er først når du bruger det aktuelle resultat at der bliver selected data.

Men det er så også fordi at C# har rigtige iterators. Det har Java ikke.
Gravatar #41 - mathiass
22. jun. 2010 10:30
Windcape (39) skrev:
Derudover så ved compileren godt hvilken type et dynamisk variabel har.

dynamic test = "foo";
typeof(test) // System.String
test = 42;
typeof(test) // System.Int32
Nej, det gør compileren bestemt ikke. typeof gør at runtime systemet giver dig den dynamiske type på runtime.
Gravatar #42 - mathiass
22. jun. 2010 10:33
#40: Jeg synes ikke at vi skal åbne en diskussion mere, men det giver altså ikke bedre performance at lave arbejdet på et andet tidspunkt, og det har slet ikke noget med lambda-udtryk at gøre ud over at det LINQ library som du tale om benytter sig af lambda-utryk i sit interface.
Gravatar #43 - mathiass
22. jun. 2010 10:40
Windcape (39) skrev:
Jeg vil gerne have du forklare hvad du mener Wildcards er så.
Du har selv linket til en fremragende ressource som fortæller om wildcards, så jeg synes at du skal prøve at læse den. Jeg kan give dig et par eksempler på forskellen på ? og Object.

Følgende type checker:

Collection<?> c = new ArrayList<String>();


Dette gør ikke:

Collection<Object> c = new ArrayList<String>();

Og heller ikke:

Collection<?> c = new ArrayList<String>();
c.add(new Object());



Prøv at sammenligne med add-metoden på Collection som tager noget af den generiske type og tænk over hvorfor den er type-sikker med wildcards.

Forskellen på dynamic og ? kan nok bedst beskrives ved at dynamic ikke type-checkes overhovedet mens ? behandles som ukendt på en sikker måde af compileren.

Man kan desuden lave bounds (? extends C) på wildcards, så compileren behandler typen som noget ukendt som man dog ved extender C. Der er et par gode eksempler på anvendelse af det på siden, som du har linket til.
Gravatar #44 - krainert
22. jun. 2010 10:40
Tak - så må jeg byde closures velkommen.
Det gør dog ikke syntaksen bedre!
Gravatar #45 - Windcape
22. jun. 2010 10:47
mathiass (43) skrev:
Der er et par gode eksempler på anvendelse af det på siden, som du har linket til.
Men deres eksempler er identiske til ting jeg kan lave i C#.

Så jeg kan stadigvæk ikke se pointen? Wildcards giver jo ingen fordele overhovedet.
Gravatar #46 - mathiass
22. jun. 2010 10:53
#45: Som jeg forstår dynamic, så vil følgende eksempel skrivet med dynamic type-checke i C# på trods af at det ikke er type-sikkert:

Collection<?> c = new ArrayList<String>();
c.add(new Object());

Korrekt?
Gravatar #47 - Windcape
22. jun. 2010 13:46
Altså du kan også skrive det sådan her:


ICollection<object> c = new List<string>();


Men jeg forstår stadigvæk ikke hvad du får ud af det?
Gravatar #48 - mathiass
22. jun. 2010 14:06
#47: Kan man det? Så jeg kan skrive:

List<string> stringlist = new List<string>();
List<object> objectlist = stringlist;

Og dermed tilføje ting af en hvilken som helst (inkompatibel) type til min stringlist gennem objectlist referencen?

Jeg har ikke lige en C# compiler tilgængelig her, men det lyder ikke særlig smart, hvis det passer. Wildcards er lige præcis en type-sikker måde at håndtere subtyping for generics får den slags typefejl på runtime.
Gravatar #49 - Windcape
22. jun. 2010 14:18
#48

Jeg checkede lige, og nej, det kan ikke gøres implicit fra object til string.

mathiass (48) skrev:
Wildcards er lige præcis en type-sikker måde at håndtere subtyping for generics får den slags typefejl på runtime.
Men hvorfor vil du overhovedet tilbyde muligheden?

Jeg forstår virkelig ikke ideen med at tillade at man tilføjer sådanne typer. Wildcards virker jo totalt meningsløse, og bare er et eksempel på hvordan Java's generics faktisk bare er dumt box-in / box-out af typer.
Gravatar #50 - Ildhesten
22. jun. 2010 15:07
#49 Motivation for wildcards kan du læse om her: (Link til pdf)
Gå til top

Opret dig som bruger i dag

Det er gratis, og du binder dig ikke til noget.

Når du er oprettet som bruger, får du adgang til en lang række af sidens andre muligheder, såsom at udforme siden efter eget ønske og deltage i diskussionerne.

Opret Bruger Login