[JAVA] operator overloading gefaked?

Pagina: 1
Acties:
  • 168 views sinds 30-01-2008
  • Reageer

  • drm
  • Registratie: Februari 2001
  • Laatst online: 09-06-2025

drm

f0pc0dert

Topicstarter
Tijdje geleden alweer, dus ik dacht, ik open maar weer eens een onzinnig topic :)

Nee, er zit me een vraagje dwars, waar ik een jaartje of 2 geleden mee zat toen ik een beetje met Java begon te freubelen.

Ik ben altijd best wel geinteresseerd geweest in de de diepere structuren van talen: hoe zitten ze feitelijk in elkaar, waar komen die structuren vandaan, hoe werkt een compiler, etc. Dat is puur hobbymatig, en ik weet er bar weinig vanaf, maar ik vind het wel mateloos interessant.

De vraag is: Hoe kan het dat wanneer je een instantie maakt van een String, je deze met een andere instantie kan concatenaten doormiddel van een plus-teken, terwijl Java geen operator overloading kent :?

als ik onzin klets, moet je het uiteraard ook zeggen (heb alweer een jaar geen Java aangeraakt), maar ik was benieuwd of 1 van de java-cracks mij een beetje kon "enlightenen" :)

Music is the pleasure the human mind experiences from counting without being aware that it is counting
~ Gottfried Leibniz


  • RickN
  • Registratie: December 2001
  • Laatst online: 14-06-2025
Lijkt mij dat dit statische operator overloading is, die gewoon deel uitmaakt van de taaldefinitie. Dat is heel wat anders dan dat je zelf dynamisch een nieuwe functie voor je operator kunt defineren. Die statische overloading zou ik zelfs niet eens overloading noemen, dat je met de * operator zowel twee ints als twee reals kunt vermenigvuldigen is toch ook geen overloading, dat is gewoon statische in de compiler zo gedefineerd. De compiler weet gewoon al dat ie bij een + zowel een getal (van meerdere types) als een string kan verwachten.

Ik ben overigens bepaald geen Java-crack, ik weet niet eens OF het waar is wat je zegt over geen overloading in Java. Maar daar heeft de vraag m.i. ook niet zoveel mee te maken.

He who knows only his own side of the case knows little of that.


  • Rhythmic
  • Registratie: Februari 2000
  • Laatst online: 07-10-2025
Heel simpel: dat is zo gedefinieerd in de taal. Als je het allemaal precies wilt weten kan je de Java Language Specification wel eens door gaan spitten :Y. Het stukje over de + operator voor Strings vind je hier.

  • drm
  • Registratie: Februari 2001
  • Laatst online: 09-06-2025

drm

f0pc0dert

Topicstarter
Eenvoudig antwoord, maar dat vind ik slordig.

String is een object, wat in feite geschreven kan worden in Java zelf. Dat zal ook soort van gebeurd zijn (het is geen primitive). Waarom word er dan in dat object een mogelijkheid gecreeerd die voor alle andere classes uitgesloten is?

maw, waarom gelden er voor een "standard class" andere regels dan voor andere classes :?

[edit:klein toevoeginkje]

Music is the pleasure the human mind experiences from counting without being aware that it is counting
~ Gottfried Leibniz


  • RickN
  • Registratie: December 2001
  • Laatst online: 14-06-2025
Op donderdag 03 januari 2002 16:01 schreef drm het volgende:
Eenvoudig antwoord, maar dat vind ik slordig.

String is een object, wat in feite geschreven kan worden in Java zelf. Dat zal ook soort van gebeurd zijn (het is geen primitive). Waarom word er dan in dat object een mogelijkheid gecreeerd die voor alle andere classes uitgesloten is?

maw, waarom gelden er voor een "standard class" andere regels dan voor andere classes :?

[edit:klein toevoeginkje]
Tja, da's een keuze hè. Als je een programmeur operator overloading biedt geeft je em een extra mogelijkheid in handen om onduidelijke code te schrijven, terwijl te constructie niet echt iets toevoegt. Concatenatie van strings weergeven met een + vind ik intuïtief duidelijk, maar als een of andere sukkel allerlei vage semantieken aan zijn + gaat toekennen wordt zijn code daar m.i. niet leesbaarder op, terwijl hij het ook gewoon met een procedure zou kunnen oplossen. Operators zijn geen procedures, programmeurs moeten er met hun handen afblijven als je het mij vraagt.

He who knows only his own side of the case knows little of that.


  • drm
  • Registratie: Februari 2001
  • Laatst online: 09-06-2025

drm

f0pc0dert

Topicstarter
Op donderdag 03 januari 2002 16:11 schreef RickN het volgende:

[..]

Tja, da's een keuze hè. Als je een programmeur operator overloading biedt geeft je em een extra mogelijkheid in handen om onduidelijke code te schrijven, terwijl te constructie niet echt iets toevoegt. Concatenatie van strings weergeven met een + vind ik intuïtief duidelijk, maar als een of andere sukkel allerlei vage semantieken aan zijn + gaat toekennen wordt zijn code daar m.i. niet leesbaarder op, terwijl hij het ook gewoon met een procedure zou kunnen oplossen. Operators zijn geen procedures, programmeurs moeten er met hun handen afblijven als je het mij vraagt.
Ja dat is natuurlijk een keuze, maar ik vind bijvoorbeeld het optellen van 2 complexe getallen (schoolvoorbeeld :z) ook intuitief duidelijk. Maar dat is verder de verantwoordelijkheid van de programmeur (lees:coder). Als ik vage constructies ga bedenken die niet leesbaar zijn dan hoeft de programmeertaal-ontwerper daar toch geen rekening mee gaan te houden, en het mij bijvoorbeeld niet toestaan om een vijfvoudig geneste .. ? .. : .. expressie te gaan gebruiken (ik geef maar een dom voorbeeld) :?

Music is the pleasure the human mind experiences from counting without being aware that it is counting
~ Gottfried Leibniz


  • mbravenboer
  • Registratie: Januari 2000
  • Laatst online: 06-11-2025
De String optelling is inderdaad een soort operator overloading, maar dan wel keihard in de taal ingebakken. Door de compiler wordt dit gewoon gedesugared naar een optelling met StringBuffers. In Java bytecode wordt dus niet de + operator op Strings toegepast.

Zie de API docs:
The Java language provides special support for the string concatentation operator ( + ), and for conversion of other objects to strings. String concatenation is implemented through the StringBuffer class and its append method. String conversions are implemented through the method toString, defined by Object and inherited by all classes in Java. For additional information on string concatenation and conversion, see Gosling, Joy, and Steele, The Java Language Specification.
De implementatie van operator overloading van de + is dus uitermate ad-hoc. Je kunt het vergelijken met de overloading van de +,/,* die in veel talen is ingebouwd voor float, double en integer optelling.

De implementatie van deze optelling is verschillend voor al deze typen. De compiler vervangt de operator door de echte implementatie. In dit geval dus een concat mbv StringBuffers :) .
maw, waarom gelden er voor een "standard class" andere regels dan voor andere classes :?
Het geldt niet zozeer voor een klasse: er is gewoon geen operator overloading in de taal Java. De + operator is volgens de Java Language Specification te gebruiken voor optelling van Strings. Dat je deze + ook gebruikt voor integers, floats en doubles is 'toeval'. ;)

Als je operator overloading voor alle klassen zou willen implementeren moet je daar een aparte syntax voor hebben zoals bijvoorbeeld in C# :) .

Blog, Stratego/XT: Program Transformation, SDF: Syntax Definition, Nix: Software Deployment


  • drm
  • Registratie: Februari 2001
  • Laatst online: 09-06-2025

drm

f0pc0dert

Topicstarter
mbravenboer paste weer eens het idee "desugaren" toe
Ja ok, zit wat in... Maar je begrijpt waarom ik zo'n grijs vlak een beetje dubieus vind? String is geen primitive, dat vind ik het "inconsequente" er aan.

Music is the pleasure the human mind experiences from counting without being aware that it is counting
~ Gottfried Leibniz


  • RickN
  • Registratie: December 2001
  • Laatst online: 14-06-2025
Op donderdag 03 januari 2002 16:17 schreef drm het volgende:

[..]

Ja dat is natuurlijk een keuze, maar ik vind bijvoorbeeld het optellen van 2 complexe getallen (schoolvoorbeeld :z) ook intuitief duidelijk.
Idd, had wat mij betreft ook best in java mogen zitten. :)
Maar dat is verder de verantwoordelijkheid van de programmeur (lees:coder). Als ik vage constructies ga bedenken die niet leesbaar zijn dan hoeft de programmeertaal-ontwerper daar toch geen rekening mee gaan te houden, en het mij bijvoorbeeld niet toestaan om een vijfvoudig geneste .. ? .. : .. expressie te gaan gebruiken (ik geef maar een dom voorbeeld) :?
Daar ben ik het dus helemaal niet mee eens. Ik vind het juist van cruciaal belang dat men bij het ontwerpen van een taal heel goed kijkt naar hoe er later in geprogrammeerd gaat worden. Als men door een taal op een bepaalde manier te ontwerpen programmeurs voor allerlei fouten kan behoeden is dat toch prachtig??? Een programmeertaal is niet slechts een verzameling taalconstructies met een compiler erachter die er mooi bytejes van maakt. Waarom willen programmeurs toch altijd 10 verschillende manieren om hetzelfde te kunnen zeggen? Door het toevoegen van een nieuwe manier om iets te kunnen zeggen kun je nooit beter gaan programmeren, alleen maar even goed of slechter.

He who knows only his own side of the case knows little of that.


  • Rhythmic
  • Registratie: Februari 2000
  • Laatst online: 07-10-2025
Ik ben het wel met RickN eens: operator overloading kan tot hele vage code leiden omdat je de semantiek van de taal kan veranderen. Een goede reden om dat uit te sluiten dus. Waarom de bedenker van Java in al zijn wijsheid besloten heeft alleen Strings apart te behandelen weet ik ook niet, al is het wel logisch. In bijna ieder programma gebruik je wel Strings, terwijl het gebruik van andere objecten in het algemeen wat minder gebruikelijk is. Een alternatief was geweest om overal StringBuffers voor te gebruiken, maar of dat nou handiger zou werken...









Uiteraard ligt er altijd een grote verantwoordelijkheid bij de programmeur om heldere code op te leveren. Als de taal dan heldere constructies aanbied is dat alleen maar mooi meegenomen. Wat dat betreft had de ..?..:.. constructie ook wel weggelaten kunnen worden uit Java, al die vaak toch wel makkelijk... :P

edit: m'n smiley werkte niet! :(

  • Orphix
  • Registratie: Februari 2000
  • Niet online
Nou ik vind operator overloading in geval van bv matrices erg handig. Bovendien is een operator overloading niet dusdanig makkelijk te maken dat het vaak 'fout' wordt gebruikt. Ik ben nog maar weinig voorbeelden tegengekomen waarbij het er _niet_ duidelijker op wordt.

  • mbravenboer
  • Registratie: Januari 2000
  • Laatst online: 06-11-2025
drm: Ja ok, zit wat in... Maar je begrijpt waarom ik zo'n grijs vlak een beetje dubieus vind? String is geen primitive, dat vind ik het "inconsequente" er aan.
Ach tja, je kan het dubieus vinden, maar dan moet je de overloading van + voor double, float en integer optelling eigenlijk ook dubieus vinden :) . Ik durf te wedden dat je die niet kwijt wilt. Dus waarom dan niet voor Strings? Strings zijn niet zomaar een standaard klasse, ze zijn wel degelijk onderdeel van de Java Language Specification (zie blz 41). Het zijn dan wel geen primitieven, maar ze maken wel onderdeel uit van de taal, net als de klasse Object.

Omdat Java sterk getypeerd is kan je gewoon de + operator overloaden voor alle onderdelen van de taal. De compiler hoeft het alleen maar te desugaren. :) .

Als jij operator-overloading wilt in Java: prima, maar dit is dus niet zozeer een inconsequentie :) .

Blog, Stratego/XT: Program Transformation, SDF: Syntax Definition, Nix: Software Deployment


  • mbravenboer
  • Registratie: Januari 2000
  • Laatst online: 06-11-2025
Rhythmic: Waarom de bedenker van Java in al zijn wijsheid besloten heeft alleen Strings apart te behandelen weet ik ook niet.
Strings zijn dus onderdeel van de Java Language Specification. Java bevat bijvoorbeeld ook String literals. Het is dus helemaal niet zo vreemd dat voor deze klasse operaties worden gedefinieerd, zeker niet voor dit geval, waar de optelling inderdaad erg makkelijk is :) .

Blog, Stratego/XT: Program Transformation, SDF: Syntax Definition, Nix: Software Deployment


  • drm
  • Registratie: Februari 2001
  • Laatst online: 09-06-2025

drm

f0pc0dert

Topicstarter
Op donderdag 03 januari 2002 16:29 schreef RickN het volgende:

[..]

Idd, had wat mij betreft ook best in java mogen zitten. :)
[..]

Daar ben ik het dus helemaal niet mee eens. Ik vind het juist van cruciaal belang dat men bij het ontwerpen van een taal heel goed kijkt naar hoe er later in geprogrammeerd gaat worden. Als men door een taal op een bepaalde manier te ontwerpen programmeurs voor allerlei fouten kan behoeden is dat toch prachtig??? Een programmeertaal is niet slechts een verzameling taalconstructies met een compiler erachter die er mooi bytejes van maakt. Waarom willen programmeurs toch altijd 10 verschillende manieren om hetzelfde te kunnen zeggen?
Opzich wel, maar in feite verandert operator overloading niets aan een oude situatie waarin code gewoon netjes gedocumenteerd moet zijn.
Als ik een enorme class schrijf waarin allerlei functies als A() b() c2000 () enzo staan, word jij er ook niet vrolijker van. Waarom zou dat met operators anders zijn?

Music is the pleasure the human mind experiences from counting without being aware that it is counting
~ Gottfried Leibniz


  • RickN
  • Registratie: December 2001
  • Laatst online: 14-06-2025
Op donderdag 03 januari 2002 16:37 schreef drm het volgende:

[..]

Opzich wel, maar in feite verandert operator overloading niets aan een oude situatie waarin code gewoon netjes gedocumenteerd moet zijn.
Als ik een enorme class schrijf waarin allerlei functies als A() b() c2000 () enzo staan, word jij er ook niet vrolijker van. Waarom zou dat met operators anders zijn?
Er zijn (voor mij) eigenlijk maar twee belangrijke overwegingen:

1: Het voegt niets toe.
2: Met operators hou je (ik) altijd de associatie met hun standaard semantiek. Als je zo'n operator dan ziet in een onverwachte omgeving kan dat onduidelijkheden geven. met A() b() c2000() heb ik dat niet. Ik hoef alleen te kijken wat die functies doen, zonder te hoeven vergeten wat ik intuïtief denk dat ze doen.

Mijn conclusie: Omdat (1), kun je (2) mooi vermijden door operator overloading gewoon niet toe te staan.

He who knows only his own side of the case knows little of that.


  • drm
  • Registratie: Februari 2001
  • Laatst online: 09-06-2025

drm

f0pc0dert

Topicstarter
mbravenboer maakte nog eens duidelijk dat String een onderdeel is van de Java Langauge Specification
Begrijp me goed, het gaat mij niet om een betoog voor of tegen operator overloading maar meer om het volgende:

Elke class in Java is een child-class van Object, toch? Een soort impliciete "extends Object" bij elke class-definition, heb ik me laten vertellen.
Goed, op die manier ontstaat er dus een boom van allerlei klassen. Een soort OOP-boom ofzo. String is net als alle andere objecten een onderdeel van die boom. Maar: er gelden andere regels voor dat onderdeel, terwijl het daarmee niet meer strict om eigenschappen van de klasse String gaat, snappie wat ik bedoel?

En net als jij laatst poste in dat Programmeer-ergernissen topics: ik vind dat int, double en float in principe ook gewoon onderdeel moeten zijn van die boom. Dus aan de andere kant zit die inconsequentie hem ook weer niet alleen in het feit dat operators toegestaan zijn op typen die onderdeel zijn van de language specification.

Ik vind het ook een beetje moeilijk uit te leggen wat ik bedoel, maar ik hoop dat je me begrijpt.

Music is the pleasure the human mind experiences from counting without being aware that it is counting
~ Gottfried Leibniz


  • RickN
  • Registratie: December 2001
  • Laatst online: 14-06-2025
Op donderdag 03 januari 2002 16:46 schreef drm het volgende:

[..]

En net als jij laatst poste in dat Programmeer-ergernissen topics: ik vind dat int, double en float in principe ook gewoon onderdeel moeten zijn van die boom.

[..]
Jaha, dat zou mooi zijn ja. Volgens mij heb je dat ook in C# en natuurlijk in SmallTalk. Dan kun je van die lochte dingen zeggen als:
code:
1
6.ToString();

He who knows only his own side of the case knows little of that.


  • Jrz
  • Registratie: Mei 2000
  • Laatst online: 17:55

Jrz

––––––––––––

Op donderdag 03 januari 2002 16:46 schreef drm het volgende:

[..]
En net als jij laatst poste in dat Programmeer-ergernissen topics: ik vind dat int, double en float in principe ook gewoon onderdeel moeten zijn van die boom.
Jij hebt het blijkbaar niet begrepen...
Als een int een instance van een class is, wat is 1 dan?
En hoe ga je dan rekenen ermee? waar moet je de eigenlijke waarde opslaan?
JUIST in een int.. een primitive.
Als je jezelf nou eerst eens ging verdiepen en hoe alles werkt, kan je wat betere comments geven

Ennnnnnnnnn laat losssssssss.... https://github.com/jrz/container-shell (instant container met chroot op current directory)


  • tomato
  • Registratie: November 1999
  • Niet online
RickN: Jaha, dat zou mooi zijn ja. Volgens mij heb je dat ook in C# en natuurlijk in SmallTalk. Dan kun je van die lochte dingen zeggen als:
code:
1
6.ToString();
In C# kan dat inderdaad 'soort van', maar eigenlijk heb je daar ook gewoon te maken met primitieve typen (auto-boxing).

In bijvoorbeeld Smalltalk en Ruby zijn alle datatypen objecten (dus ook integers, floats, arrays, hashes, etc).

  • tomato
  • Registratie: November 1999
  • Niet online
Jrz: Als een int een instance van een class is, wat is 1 dan?
En hoe ga je dan rekenen ermee? waar moet je de eigenlijke waarde opslaan?
JUIST in een int.. een primitive.
En waarom zou een object geen predefined data type mogen zijn :?
Als je jezelf nou eerst eens ging verdiepen en hoe alles werkt, kan je wat betere comments geven
Houden we het een beetje vriendelijk? ;)

  • .oisyn
  • Registratie: September 2000
  • Laatst online: 04-04 03:24

.oisyn

Moderator Devschuur®

Demotivational Speaker

Op donderdag 03 januari 2002 17:01 schreef Jrz het volgende:

[..]

Jij hebt het blijkbaar niet begrepen...
Als een int een instance van een class is, wat is 1 dan?
En hoe ga je dan rekenen ermee? waar moet je de eigenlijke waarde opslaan?
JUIST in een int.. een primitive.
Als je jezelf nou eerst eens ging verdiepen en hoe alles werkt, kan je wat betere comments geven
oh god daar hebben we meneer ik-zeik-jou-af-omdat-je-er-volgens-mij-geen-verstand-van-hebt weer. Wat is er aan de hand, heb je je dag niet vandaag ofzo? :?

sorry, verder heb ik niets toe te voegen :)

Give a man a game and he'll have fun for a day. Teach a man to make games and he'll never have fun again.


  • mbravenboer
  • Registratie: Januari 2000
  • Laatst online: 06-11-2025
drm: Begrijp me goed, het gaat mij niet om een betoog voor of tegen operator overloading.
Maar dat is nu juist het punt: daar gaat het uiteindelijk wel om ;) .

String is inderdaad wel een 'gewone' klasse, maar ook een speciale klasse: hij maakt onderdeel uit van de JLS. Daarom kunnen er in de taal Java zonder extra syntax speciale features voor deze klasse worden opgenomen. Voor onbekende klassen is dit niet mogelijk zonder een syntax voor operator overloading.

Operator overloading vereist in een taal dus een syntax. Dat hebben ze bewust niet in Java gestopt, maar dat houdt niemand tegen om voor bekende klassen in de JLS wel operatoren te definieren voor deze klassen. Dat deze in dit geval toevallig overloaded is, is eigenlijk irrelevant. Wat wel relevant is: er zijn operatoren gedefinieerd voor een klasse. Dat zou je inconsequent kunnen noemen, maar het is dus wel een begrijpelijke keuze.

Er is dus absoluut geen operator overloading gefaked want daarmee zou je erop doelen dat er een syntax nodig is voor operator overloading. Deze is dus echter niet nodig standaard klassen of primitieve typen uit de JLS.
En net als jij laatst poste in dat programmeer-ergernissen topics: ik vind dat int, double en float in principe ook gewoon onderdeel moeten zijn van die boom.
Tja en dat is dus ook een vervelend: deze keuze is denk ik een vervelende maar noodzakelijke. Objecten moeten in principe op de heap-gealloceerd worden. Dit zou voor de primitieven veel te hoge kosten met zich mee brengen. De object-georienteerde gedachte in de toepassing daarvan in Java sluit dus in feite niet goed genoeg op de praktijk aan. De primitieven int, float, boolean etc. Kunnen door de scheiding van primitieven en objecten op de stack gealloceerd worden. C# biedt hiervoor auto-boxing, waarmee de primitieven automatisch ingepakt woden in een object als dat nodig is. Dit heeft echter ook een groot nadeel: deze conversie is niet meer zichtbaar en kan dus voor lastige performance-problemen zorgen die moeilijk in te zien zijn. De expliciete boxing in Java is als je het zo bekijkt nog geeneens zo gek.

Blog, Stratego/XT: Program Transformation, SDF: Syntax Definition, Nix: Software Deployment


  • mbravenboer
  • Registratie: Januari 2000
  • Laatst online: 06-11-2025
Jrz: Jij hebt het blijkbaar niet begrepen...
Leg het ons minder bedeelden dan even goed uit, want ik snap niets van je vage stukje ;) . Een int waarde is overigens geen instantie van een klasse, maar het zou het uitstekend kunnen zijn.

Blog, Stratego/XT: Program Transformation, SDF: Syntax Definition, Nix: Software Deployment


  • drm
  • Registratie: Februari 2001
  • Laatst online: 09-06-2025

drm

f0pc0dert

Topicstarter
Jrz:
Jij hebt het blijkbaar niet begrepen...
*kuch* Ik probeer een discussie te houden. Doe ff rielekst.
Als een int een instance van een class is, wat is 1 dan?
1 is een waarde. Kan net zo goed een float of een char of byte of wat dan ook zijn.
En hoe ga je dan rekenen ermee? waar moet je de eigenlijke waarde opslaan?
Dat is het probleem van de compiler, niet van mij. Waar slaat een compiler de properties van een object op? Zal mij een zorg wezen, zolang er maar in staat wat ik wil.
JUIST in een int.. een primitive.
Als je jezelf nou eerst eens ging verdiepen en hoe alles werkt, kan je wat betere comments geven
Ik hou niet van flames.
mbravenboer:
Maar dat is nu juist het punt: daar gaat het uiteindelijk wel om ;) .

String is inderdaad wel een 'gewone' klasse, maar ook een speciale klasse: hij maakt onderdeel uit van de JLS. Daarom kunnen er in de taal Java zonder extra syntax speciale features voor deze klasse worden opgenomen. Voor onbekende klassen is dit niet mogelijk zonder een syntax voor operator overloading.
true ...
Operator overloading vereist in een taal dus een syntax. Dat hebben ze bewust niet in Java gestopt, maar dat houdt niemand tegen om voor bekende klassen in de JLS wel operatoren te definieren voor deze klassen. Dat deze in dit geval toevallig overloaded is, is eigenlijk irrelevant. Wat wel relevant is: er zijn operatoren gedefinieerd voor een klasse. Dat zou je inconsequent kunnen noemen, maar het is dus wel een begrijpelijke keuze.
Begrijpelijk is het absoluut, ja. Dat zou ik durven te betwisten :D
Er is dus absoluut geen operator overloading gefaked want daarmee zou je erop doelen dat er een syntax nodig is voor operator overloading. Deze is dus echter niet nodig standaard klassen of primitieve typen uit de JLS.
vandaar de vraagteken in topictitle ;)
Tja en dat is dus ook een vervelend: deze keuze is denk ik een vervelende maar noodzakelijke. Objecten moeten in principe op de heap-gealloceerd worden. Dit zou voor de primitieven veel te hoge kosten met zich mee brengen. De object-georienteerde gedachte in de toepassing daarvan in Java sluit dus in feite niet goed genoeg op de praktijk aan. De primitieven int, float, boolean etc. Kunnen door de scheiding van primitieven en objecten op de stack gealloceerd worden. C# biedt hiervoor auto-boxing, waarmee de primitieven automatisch ingepakt woden in een object als dat nodig is. Dit heeft echter ook een groot nadeel: deze conversie is niet meer zichtbaar en kan dus voor lastige performance-problemen zorgen die moeilijk in te zien zijn. De expliciete boxing in Java is als je het zo bekijkt nog geeneens zo gek.
Je hebt helemaal gelijk.

shit :D

Music is the pleasure the human mind experiences from counting without being aware that it is counting
~ Gottfried Leibniz


  • mbravenboer
  • Registratie: Januari 2000
  • Laatst online: 06-11-2025
drm: Je hebt helemaal gelijk. shit :D
Volgende keer beter ;) .

Maar ik snap je punt verder wel hoor: de hele zaak zit onlogisch inelkaar, maar het kan helaas in de praktijk niet anders. OO is heel leuk, maar om het ook praktisch nuttig te maken moet je een paar zaken minder mooi en consequent doen. Hier in dit topic zijn een paar goede punten naar boven gekomen :) .

Een perfecte taal zou alleen maar objecten kennen. Door analyse kan je dan bekijken of bepaalde objecten eventueel op de stack gealloceerd kunnen worden, zodat je daar toch nog de performance winst pakt. Je bent dan vrijwel volledig van je probleem af :) .

Blog, Stratego/XT: Program Transformation, SDF: Syntax Definition, Nix: Software Deployment


  • wasigh
  • Registratie: Januari 2001
  • Niet online

wasigh

wasigh.blogspot.com

een 1 is een literal, geen variabele.

Een String is een specials class die eigenlijk meer bij de ingebouwde typen als bij Objecten hoort

(maar daar waren jullie geloof ik al uit ;) )

  • wasigh
  • Registratie: Januari 2001
  • Niet online

wasigh

wasigh.blogspot.com

Op donderdag 03 januari 2002 17:01 schreef Jrz het volgende:

[..]

Jij hebt het blijkbaar niet begrepen...
Als een int een instance van een class is, wat is 1 dan?
En hoe ga je dan rekenen ermee? waar moet je de eigenlijke waarde opslaan?
JUIST in een int.. een primitive.
Als je jezelf nou eerst eens ging verdiepen en hoe alles werkt, kan je wat betere comments geven
Dit is al de 2e keer dat je erg negatief opvalt met een flame in een topic: zie ook: [topic=368406]

Je krijg hier een waarschuwing voor. Hou het gezellig of reageer niet.

  • drm
  • Registratie: Februari 2001
  • Laatst online: 09-06-2025

drm

f0pc0dert

Topicstarter
mbravenboer:

Maar ik snap je punt verder wel hoor: de hele zaak zit onlogisch inelkaar, maar het kan helaas in de praktijk niet anders. OO is heel leuk, maar om het ook praktisch nuttig te maken moet je een paar zaken minder mooi en consequent doen. Hier in dit topic zijn een paar goede punten naar boven gekomen :) .

Een perfecte taal zou alleen maar objecten kennen. Door analyse kan je dan bekijken of bepaalde objecten eventueel op de stack gealloceerd kunnen worden, zodat je daar toch nog de performance winst pakt. Je bent dan vrijwel volledig van je probleem af :) .
Precies. Een compiler zou wellicht zo slim moeten zijn om een object waarbij de properties gereduceerd kunnen worden tot 1 waarde te "downgraden" tot een primitive en op de stack kunnen. Best aardig idee.
Eigenlijk zou je dan 1 baseclass moeten hebben die de parent vormt voor alle geboxte primitives. Maakt het voor de compiler al weer een stuk eenvoudiger, denk ik... of is dat dom?

Gebeurt er trouwens niet uberhaupt al iets dergelijks in Java, wanneer je dus expliciet boxt? gokje: desugaren? ;)
Volgende keer beter ;) .
Ach, weer een leuke discussie gehad, toch?

Music is the pleasure the human mind experiences from counting without being aware that it is counting
~ Gottfried Leibniz


  • mbravenboer
  • Registratie: Januari 2000
  • Laatst online: 06-11-2025
drm: Precies. Een compiler zou wellicht zo slim moeten zijn om een object waarbij de properties gereduceerd kunnen worden tot 1 waarde te "downgraden" tot een primitive en op de stack kunnen.
Zeker, dat is heel goed mogelijk. De analyse moet wel erg goed (en wellicht pessimistisch) gebeuren, maar je kunt er wellicht best aardig resultaten mee krijgen :) . Hetzelfde zie je in feite ook in optimaliserende compilers die records op de stack proberen te plaatsen. Of dit in optimaliserende OO-taal-compilers ook al gebeurd weet ik niet, maar voor Java in ieder geval niet... Sowieso zou het voor bekende primitieven mogelijk moeten zijn en zelfs voor onbekende primitieven is het wel een serieuze optie. Je krijgt echter wel wat moeilijkheden met objecten die in methoden in die klasse worden aangemaakt, die kunnen dan namelijk ook op de stack worden geplaatst. Bij primitieven is dit vaak niet echt een punt, maar voor een generieke oplossing is dat wel degelijk zeer relevant. Ook moet je nog nagaan dat er geen andere objecten escapen en dat begint toch allemaal wel aardig complex te worden :o . Alleen optimalisering voor primitieven en ook niet voor objecten in deze primitieve zou dus al fantastisch zijn.

Je zou dan volledig van de ranzige scheiding in Java en de ranzige auto-boxing in C# af zijn. Wel moet je dan wellicht een notie van pass-by-value (wasigh, niet zeuren ;) ) hebben omdat je anders heel snel een escapende primitieve hebt, die je in feite by-value wilt doorgeven aan een andere methode. Eigenlijk zou je daarbij dus moeten klonen om rekening te houden met de performance, maar een speciale taal-constructie is daarvoor wel wenselijk.
Gebeurt er trouwens niet uberhaupt al iets dergelijks in Java, wanneer je dus expliciet boxt? gokje: desugaren? ;)
Expliciet boxen? Nou ja, je kunt van elke primitieve natuurlijk een object maken door hem in een van de immutable-'primitieve-klassen' te stoppen. Dit gebeurt niet automatisch zoals in C#. Of bedoel je dat niet?
Ach, weer een leuke discussie gehad, toch?
Zeker :) .

Blog, Stratego/XT: Program Transformation, SDF: Syntax Definition, Nix: Software Deployment


  • drm
  • Registratie: Februari 2001
  • Laatst online: 09-06-2025

drm

f0pc0dert

Topicstarter
mbravenboer:
Zeker, dat is heel goed mogelijk. De analyse moet wel erg goed (en wellicht pessimistisch) gebeuren, maar je kunt er wellicht best aardig resultaten mee krijgen :) . Hetzelfde zie je in feite ook in optimaliserende compilers die records op de stack proberen te plaatsen. Of dit in optimaliserende OO-taal-compilers ook al gebeurd weet ik niet, maar voor Java in ieder geval niet... Sowieso zou het voor bekende primitieven mogelijk moeten zijn en zelfs voor onbekende primitieven is het wel een serieuze optie. Je krijgt echter wel wat moeilijkheden met objecten die in methoden in die klasse worden aangemaakt, die kunnen dan namelijk ook op de stack worden geplaatst. Bij primitieven is dit vaak niet echt een punt, maar voor een generieke oplossing is dat wel degelijk zeer relevant. Ook moet je nog nagaan dat er geen andere objecten escapen en dat begint toch allemaal wel aardig complex te worden :o . Alleen optimalisering voor primitieven en ook niet voor objecten in deze primitieve zou dus al fantastisch zijn.

Je zou dan volledig van de ranzige scheiding in Java en de ranzige auto-boxing in C# af zijn. Wel moet je dan wellicht een notie van pass-by-value (wasigh, niet zeuren ;) ) hebben omdat je anders heel snel een escapende primitieve hebt, die je in feite by-value wilt doorgeven aan een andere methode. Eigenlijk zou je daarbij dus moeten klonen om rekening te houden met de performance, maar een speciale taal-constructie is daarvoor wel wenselijk.
Wat bedoel je met "escapen" :?
--
Als in de taal vastgelegd is, dat je per definitie een pass-by-reference doet, dan is dat toch voor de compiler geen probleem? Zou het alleen maar overzichtelijker maken, dat er hoe dan ook sprake is van een object en hoe dan ook sprake van een pass-by-reference. Je kunt tenslotte heel prima een reference naar een primitive hebben, toch?
Expliciet boxen? Nou ja, je kunt van elke primitieve natuurlijk een object maken door hem in een van de immutable-'primitieve-klassen' te stoppen. Dit gebeurt niet automatisch zoals in C#. Of bedoel je dat niet?
Ik bedoel: optimaliseert de Java compiler zoiets niet:
code:
1
a = new Integer ( 1 );

naar een primitive? Dat bedoelde ik met "expliciet boxen".
Misschien niet echt netjes gekozen term :+

Music is the pleasure the human mind experiences from counting without being aware that it is counting
~ Gottfried Leibniz


  • mbravenboer
  • Registratie: Januari 2000
  • Laatst online: 06-11-2025
drm: Wat bedoel je met "escapen" :?
Dat een object nog kan (moet) bestaan nadat de methode waarin hij wordt aangemaakt al is afgesloten.

Als dit niet het geval is, kan het object op de stack worden bewaard. Als dit wel het geval is, is het frame van de methode invocatie weg na het afsluiten van de methode en moet het object dus op de heap worden gezet. Dit gebeurt nu echter standaard... Voor objecten op de heap is garbage collection nodig en ze moeten uiteraard gealloceerd worden.
Als in de taal vastgelegd is, dat je per definitie een pass-by-reference doet, dan is dat toch voor de compiler geen probleem? Zou het alleen maar overzichtelijker maken, dat er hoe dan ook sprake is van een object en hoe dan ook sprake van een pass-by-reference. Je kunt tenslotte heel prima een reference naar een primitive hebben, toch?
Een reference naar primitieven? Ik weet niet of je nu over de toekomst of over het heden praat, maar in Java is het in ieder geval niet mogelijk om een primitieve (int, float, double) by reference mee te geven. De methode die je aanroept kan dus nooit een lokale primitieve wijzigen tijdens deze invocatie. In C/C++ kan dit uiteraard wel.

Het punt is dit: in Java gaan de pointers naar objecten by-value. In normaal spraak-gebruik zou je dus kunnen zeggen dat het object 'by-reference' wordt meegegeven. Als alle primitieven ook objecten worden krijg je een probleem als je serieus wilt gaan optimaliseren: je geeft deze waarden vaak mee aan andere methoden. Ze zullen dan erg snel escapen. Dit komt omdat je het object by-reference meegeeft. Maar eigenlijk is dit vaak helemaal niet nodig: by-value zou hier ook uitstekend zijn en dus een positief effect hebben op het aantal primitieven die op de stack kunnen worden geplaatst.
Ik bedoel: optimaliseert de Java compiler zoiets niet.
Nee, dat denk (en hoop) ik niet. Maar dit is dus eigenlijk wel een mogelijke opzet van het idee: alles als object gebruiken en pas in de compiler zelf een scheiding maken tussen primitieven en objecten...

Blog, Stratego/XT: Program Transformation, SDF: Syntax Definition, Nix: Software Deployment


  • drm
  • Registratie: Februari 2001
  • Laatst online: 09-06-2025

drm

f0pc0dert

Topicstarter
mbravenboer:
Dat een object nog kan (moet) bestaan nadat de methode waarin hij wordt aangemaakt al is afgesloten.

Als dit niet het geval is, kan het object op de stack worden bewaard. Als dit wel het geval is, is het frame van de methode invocatie weg na het afsluiten van de methode en moet het object dus op de heap worden gezet. Dit gebeurt nu echter standaard... Voor objecten op de heap is garbage collection nodig en ze moeten uiteraard gealloceerd worden.
ach so
Een reference naar primitieven? Ik weet niet of je nu over de toekomst of over het heden praat, maar in Java is het in ieder geval niet mogelijk om een primitieve (int, float, double) by reference mee te geven. De methode die je aanroept kan dus nooit een lokale primitieve wijzigen tijdens deze invocatie. In C/C++ kan dit uiteraard wel.
Dat bedoel ik. Ik spreek uit C/C++ "ervaring" (*kuch*), waar het dus wel mogelijk is. En als ik zo een beetje inschat hoe dat realiseerbaar moet zijn, weet ik dat het mogelijk is om de hele structuur te baseren op "pass-by-reference". Waarom zou je dat als taal-ontwerper niet doen?
Het punt is dit: in Java gaan de pointers naar objecten by-value. In normaal spraak-gebruik zou je dus kunnen zeggen dat het object 'by-reference' wordt meegegeven. Als alle primitieven ook objecten worden krijg je een probleem als je serieus wilt gaan optimaliseren: je geeft deze waarden vaak mee aan andere methoden. Ze zullen dan erg snel escapen. Dit komt omdat je het object by-reference meegeeft. Maar eigenlijk is dit vaak helemaal niet nodig: by-value zou hier ook uitstekend zijn en dus een positief effect hebben op het aantal primitieven die op de stack kunnen worden geplaatst.
[..]

Nee, dat denk (en hoop) ik niet. Maar dit is dus eigenlijk wel een mogelijke opzet van het idee: alles als object gebruiken en pas in de compiler zelf een scheiding maken tussen primitieven en objecten...
Dat is exact wat ik bedoel. Als het er "on top" uitziet voor de programmeur dat het allemaal objecten zijn, is het de taak van de compiler om uit te vissen wat gereduceerd kan worden tot primitive.

Wat is het probleem met een reference naar een primitive? Kan de compiler niks met een reference naar de stack :?
<edit>
en dat kan (toegegeven) natuurlijk best een taaldefinitie zijn
</edit>


* drm vindt dit mateloos interessant, btw :)

Music is the pleasure the human mind experiences from counting without being aware that it is counting
~ Gottfried Leibniz


  • mbravenboer
  • Registratie: Januari 2000
  • Laatst online: 06-11-2025
drm: Dat is exact wat ik bedoel. Als het er "on top" uitziet voor de programmeur dat het allemaal objecten zijn, is het de taak van de compiler om uit te vissen wat gereduceerd kan worden tot primitive.
Zeker, dat zou het fraaist zijn.
Wat is het probleem met een reference naar een primitive? Kan de compiler niks met een reference naar de stack :?
Als je een primitieve (of een willekeurig ander object) by-reference meegeeft is er een (grote) kans dat het object alsnog gaat escapen doordat er bijvoorbeeld ergens een referentie wordt bewaard in de methode aanroep. Je moet dan alle code door gaan lopen om te checken of een object escaped of niet. Dit moet jij vaak vrij pessimistisch doen. Hierdoor zullen veel minder objecten op de stack belanden. Je geeft hier namelijk een object by-reference mee, terwijl je dat vaak helemaal niet nodig hebt. By-value veroorzaakt wat meer gekopieer (voor primitieven is dat sowieso geen punt), maar dan kan een object wel sneller op de stack worden geplaatst.

Maar goed, het valt nog maar te bezien hoeveel effect dit echt heeft. Misschien valt het aantal primitieven die als parameter worden meegegeven inderdaad wel mee en kan je dus beter beslissen om je taal niet onnodig te vervuilen :) .

De kwestie is trouwens absoluut niet triviaal. Er zijn ontzettend veel complicaties als je het wilt oplossen voor alle objecten. Als je het alleen voor primitieven wilt doen kan je wel wat simplificerende aannames maken, waardoor het probleem beter is op te lossen... Als de primitieven objecten daarbij ook nog immutable zijn wordt het probleem nog eenvoudiger en wel reeel op te lossen...

* mbravenboer vindt dit ook wel leuk :) .

Blog, Stratego/XT: Program Transformation, SDF: Syntax Definition, Nix: Software Deployment


  • drm
  • Registratie: Februari 2001
  • Laatst online: 09-06-2025

drm

f0pc0dert

Topicstarter
Op maandag 07 januari 2002 11:39 schreef mbravenboer het e.e.a.
Waar ligt nou precies de grens of een object of primitive op de stack kan of niet? Ik snap nl. niet helemaal wat dat nou met escapen te maken heeft :?

Music is the pleasure the human mind experiences from counting without being aware that it is counting
~ Gottfried Leibniz


  • mbravenboer
  • Registratie: Januari 2000
  • Laatst online: 06-11-2025
drm: Waar ligt nou precies de grens of een object of primitive op de stack kan of niet? Ik snap nl. niet helemaal wat dat nou met escapen te maken heeft :?
Als een object in een op de stack gebruikt wordt, staat hij dus in een stack-frame (ook wel activation record genoemd). Dit is een stuk geheugen waar alle info (stack pointer, frame-pointer, temporaries, locale variabelen, argumeten) in staat van een methode aanroep. Dit stuk wordt vaak in 1 keer gealloceerd en in normale talen ook direct opgeruimd als een methode afsluit: lokale variabelen zijn niet meer beschikbaar als de methode is afgesloten. Deze stonden namelijk in het stack-frame (activation record) van de methode en dat frame is opgeruimd als de methode returned.

Als een object wordt aangemaakt in een methode en niet meer bereikbaar is nadat de methode is teruggekeerd escaped hij dus niet. In dit geval is het mogelijk om dit object in het stack-frame van deze methode te zetten.

Als een object echter nog beschikbaar is als de methode al lang is afgesloten escaped het object wel. Het eenvoudigste voorbeeld is bijvoorbeeld het opleveren van een object als resultaat. In dat geval is dat object uiteraard nog beschikbaar na de methode activatie en kan hij dus nooit op de stack worden geplaatst.

Het punt van mijn gezeur of klonen/pass-by-value is nu dat er grote kans is dat primitieven escapen terwijl dat eigenlijk niet nodig is. Als je dus nog wel onderscheid hebt tussen pass-by-value en pass-by-reference kan je de compiler een flink handje helpen...

Overigens moet je ook nog beslissen wat je met assignments gaat doen als alles een object is. Als primitieve objecten immutable zijn dus dit niet zo'n probleem, maar die aanname moet je dan wel maken. Je krijgt als je assignment ziet als pointer assignment een enorme vracht aliasen...
code:
1
2
int x = 4;
int y = x;

Is het object '4' hetzelfde object als waar y naar wijst?
Wat gebeurt er bij equivalentie ( == )? Je bedoelt dan wellicht een (in Java termen) .equals, dus inhoudelijke vergelijking. Maar wat nu als je toch pointer equivalentie wilt controleren?

Je moet wellicht voor een zinvolle oplossing een hoop aannames maken die het probleem alleen oplossen voor bekende primitieven die immutable zijn... Of je de zaak echt aanpakken en uitgebreid aan de gang gaan met het klonen van 'objecten' bij assignments en methode aanroepen. Daarvoor moet je dan echter wel syntax hebben...

Blog, Stratego/XT: Program Transformation, SDF: Syntax Definition, Nix: Software Deployment


  • drm
  • Registratie: Februari 2001
  • Laatst online: 09-06-2025

drm

f0pc0dert

Topicstarter
mbravenboer:
Als een object in een op de stack gebruikt wordt, staat hij dus in een stack-frame (ook wel activation record genoemd). Dit is een stuk geheugen waar alle info (stack pointer, frame-pointer, temporaries, locale variabelen, argumeten) in staat van een methode aanroep. Dit stuk wordt vaak in 1 keer gealloceerd en in normale talen ook direct opgeruimd als een methode afsluit: lokale variabelen zijn niet meer beschikbaar als de methode is afgesloten. Deze stonden namelijk in het stack-frame (activation record) van de methode en dat frame is opgeruimd als de methode returned.

Als een object wordt aangemaakt in een methode en niet meer bereikbaar is nadat de methode is teruggekeerd escaped hij dus niet. In dit geval is het mogelijk om dit object in het stack-frame van deze methode te zetten.

Als een object echter nog beschikbaar is als de methode al lang is afgesloten escaped het object wel. Het eenvoudigste voorbeeld is bijvoorbeeld het opleveren van een object als resultaat. In dat geval is dat object uiteraard nog beschikbaar na de methode activatie en kan hij dus nooit op de stack worden geplaatst.
Ja, ok. Dan zat ik in de goeie richting :)
Het punt van mijn gezeur of klonen/pass-by-value is nu dat er grote kans is dat primitieven escapen terwijl dat eigenlijk niet nodig is. Als je dus nog wel onderscheid hebt tussen pass-by-value en pass-by-reference kan je de compiler een flink handje helpen...
true...
Overigens moet je ook nog beslissen wat je met assignments gaat doen als alles een object is. Als primitieve objecten immutable zijn dus dit niet zo'n probleem, maar die aanname moet je dan wel maken. Je krijgt als je assignment ziet als pointer assignment een enorme vracht aliasen...
code:
1
2
int x = 4;
int y = x;

Is het object '4' hetzelfde object als waar y naar wijst?
Wat gebeurt er bij equivalentie ( == )? Je bedoelt dan wellicht een (in Java termen) .equals, dus inhoudelijke vergelijking. Maar wat nu als je toch pointer equivalentie wilt controleren?

Je moet wellicht voor een zinvolle oplossing een hoop aannames maken die het probleem alleen oplossen voor bekende primitieven die immutable zijn... Of je de zaak echt aanpakken en uitgebreid aan de gang gaan met het klonen van 'objecten' bij assignments en methode aanroepen. Daarvoor moet je dan echter wel syntax hebben...
Hehehe :) dat maakt het probleem deste interessanter...

1 punt hebben we alvast te pakken: Als je operator overloading in de taaldefinitie opneemt, kun je een aantal operators non-overloadable maken. Bijvoorbeeld assignment operator (=), equals operator (==), en is-the-same (zelfde object, zelfde geheugenplek, oftewel pointer-comparison) (===). (Is maar een voorbeeldje).
Je zou voor het klonen van objecten gewoon de = operator kunnen gebruiken, en voor verwijzingen naar objecten teruggrijpen op de reference notatie van C++ (&).

Zo krijg je een dergelijke syntax:
code:
1
2
3
int a = 4;   // wijs waarde 4 toe aan c
int b = &a;  // b === c
int c = b;   // b == c maar niet b === c

etcetera. Mmmm, zullen we een taal gaan ontwikkelen? :D

Maar goed, wat ik wil zeggen is dat de problemen die je aanroert al op te lossen zijn in de taaldefinitie zelf, of lees ik ergens overheen?

edit:
Ik bedacht me opeens dat dit logischer is:
code:
1
2
3
int a = &4;   // wijs waarde 4 toe aan c
int b = a;  // b === c
int c = &b;   // b == c maar niet b === c

Dus: expliciet aangeven wanneer je het over de waarde hebt en niet over het geheugenadres. :{ hmmm Ik vind deze nieuwe taal opeens zo leuk niet meer :{ ;)

Waarom is er dan ook niet gewoon een gulden middenweg Java/C++ :?

Music is the pleasure the human mind experiences from counting without being aware that it is counting
~ Gottfried Leibniz


  • marcusk
  • Registratie: Februari 2001
  • Laatst online: 26-09-2023
Een pagina terug ofzo hadden jullie het over C# auto-boxing. Als ik het goed begrijp wordt er daardoor een instantie van een encapsulatie-klasse (in dit geval de C# equivalent van Java's Integer) gemaakt bij aanroepen als '3.ToString()'. Waarom is dat ? Je kunt het toch veel beter vertalen naar (zodat het dus syntactische suiker (;)) is voor- ) een statische-methode aanroep als Integer.ToString(3) ? Waarom hebben de C# mensen dat niet gedaan? :)

  • drm
  • Registratie: Februari 2001
  • Laatst online: 09-06-2025

drm

f0pc0dert

Topicstarter
Op maandag 07 januari 2002 14:41 schreef marcusk het volgende:
Een pagina terug ofzo hadden jullie het over C# auto-boxing. Als ik het goed begrijp wordt er daardoor een instantie van een encapsulatie-klasse (in dit geval de C# equivalent van Java's Integer) gemaakt bij aanroepen als '3.ToString()'. Waarom is dat ? Je kunt het toch veel beter vertalen naar (zodat het dus syntactische suiker (;)) is voor- ) een statische-methode aanroep als Integer.ToString(3) ? Waarom hebben de C# mensen dat niet gedaan? :)
Ik heb niet zo veel verstand van C#, maar ik heb het vermoeden dat het een abstractie-issue is. Een object moet zelf de functionaliteit hebben om een string van zichzelf te bouwen, en dat moet dan dus niet aan een statische method overgelaten worden. Mede om uitbreidbaarheid en consequentie/consistentie tegemoet te treden. (denk ik :z)

Music is the pleasure the human mind experiences from counting without being aware that it is counting
~ Gottfried Leibniz


  • mbravenboer
  • Registratie: Januari 2000
  • Laatst online: 06-11-2025
1 punt hebben we alvast te pakken: Als je operator overloading in de taaldefinitie opneemt, kun je een aantal operators non-overloadable maken.
Dat is inderdaad ook de keuze die in C# is gemaakt.
Bijvoorbeeld assignment operator (=), equals operator (==), en is-the-same (zelfde object, zelfde geheugenplek, oftewel pointer-comparison) (===). (Is maar een voorbeeldje).
Twee verschillende vergelijkingsoperatoren lijkt mij inderdaad een uitstekend idee. De huidige oplossing in Java vind ik niet prettig werken. Of dat dan weer een =je extra moet worden zien we dan wel weer ;) . Ik zou wel wat voelen voor dit:

1. Assigment operator wordt :=
2. Er is een operatie nodig om een object (shallow) te clonen zonder een clone methode expliciet aan te roepen: $
3. Er is een pointer vergelijkings operatie nodig. Simpel =
4. Er is een waarde vergelijkings operatie nodig. Simpel $=
code:
1
2
3
4
5
6
Integer a := 1;   // 1 is een Integer object.
Integer b := $a;  // $ is de clone/value-of operatie
Integer c := a;   // object a is object b

a = c        // object a is object b
a $= c      // waarde van object a is waarde van object c

Er is echter nog een operatie handig voor parameter-passing: het maakt niet uit of er by-reference of by-value wordt doorgegeven. Doe maar wat je wilt. Daarvoor kan je natuurlijk weer aparte syntax verzinnen zoals bijvoorbeeld ? oid.
Dus: expliciet aangeven wanneer je het over de waarde hebt en niet over het geheugenadres.
Tja, ik denk toch dat dat de beste aanpak is. Je krijgt anders erg snel dat je voortdurend aan moet geven dat je niet wilt clonen en dat is nu juist het fraaie van Java: standaard wordt er niet gecloned.
etcetera. Mmmm, zullen we een taal gaan ontwikkelen?
Altijd leuk ;) . Merk overigens op dat je dit heel eenvoudig als front-end voor Java kunt implementeren: Java kent clone operaties, primitieven als objecten en echte primitieven, dus alles wat nodig is :) . Je kunt dus Java als doel-taal gebruiken en zo een hele hoop werk besparen. Je hoeft nu alleen het primitieven probleem op te lossen.
Maar goed, wat ik wil zeggen is dat de problemen die je aanroert al op te lossen zijn in de taaldefinitie zelf, of lees ik ergens overheen?
Nee hoor, lijkt mij ook. Het is echter de uitdaging om de oplossing duidelijk, fraai en werkbaar te maken: je bent in feite een probleem in de taal Java op aan het lossen. Als de oplossing onduidelijker is dan het oorspronkelijke probleem ben je natuurlijk behoorlijk verkeerd bezig ;) .
Waarom is er dan ook niet gewoon een gulden middenweg Java/C++
Tja, dat zou C# moeten zijn, maar IMHO zijn ze daar op veel punten niet bepaald origineel bezig.

Merk trouwens het verschil in aanpak op: C# lost het probleem op door twee soorten data-typen te gebruiken: value-types en reference-types. Value-types komen per definitie op de stack terecht en reference-types per definitie op de heap. Dat onderscheid is er uiteraard niet voor de lol. In onze gedachten maken we echter onderscheid in operatie en er is dus maar 1 soort data-type.
marcusk: Als ik het goed begrijp wordt er daardoor een instantie van een encapsulatie-klasse (in dit geval de C# equivalent van Java's Integer) gemaakt bij aanroepen als '3.ToString()'.
Dit gebeurt inderdaad en staat zelfs letterlijk op pagina 17 van a programmer's introduction to C#. Je ziet al gelijk wat voor een vreselijk bij-effect auto-boxing heeft. Je kunt in dit geval inderdaad veel beter desugaren ( ;) ) naar mijn mening.

Wat denk je dat er hier gebeurt:
code:
1
2
3
4
5
6
int x = 5
Console.WriteLine(x.ToString())
Console.WriteLine(x.ToString())
Console.WriteLine(x.ToString())
Console.WriteLine(x.ToString())
Console.WriteLine(x.ToString())

Zou x is hier maar 1 keer geboxed worden? Misschien dat dit simpele geval geoptimaliseerd wordt, maar ik vrees het ergste voor situaties waar de auto-boxing op diverse plaatsen in een methode plaats vindt. Je ziet hier gelijk het grote probleem van auto-boxing.

Onze ideeen zijn daarom volgens mij veel beter: zet primitieven niet om naar objecten als ze als object gebruikt worden, maar analyseer of een primitief-object percee ook een echt volwaardig object moet zijn. Voordelen: duidelijkheid, gescheiden problematiek: programmeur wordt in principe vrijwel nergens mee lastig gevallen, operatoren op objecten zijn noodzakelijk maar fraai, performance winst.
Waarom hebben de C# mensen dat niet gedaan?
Tja.... goede vraag :) . Consequentie voor alles wat value-type is waarschijnlijk.

Blog, Stratego/XT: Program Transformation, SDF: Syntax Definition, Nix: Software Deployment


  • drm
  • Registratie: Februari 2001
  • Laatst online: 09-06-2025

drm

f0pc0dert

Topicstarter
mbravenboer:
Dat is inderdaad ook de keuze die in C# is gemaakt.

Twee verschillende vergelijkingsoperatoren lijkt mij inderdaad een uitstekend idee. De huidige oplossing in Java vind ik niet prettig werken. Of dat dan weer een =je extra moet worden zien we dan wel weer ;) . Ik zou wel wat voelen voor dit:

1. Assigment operator wordt :=
2. Er is een operatie nodig om een object (shallow) te clonen zonder een clone methode expliciet aan te roepen: $
3. Er is een pointer vergelijkings operatie nodig. Simpel =
4. Er is een waarde vergelijkings operatie nodig. Simpel $=
code:
1
2
3
4
5
6
Integer a := 1;   // 1 is een Integer object.
Integer b := $a;  // $ is de clone/value-of operatie
Integer c := a;   // object a is object b

a = c        // object a is object b
a $= c      // waarde van object a is waarde van object c
zoiets, ja.
Er is echter nog een operatie handig voor parameter-passing: het maakt niet uit of er by-reference of by-value wordt doorgegeven. Doe maar wat je wilt. Daarvoor kan je natuurlijk weer aparte syntax verzinnen zoals bijvoorbeeld ? oid.

Tja, ik denk toch dat dat de beste aanpak is. Je krijgt anders erg snel dat je voortdurend aan moet geven dat je niet wilt clonen en dat is nu juist het fraaie van Java: standaard wordt er niet gecloned.
idd
Altijd leuk ;) . Merk overigens op dat je dit heel eenvoudig als front-end voor Java kunt implementeren: Java kent clone operaties, primitieven als objecten en echte primitieven, dus alles wat nodig is :) . Je kunt dus Java als doel-taal gebruiken en zo een hele hoop werk besparen. Je hoeft nu alleen het primitieven probleem op te lossen.
jep. Wel leuk idee. Maar wat schiet je er mee op ...[quote]
Nee hoor, lijkt mij ook. Het is echter de uitdaging om de oplossing duidelijk, fraai en werkbaar te maken: je bent in feite een probleem in de taal Java op aan het lossen. Als de oplossing onduidelijker is dan het oorspronkelijke probleem ben je natuurlijk behoorlijk verkeerd bezig ;) .
[quote]
:D idd
Tja, dat zou C# moeten zijn, maar IMHO zijn ze daar op veel punten niet bepaald origineel bezig.

Merk trouwens het verschil in aanpak op: C# lost het probleem op door twee soorten data-typen te gebruiken: value-types en reference-types. Value-types komen per definitie op de stack terecht en reference-types per definitie op de heap. Dat onderscheid is er uiteraard niet voor de lol. In onze gedachten maken we echter onderscheid in operatie en er is dus maar 1 soort data-type.
[..]

Dit gebeurt inderdaad en staat zelfs letterlijk op pagina 17 van a programmer's introduction to C#. Je ziet al gelijk wat voor een vreselijk bij-effect auto-boxing heeft. Je kunt in dit geval inderdaad veel beter desugaren ( ;) ) naar mijn mening.

Wat denk je dat er hier gebeurt:
code:
1
2
3
4
5
6
int x = 5
Console.WriteLine(x.ToString())
Console.WriteLine(x.ToString())
Console.WriteLine(x.ToString())
Console.WriteLine(x.ToString())
Console.WriteLine(x.ToString())

Zou x is hier maar 1 keer geboxed worden? Misschien dat dit simpele geval geoptimaliseerd wordt, maar ik vrees het ergste voor situaties waar de auto-boxing op diverse plaatsen in een methode plaats vindt. Je ziet hier gelijk het grote probleem van auto-boxing.

Onze ideeen zijn daarom volgens mij veel beter: zet primitieven niet om naar objecten als ze als object gebruikt worden, maar analyseer of een primitief-object percee ook een echt volwaardig object moet zijn. Voordelen: duidelijkheid, gescheiden problematiek: programmeur wordt in principe vrijwel nergens mee lastig gevallen, operatoren op objecten zijn noodzakelijk maar fraai, performance winst.
Lijkt me een mooie conclusie :)

Music is the pleasure the human mind experiences from counting without being aware that it is counting
~ Gottfried Leibniz


  • mbravenboer
  • Registratie: Januari 2000
  • Laatst online: 06-11-2025
drm: jep. Wel leuk idee. Maar wat schiet je er mee op ...
:? dat lijkt mij duidelijk: dat is toch precies een oplossing die je zou willen zien?

Dat het voor nu te veel werk is of niet direct de wereld zal veroveren is niet relevant ;) .

Blog, Stratego/XT: Program Transformation, SDF: Syntax Definition, Nix: Software Deployment


  • drm
  • Registratie: Februari 2001
  • Laatst online: 09-06-2025

drm

f0pc0dert

Topicstarter
mbravenboer:

[..]

:? dat lijkt mij duidelijk: dat is toch precies een oplossing die je zou willen zien?

Dat het voor nu te veel werk is of niet direct de wereld zal veroveren is niet relevant ;) .
Hahaha! :D pioniershart vs. pessimist!

Man, ik heb niet eens genoeg tijd om tussendoor wat aan kleine rotprojectjes te werken, dus laat staan zoiets!

Misschien dat er meer mensen zo over een taalspecificatie denken? Dan kunnen we met een clubje na gaan denken over directe specificaties. Lijkt me wel lollig. Van de avond-uurtjes kan ik hier en daar toch nog wel wat afsnoepen *D ;)

Music is the pleasure the human mind experiences from counting without being aware that it is counting
~ Gottfried Leibniz


  • mbravenboer
  • Registratie: Januari 2000
  • Laatst online: 06-11-2025
Misschien dat er meer mensen zo over een taalspecificatie denken? Dan kunnen we met een clubje na gaan denken over directe specificaties. Lijkt me wel lollig. Van de avond-uurtjes kan ik hier en daar toch nog wel wat afsnoepen *D ;)
Er zijn al veel Java front-ends (grammatica's, parsers, abstract syntax trees, pretty-printers) dus in principe hoeft het nog geeneens erg veel werk te zijn. Je kunt eerst kiezen voor een pessimistische aanpak, waarbij alles een object is. De taalaanpassingen zijn vrij klein.

Je kunt daarna vanuit een werkend product gaan optimaliseren door primitieve-objecten naar echte primitieven te gaan vertalen waar mogelijk :) .

Blog, Stratego/XT: Program Transformation, SDF: Syntax Definition, Nix: Software Deployment


  • drm
  • Registratie: Februari 2001
  • Laatst online: 09-06-2025

drm

f0pc0dert

Topicstarter
Op maandag 07 januari 2002 17:31 schreef mbravenboer het volgende:

[..]

Er zijn al veel Java front-ends (grammatica's, parsers, abstract syntax trees, pretty-printers) dus in principe hoeft het nog geeneens erg veel werk te zijn. Je kunt eerst kiezen voor een pessimistische aanpak, waarbij alles een object is. De taalaanpassingen zijn vrij klein.

Je kunt daarna vanuit een werkend product gaan optimaliseren door primitieve-objecten naar echte primitieven te gaan vertalen waar mogelijk :) .
De vraag is alleen: wie geeft de aftrap ;) En ik ben nou ook weer niet dermate veel met Java bezig dat het een prioriteit zou kunnen hebben. Zou ik eerder kiezen voor iets dergelijks te realiseren voor PHP. Ook geen gek idee trouwens.... * drm gaat er eens over nadenken....

Music is the pleasure the human mind experiences from counting without being aware that it is counting
~ Gottfried Leibniz


  • marcusk
  • Registratie: Februari 2001
  • Laatst online: 26-09-2023
Op 07/01/2002 15:37 schreef mbravenboer het volgende:
Onze ideeen zijn daarom volgens mij veel beter: zet primitieven niet om naar objecten als ze als object gebruikt worden, maar analyseer of een primitief-object percee ook een echt volwaardig object moet zijn. Voordelen: duidelijkheid, gescheiden problematiek: programmeur wordt in principe vrijwel nergens mee lastig gevallen, operatoren op objecten zijn noodzakelijk maar fraai, performance winst.
Maar wat is het voordeel van dat systeem t.o.v. het idee dat ik had? Dus dat primitieven qua syntax als objecten behandeld worden, maar gewoon op de stack blijven, en gekopieerd worden bij functieaanroepen? Dat lijkt me iig veel makkelijker te implementeren, en er hoeven nooit primitieven op de heap.

  • mbravenboer
  • Registratie: Januari 2000
  • Laatst online: 06-11-2025
marcusk: Maar wat is het voordeel van dat systeem t.o.v. het idee dat ik had? Dus dat primitieven qua syntax als objecten behandeld worden, maar gewoon op de stack blijven, en gekopieerd worden bij functieaanroepen?
Op zich natuurlijk een heel aardig idee, maar helaas niet mogelijk (zonder extra uitbreiding).... Het enige wat je hiermee bereikt is dat je methoden op primitieven kunt aanroepen (doordat deze dus gedesugared worden naar aanroepen van static methoden).

Maar wat als je nu echt de primitieve als object wilt gebruiken? Zet hem bijvoorbeeld eens in een verzameling van objecten. Als deze verzameling de duur van de oorspronkelijke methode aanroep overleeft en dus nog bereikbaar is na de methode waarin de primitieve is aangemaakt ben je de pineut: de primitieve stond immers op de stack in het stack-frame van deze methode.
Dat lijkt me iig veel makkelijker te implementeren, en er hoeven nooit primitieven op de heap.
Wat jij voorstelt is in principe een soort value-types uit C# waarop je methoden kunt aanroepen. Dat is op zich best handig, maar je kunt ze dan dus niet als een echt object behandelen tenzij je deze value gaat boxen zoals in C#: value-types belanden nooit op de heap. Je hebt dan echter nog steeds een expliciete scheiding tussen value-types (alleen primitieven in dit geval) en reference-types... Je schiet er dus eigenlijk niet zo heel erg gek veel mee op...

Blog, Stratego/XT: Program Transformation, SDF: Syntax Definition, Nix: Software Deployment


  • marcusk
  • Registratie: Februari 2001
  • Laatst online: 26-09-2023
Hehe, daar heb je gelijk in ja :D
|:( Dat ik daar niet aan gedacht had :)

(Snap ik meteen wat het nut van auto-boxing nou eigenlijk is ;))
Pagina: 1