[Java-functioneel] Lazy evaluation

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

Acties:
  • 0 Henk 'm!

  • mbravenboer
  • Registratie: Januari 2000
  • Laatst online: 07-10-2022
Zoals de oplettend GoT bezoeker in pagina 4&5 van dit topic ( [topic=196671] ) gelezen zal hebben, ben ik bezig met een implementatie van parser combinators in Java. Ik heb de niet lazy versie van de combinator library vrijwel werkend, maar dat heeft denk ik niet zo veel zin. Het moet natuurlijk lazy :) . Omdat het andere topic nu wel erg uit de hand begon te lopen begin ik toch maar ff een nieuwe...

Ik heb een klein testje gemaakt voor lazy-evaluation. Het systeem is heel simpel, generiek en orthogonaal. Ik weet toch niet helemaal zeker of dit 'the way to go' is, dus ik ben benieuwd of iemand nog een betere oplossing ziet of commentaar heeft op mijn oplossing.

Het idee is heel simpel. De interface voor een functie is nog steeds hetzelfde.
code:
1
2
3
4
public interface Function<A, R>
{
    public R apply(A argument);
}

Alles wat evalueerbaar moet zijn, moet de interface Lazy implementeren. Deze is generiek voor alle typen. De tweede methode is uiteraard alleen voor testdoeleinden.
code:
1
2
3
4
5
public interface Lazy<A>
{
    public A evaluate();
    public boolean isEvaluated();
}

Uiteindelijk moet je toch ergens beginnen, dus is er een generieke implementatie van Lazy, die voor alle typen werkt en dus echt een waarde heeft:
code:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
public class NotLazy<A> implements Lazy<A>
{
    private A _value;

    public NotLazy(A value)
    {
        super();
        _value = value;
    }

    public A evaluate()
    {
        return _value;
    }

    public boolean isEvaluated()
    {
        return true;
    }
}

Ok, dan komt nu de lazy implementatie van plus :) .
code:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
public class Plus implements Function<Lazy<Integer>, Function<Lazy<Integer>,Lazy<Integer>>>
{
    public Function<Lazy<Integer>, Lazy<Integer>> apply(Lazy<Integer> argument1)
    {
        return new AnonymousResult1(argument1); 
    }

    private class AnonymousResult1 implements Function<Lazy<Integer>, Lazy<Integer>>
    {
        private Lazy<Integer> _argument1;

        public AnonymousResult1(Lazy<Integer> argument1)
        {
            _argument1 = argument1;
        }

        public Lazy<Integer> apply(Lazy<Integer> argument2)
        {
            return new AnonymousResult2(argument2);         
        }

        private class AnonymousResult2 implements Lazy<Integer>
        {
            private Lazy<Integer>    _argument2;
            private Integer     _result;

            public AnonymousResult2(Lazy<Integer> argument2)
            {
                _argument2 = argument2;
                _result == null;
            }
            
            public Integer evaluate()
            {
                if(_result == null)
                {
                    _result = new Integer(_argument1.evaluate().intValue() + _argument2.evaluate().intValue());
                }

                return result;                  
            }

            public boolean isEvaluated()
            {
                return _result != null;
            }
        }
    }
}

en de test klasse (het werkt btw ;) ) :
code:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
public class LazyTest extends TestCase
{
    public LazyTest(String name)
    {
        super(name);
    }

    public void testLazyPlus()
    {
        NotLazy<Integer> value1 = new NotLazy(new Integer(2));
        NotLazy<Integer> value2 = new NotLazy(new Integer(3));

        Lazy<Integer> value3 = new Plus().apply(value1).apply(value2);
        Lazy<Integer> value4 = new Plus().apply(value2).apply(value1);

        assertEquals("Plus result is 5",     value3.evaluate(), new Integer(5));
        assertTrue("Second not evaluated",  !value4.isEvaluated());
    }

    public static Test suite()
    {
        TestSuite suite = new TestSuite(LazyTest.class);
        return suite;
    }

}

Dat werkt dus allemaal lekker.

Nu vraag ik me af of dit de goede oplossing is. Je ziet duidelijk dat je op deze manier met oneindige lijsten kan werken. Wat ik echter niet zeker weet (en ik kon zo snel ff geen test verzinnen) is of dit ook gaat werken in de standaard tovertruk in lazy talen:

functie 1 krijgt als argument het resultaat mee functie 2
functie 2 krijgt als argument het resultaat mee functie 1

Dit is een imperatieve taal natuurlijk volkomen onzin. Zou dit kunnen met mijn lazy-evaluation implementatie (uiteraard alleen als de berekening ook wel echt mogelijk is)?
Weet iemand zo ff een werkend voorbeeldje van zo'n combinatie? Ik kan alleen maar voorbeelden bedenken die echt niet kunnen ;) .

Tips of kritiek wordt gewaardeerd :)

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


Acties:
  • 0 Henk 'm!

  • Juup
  • Registratie: Februari 2000
  • Niet online
Ik heb het vorige topic ook grotendeels gelezen maar ik heb werkelijk geen flauw idee war dit over gaat. Weet je een URL met wat uitleg wat er hier berekend/gedaan wordt?

Een wappie is iemand die gevallen is voor de (jarenlange) Russische desinformatiecampagnes.
Wantrouwen en confirmation bias doen de rest.


Acties:
  • 0 Henk 'm!

  • Tomatrix
  • Registratie: Juni 1999
  • Laatst online: 27-02 16:26
Ik zal eerst eens die geparametriseerde compiler eens downen.
Early Access?

Acties:
  • 0 Henk 'm!

  • mbravenboer
  • Registratie: Januari 2000
  • Laatst online: 07-10-2022
Tomatrix: Ik zal eerst eens die geparametriseerde compiler eens downen.
Early Access?
Yep early access, je moet wel de specificatie er goed bij houden want sommige dingen zijn nog vrij onlogisch. De implementatie is echter gewoon een uitgebreidde versie van de compiler in de 1.4.0 beta dus verder is hij wel aardig ok :) .

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


Acties:
  • 0 Henk 'm!

  • Tomatrix
  • Registratie: Juni 1999
  • Laatst online: 27-02 16:26
Kan je deze functionaliteit trouwens niet makkelijker bereiken met iets als JProlog?

Acties:
  • 0 Henk 'm!

  • mbravenboer
  • Registratie: Januari 2000
  • Laatst online: 07-10-2022
Jaaap: ik heb werkelijk geen flauw idee war dit over gaat. Weet je een URL met wat uitleg wat er hier berekend/gedaan wordt?
Ik reken eigenlijk 2 + 3 uit :o .

Als je nooit met een functionele taal hebt gewerkt kan je het misschien maar beter volledig negeren :) . Het idee van een functionele taal is dat werkelijk alles een functie is die 1 parameter meekrijgt en dan weer een nieuwe functie oplevert:

(+) 2 3

betekent bijvoorbeeld de functie (+) toegepast op 2 en daarna toegepast op 3. Je kan dus bijvoorbeeld ook schrijven:

plus2 = (+) 2
plus2 3

Maar goed, als je het leuk vindt moet je bijvoorbeeld eens op http://www.haskell.org kijken. Dat is een vrij populaire functionele taal.

Ik ben nu bezig om Java om te bouwen (verkrachten?) naar een functionele taal.

<fluistermode>
Misschien dat er later op deze manier een (goede) Haskell -> Java compiler geschreven kan worden.
</fluistermode>

Als je meer wilt weten over geparameterizeerde typen (die ik zwaar gebruik) moet je eens kijken bij JSR-14 op http://www.jcp.org

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


Acties:
  • 0 Henk 'm!

  • mbravenboer
  • Registratie: Januari 2000
  • Laatst online: 07-10-2022
Tomatrix: Kan je deze functionaliteit trouwens niet makkelijker bereiken met iets als JProlog?
Misschien wel, maar Haskell vindt ik een fraaiere taal. Het gaat mij bovendien allereerst om de parser-combinators en die heb ik nog niet in Prolog gezien...

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


Acties:
  • 0 Henk 'm!

Verwijderd

Ik vind dit zwaar interressant, maar heb nog nooit gewerkt met die geparametiseerde typen in Java. Daar ga ik zo eerst maar eens over lezen, en dan ga ik je implementatie eens bestuderen.
Ik heb ooit eens geprobeerd om parser combinators te schrijven in een imperatieve taal, maar dat lukte dus niet. :)

Acties:
  • 0 Henk 'm!

  • mbravenboer
  • Registratie: Januari 2000
  • Laatst online: 07-10-2022
joska: Ik vind dit zwaar interressant, maar heb nog nooit gewerkt met die geparametiseerde typen in Java. Daar ga ik zo eerst maar eens over lezen, en dan ga ik je implementatie eens bestuderen.
JSR-14: http://www.jcp.org/jsr/detail/14.jsp
Public review specificatie: http://www.jcp.org/aboutJava/communityprocess/review/jsr014/index.html
Early-access compiler: http://developer.java.sun.com/developer/earlyAccess/adding_generics/

Compileren is een beetje lastig (je moet diverse classpaths instellen) maar als je Ant gebruikt van Apache, werkt het heel makkelijk. 1x instellen = altijd werken :) .
Ik heb ooit eens geprobeerd om parser combinators te schrijven in een imperatieve taal, maar dat lukte dus niet. :)
Daar hadden meer mensen last van ;)

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


Acties:
  • 0 Henk 'm!

  • Alarmnummer
  • Registratie: Juli 2001
  • Laatst online: 09-07-2024

Alarmnummer

-= Tja =-

Op zaterdag 04 augustus 2001 14:57 schreef mbravenboer het volgende:

[..]

JSR-14: http://www.jcp.org/jsr/detail/14.jsp
Public review specificatie: http://www.jcp.org/aboutJava/communityprocess/review/jsr014/index.html
Early-access compiler: http://developer.java.sun.com/developer/earlyAccess/adding_generics/

Compileren is een beetje lastig (je moet diverse classpaths instellen) maar als je Ant gebruikt van Apache, werkt het heel makkelijk. 1x instellen = altijd werken :) .
[..]

Daar hadden meer mensen last van ;)
Ik ontwerp ik altijd wrappers om collection types heen (ArrayList, Vectors, Hashmaps etc) en bouw een aantal standaard methodes erin. Zo`n wrapperklasse die biedt ook de mogelijkheid om met listeners en events te gaan werken. Ik heb al even zitten kijken naar die geparametriseerde typen maar ik denk dat ik het voorlopig nog wel even zonder kan doen. Maar om van java een functionele taal te maken klinkt wel erg interessant. Alleen moet ik mijn haskell boek dan maar weer eens induiken :) anders heeft het geen nut.

Acties:
  • 0 Henk 'm!

  • mbravenboer
  • Registratie: Januari 2000
  • Laatst online: 07-10-2022
Alarmnummer: Ik ontwerp ik altijd wrappers om collection types heen (ArrayList, Vectors, Hashmaps etc) en bouw een aantal standaard methodes erin. Zo`n wrapperklasse die biedt ook de mogelijkheid om met listeners en events te gaan werken.
Hehe :) die heb ik ook liggen. Eerder schreef ik ze echter voor elke type (althans... find... replace) om type-safety te houden. Met behulp van de geparameterizeerde typen kan je echter 1 generieke klasse gebruiken, zodat je minder code hebt en deze steeds verder kan verbeteren. Wil je stukje code zien?
Maar om van java een functionele taal te maken klinkt wel erg interessant. Alleen moet ik mijn haskell boek dan maar weer eens induiken :) anders heeft het geen nut.
Echt makkelijk werkt het niet hoor. Je moet niet verwachten dat je volledige functionele programma's met ingewikkelde maps en folds makkelijk kan schrijven. Je moet namelijk van elke functie de types aangeven die je gebruikt. Bij een generieke map moet je dus zeggen welke type variabele van welk type is als je deze functie aanroept. Dit maakt je code helaas behoorlijk onleesbaar als je echt ingewikkelde combinaties hebt.

Parsers zijn wel makkelijk te gebruiken omdat die (meestal) maar op twee variabelen geparameterizeerd zijn....

Voorbeeldje:
code:
1
2
LinkedList<Pair<A, LinkedList<S>>> resultOfA = _parser.apply(symbols);
return new Map<Pair<A, LinkedList<S>>, Pair<B, LinkedList<S>>>().apply(new Mapping()).apply(resultOfA);

Als je dit opruimt krijg je:
code:
1
2
LinkedList resultOfA = _parser.apply(symbols);
return new Map().apply(new Mapping()).apply(resultOfA);

Tja.... sterke typering en geen type inferentie...

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


Acties:
  • 0 Henk 'm!

  • farlane
  • Registratie: Maart 2000
  • Laatst online: 11:22
Ik volg het allemaal met erg veel interesse, maar er wordt me na je antwoord op Jaapf wel iets duidelijk.

Als je niet bekend bent met het principe 'functionele taal' (zoals ik) dan snap je werkelijk geen biet van waar je eigenlijk naartoe wilt met het hele verhaal. ( Toch maar eens snuffelen bij haskell.org dan.. )

Overigens waardeer ik een leuk stukje code altijd. Ik wil meer ... :)

Somniferous whisperings of scarlet fields. Sleep calling me and in my dreams i wander. My reality is abandoned (I traverse afar). Not a care if I never everwake.


Acties:
  • 0 Henk 'm!

Verwijderd

He cool, idd, als je niet begrijpt hoe functionele talen werken kun je maar beter even de andere kant op kijken ;) , maaruh ik wist niet dat er al zulke 'vergaande' implementaties van parser combinators waren voor Java. Give us more...

* Stoned-cow is inmiddels aan 4e jaar informatica aan UU begonnen

Acties:
  • 0 Henk 'm!

  • mbravenboer
  • Registratie: Januari 2000
  • Laatst online: 07-10-2022
Stoned-cow: maaruh ik wist niet dat er al zulke 'vergaande' implementaties van parser combinators waren voor Java. Give us more...
Die bestonden een week geleden ook nog niet ;) .
* Stoned-cow is inmiddels aan 4e jaar informatica aan UU begonnen
* mbravenboer zit 1 jaartje verder op dezelfde :)

Als ik tevreden ben over de niet lazy versie (de lazy duurt nog een tijdje) zal ik even een link posten naar de volledige code met wat voorbeelden hoe je het kan gebruiken...

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


Acties:
  • 0 Henk 'm!

  • Alarmnummer
  • Registratie: Juli 2001
  • Laatst online: 09-07-2024

Alarmnummer

-= Tja =-

Op zaterdag 04 augustus 2001 15:15 schreef mbravenboer het volgende:

[..]

Hehe :) die heb ik ook liggen. Eerder schreef ik ze echter voor elke type (althans... find... replace) om type-safety te houden. Met behulp van de geparameterizeerde typen kan je echter 1 generieke klasse gebruiken, zodat je minder code hebt en deze steeds verder kan verbeteren. Wil je stukje code zien?
[..]

Echt makkelijk werkt het niet hoor. Je moet niet verwachten dat je volledige functionele programma's met ingewikkelde maps en folds makkelijk kan schrijven. Je moet namelijk van elke functie de types aangeven die je gebruikt. Bij een generieke map moet je dus zeggen welke type variabele van welk type is als je deze functie aanroept. Dit maakt je code helaas behoorlijk onleesbaar als je echt ingewikkelde combinaties hebt.

Parsers zijn wel makkelijk te gebruiken omdat die (meestal) maar op twee variabelen geparameterizeerd zijn....

Voorbeeldje:
code:
1
2
LinkedList<Pair<A, LinkedList<S>>> resultOfA = _parser.apply(symbols);
return new Map<Pair<A, LinkedList<S>>, Pair<B, LinkedList<S>>>().apply(new Mapping()).apply(resultOfA);

Als je dit opruimt krijg je:
code:
1
2
LinkedList resultOfA = _parser.apply(symbols);
return new Map().apply(new Mapping()).apply(resultOfA);

Tja.... sterke typering en geen type inferentie...
Ik weet hoe geparametriseerde types werken :) Heb al even gekeken naar de pizza compiler en het vervolg daarop. Daar heeft sun zijn final draft? ook op gebaseerd. Maar meestal zijn mijn object vrij specifiek en de tijd dat ik bezig ben om een wrapper te schrijven is niet zo groot. Meestal is het ook wat knip en plakwerk en wat replace. Ben vrij veel tijd kwijt om de 'echte' code te schrijven :) en niet een of andere wrapper.

Acties:
  • 0 Henk 'm!

  • mbravenboer
  • Registratie: Januari 2000
  • Laatst online: 07-10-2022
farlane: Als je niet bekend bent met het principe 'functionele taal' (zoals ik) dan snap je werkelijk geen biet van waar je eigenlijk naartoe wilt met het hele verhaal.
Hehe :) dat kan ik me voorstellen :) Het ziet erg uitermate niet Java achtig uit allemaal :) . Misschien is het leuk om eens iets te vertellen over functionele talen... maar goed, voorlopig nog genoeg te doen :) .
Overigens waardeer ik een leuk stukje code altijd. Ik wil meer ... :)
Geduld, ik GoT te veel ;)

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


Acties:
  • 0 Henk 'm!

  • mbravenboer
  • Registratie: Januari 2000
  • Laatst online: 07-10-2022
Alarmnummer: Daar heeft sun zijn final draft? ook op gebaseerd.
Klopt het is feite een invoering van GJ (ex-pizza) in Java. De compiler hebben ze denk ik wel opnieuw gebakken als ik de bugs zo zie die erin zitten...

PS: het is wel fijn als je ietsje meer knipt in de tekst die je quote :)

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


Acties:
  • 0 Henk 'm!

  • Alarmnummer
  • Registratie: Juli 2001
  • Laatst online: 09-07-2024

Alarmnummer

-= Tja =-

En ik werk op dit moment nog vrij veel met serialize en daarvoor heb ik vaak toch eigen readers en writers nodig. En als je een wrapper maakt dan heb je weer eens het gevoel iets te doen :)

Maar hoop dat je ons een beetje op de hoogte houd. Een imperatieve programmeer taal is fijn (controle) maar een functionele programmeer taal is makkelijker (nouja :) ) je snapt wel wat ik bedoel. En het zou leuk zijn als je dat met elkaar kan combineren. Vind trouwens ebnf in combinatie met java ook erg fijn.

Acties:
  • 0 Henk 'm!

  • Alarmnummer
  • Registratie: Juli 2001
  • Laatst online: 09-07-2024

Alarmnummer

-= Tja =-

Op zaterdag 04 augustus 2001 15:40 schreef mbravenboer het volgende:
PS: het is wel fijn als je ietsje meer knipt in de tekst die je quote :)
is goed :)

Acties:
  • 0 Henk 'm!

  • marcusk
  • Registratie: Februari 2001
  • Laatst online: 26-09-2023
ik ben bezig met een Haskell-tutorial, en ik snap nu wel een beetje hoe het in elkaar zit, maar wat is nou het nut van deze taal? dus waarvoor zou ik het willen gebruiken?

Acties:
  • 0 Henk 'm!

  • mbravenboer
  • Registratie: Januari 2000
  • Laatst online: 07-10-2022
marcusk: ik ben bezig met een Haskell-tutorial
Met lezen neem ik aan? ;)
en ik snap nu wel een beetje hoe het in elkaar zit, maar wat is nou het nut van deze taal? dus waarvoor zou ik het willen gebruiken?
Omdat alles een functie is kan je er heel aardig over redeneren. Het heeft een hele goede wiskundige basis, waardoor het redeneren over programma's veel beter gaat. Bij imperatieve talen is dit nagenoeg heel lastig :) .

Verder is de syntax zeer compact en is het ideaal voor het combineren van berekeningen. Je kan heel makkelijk functies combineren en opnieuw toepassen.

De meeste functionele talen bieden ook een veel betere ondersteuning voor generiek programmeren. Dit komt vooral door de goede wiskundige basis.

Veel functionele talen hebben ook lazy-evaluation, wat betekent dat waarden pas uitgerekend worden als ze ook ehct nodig zijn. Hierdoor kan je bijvoorbeeld met oneindige lijsten werken :) .

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


Acties:
  • 0 Henk 'm!

  • tomato
  • Registratie: November 1999
  • Niet online
Op zaterdag 04 augustus 2001 20:08 schreef marcusk het volgende:
ik ben bezig met een Haskell-tutorial, en ik snap nu wel een beetje hoe het in elkaar zit, maar wat is nou het nut van deze taal? dus waarvoor zou ik het willen gebruiken?
Ik heb er zelf ook totaal geen ervaring mee, maar het idee dat ik heb is dat je er hele bondige, to-the-point programma's mee kan schrijven en dat je er gemakkelijk correctheid van een programma mee kan bewijzen. Zal vast nog meer zijn (er wordt altijd geroepen dat het zeer geschikt is voor prototypes, maar dat zal wel te maken hebben met wat ik net noemde). Anders even wachten op mbravenboer en/of joska ;)

[edit]
Te laat :(
Sla dit maar over en lees alleen die van mbravenboer :+

Acties:
  • 0 Henk 'm!

  • mbravenboer
  • Registratie: Januari 2000
  • Laatst online: 07-10-2022
tomato schreef goede info of FP
Sla dit maar over en lees alleen die van mbravenboer :+
Nou ik vond jouw stukje ook wel duidelijk en kloppend :) . Toch lezen dus ;) .

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


Acties:
  • 0 Henk 'm!

  • marcusk
  • Registratie: Februari 2001
  • Laatst online: 26-09-2023
Met lezen neem ik aan? ;)
hehe :)
Omdat alles een functie is kan je er heel aardig over redeneren. Het heeft een hele goede wiskundige basis, waardoor het redeneren over programma's veel beter gaat. Bij imperatieve talen is dit nagenoeg heel lastig :) .

Verder is de syntax zeer compact en is het ideaal voor het combineren van berekeningen. Je kan heel makkelijk functies combineren en opnieuw toepassen.

De meeste functionele talen bieden ook een veel betere ondersteuning voor generiek programmeren. Dit komt vooral door de goede wiskundige basis.

Veel functionele talen hebben ook lazy-evaluation, wat betekent dat waarden pas uitgerekend worden als ze ook ehct nodig zijn. Hierdoor kan je bijvoorbeeld met oneindige lijsten werken :) .
Nou ja, ik kan me er nog niet echt veel bij voorstellen, maar na de vakantie ga ik naar de TU Twente, Informatica, en dit is het eerste trimester:

Practicum Maple 1
Calculus I INF*
Lineaire algebra *
Oriëntatie ICT 1
Functioneel programmeren
Informatiesystemen

Dus dan zal het allemaal wel wat duidelijker worden :)
tomato: Sla dit maar over en lees alleen die van mbravenboer
sorry, ik had het al gelezen ;)
mbravenboer: Toch lezen dus
Gelukkig ;)

Acties:
  • 0 Henk 'm!

  • mbravenboer
  • Registratie: Januari 2000
  • Laatst online: 07-10-2022
Ok, klein voorbeedje dan... Je kent Java dus ik maak ff een vergelijking.

Stel nu eens dat ik een lijst van getallen heb en bij alle getallen 1 op wil tellen.

In Java kan dat zo:
code:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
List<Integer> ints = new ArrayList<Integer>();
ints.add(new Integer(2));
ints.add(new Integer(3));
ints.add(new Integer(1));
ints.add(new Integer(5));

List<Integer> result = new ArrayList<Integer>();

Iterator<Integer> iterator = ints.iterator();
while(iterator.hasNext())
{
    result.add(new Integer(iterator.next().intValue() + 1).
}

return result;

In Haskell heb je echter een generieke functie Map. Deze functie krijgt twee argumenten: een functie van a naar b ( a->b) en een lijst van as. Als resultaat levert het een lijst van bs op. De functie wordt dus toegepast op elke element van de lijst. Hierdoor veranderd elke type a van in een type b.

Dit schrijf je zo op:
code:
1
map :: (a->b) -> [a] -> [b]

Je kan nu heel makkelijk een functie maken die bij een getal 1 optelt. Dit is namelijk gewoon:
code:
1
(+) 1

Dit is de functie + toegepast met 1. (+) heeft uiteraard nog 1 argument nodig en dat is nu dus precies een item uit de lijst.


Je krijgt nu dus als code
code:
1
map ((+) 1) [2,1,3,5]

Dit doet dus precies hetzelfde als de hele lap Java code hierboven.

In Haskell (en andere FP talen) programmeer je namelijk op een declaratieve manier. Dit betekent dat je niet opgeeft hoe je iets wilt bereiken (dit doe je bij imperatief programmeren: C, Java etc) maar wat je wilt bereiken. De compiler zoekt dan zelf uit hoe hij dit gaat begrijpen :) .

Zo duidelijker?

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


Acties:
  • 0 Henk 'm!

  • marcusk
  • Registratie: Februari 2001
  • Laatst online: 26-09-2023
Op zaterdag 04 augustus 2001 20:43 schreef mbravenboer het volgende:
Ok, klein voorbeedje dan... Je kent Java dus ik maak ff een vergelijking.
Ik heb idd ooit wel eens iets in Java gemaakt, maar dat was slechts een simpel applet-je
Dit doet dus precies hetzelfde als de hele lap Java code hierboven.
Dat is idd best wel iets korter ;)
Zo duidelijker?
Ja zeker ! Bedankt voor de uitleg :)

Acties:
  • 0 Henk 'm!

Verwijderd

M 'Javaguru' bravenboer, kun je me nog even vertellen waar op die jcp site ik een uitleg kan vinden van geparametiseerde typen?

Acties:
  • 0 Henk 'm!

  • mbravenboer
  • Registratie: Januari 2000
  • Laatst online: 07-10-2022
Ik had eerder in het topic 3 links gepost je moet de public review hebben:

http://www.jcp.org/aboutJava/communityprocess/review/jsr014/index.html

ff op continue klikken en je krijgt een zip met daarin API documentatie voor de geparameterizeerde klassen en de specificatie in PDF.

De PDF is op sommige punten behoorlijk formeel, dus lees het niet al te precies ;)

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


Acties:
  • 0 Henk 'm!

Verwijderd

Op zaterdag 04 augustus 2001 22:42 schreef mbravenboer het volgende:
Ik had eerder in het topic 3 links gepost je moet de public review hebben:

http://www.jcp.org/aboutJava/communityprocess/review/jsr014/index.html

ff op continue klikken en je krijgt een zip met daarin API documentatie voor de geparameterizeerde klassen en de specificatie in PDF.

De PDF is op sommige punten behoorlijk formeel, dus lees het niet al te precies ;)
Thanx! :) Ik kon het echt niet vinden.

Acties:
  • 0 Henk 'm!

  • marcusk
  • Registratie: Februari 2001
  • Laatst online: 26-09-2023
Is dit gewoon hetzelfde als C++ templates, of lijkt het er alleen erg op ?

Acties:
  • 0 Henk 'm!

Verwijderd

Op zaterdag 04 augustus 2001 22:57 schreef marcusk het volgende:
Is dit gewoon hetzelfde als C++ templates, of lijkt het er alleen erg op ?
Voor zover ik begrepen heb niet (maar ik heb me er nog niet in verdiept)

Acties:
  • 0 Henk 'm!

  • Alarmnummer
  • Registratie: Juli 2001
  • Laatst online: 09-07-2024

Alarmnummer

-= Tja =-

Op zaterdag 04 augustus 2001 22:57 schreef marcusk het volgende:
Is dit gewoon hetzelfde als C++ templates, of lijkt het er alleen erg op ?
De geparametriseerde types kun je vergelijken met templates. Dat hadden we nog niet :)

Acties:
  • 0 Henk 'm!

  • mbravenboer
  • Registratie: Januari 2000
  • Laatst online: 07-10-2022
C++ templates worden over het algemeen als evil, onduidelijk en obscuur beschouwd. Geparameterizeerde typen zijn volgens de JSR en specificatie nadrukkelijk geen Java versie van C++ templates.

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


Acties:
  • 0 Henk 'm!

  • mbravenboer
  • Registratie: Januari 2000
  • Laatst online: 07-10-2022
Om weer even ontopic te gaan: Ik ben op dit moment bezig met de lazy lijst, zodat ik oneindige lijsten kan definieren. Als dit goed werkt wordt lazy-evaluation ook in de parser combinators ingevoerd :) .

Als je morgenochtend wakker wordt heb ik denk ik de lazy en oneindige lijsten gepost ;) . Ik ben van plan om het maar gelijk goed te doen en dus de functie iterate te implementeren, die lekker geparameterizeerd een oneindige lijst op levert.

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


Acties:
  • 0 Henk 'm!

  • Alarmnummer
  • Registratie: Juli 2001
  • Laatst online: 09-07-2024

Alarmnummer

-= Tja =-

Op zondag 05 augustus 2001 00:35 schreef mbravenboer het volgende:
C++ templates worden over het algemeen als evil, onduidelijk en obscuur beschouwd. Geparameterizeerde typen zijn volgens de JSR en specificatie nadrukkelijk geen Java versie van C++ templates.
Misschien dat ik dan de boot heb gemist. Ik had begrepen dat het wel templates waren zoals uit c. Wil je me misschien uitleggen waarom het niet zo is?

Acties:
  • 0 Henk 'm!

  • mbravenboer
  • Registratie: Januari 2000
  • Laatst online: 07-10-2022
Alarmnummer: Misschien dat ik dan de boot heb gemist. Ik had begrepen dat het wel templates waren zoals uit c. Wil je me misschien uitleggen waarom het niet zo is?
Hier kan je er iets over lezen:

http://swen.uwaterloo.ca/~drayside/TALKS/GENERICITY/

De naam van de oplossing in Java zegt het eigenlijk al: geparameterizeerde typen. Een klasse is dus echt geparameterizeerd met een bepaald type. In C++ is een template echter in feite een generator van een familie van klassen. Echt een template dus. Type-checking van een template kan pas gebeuren nadat de klasse is gegeneerd. In Java is dit niet zo (slides vertellen het iets beter denk ik ;) , ik weet niet erg veel C++ )

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


Acties:
  • 0 Henk 'm!

  • mbravenboer
  • Registratie: Januari 2000
  • Laatst online: 07-10-2022
Volgens mij werkt het :)

Ik heb nog geen echte test geschreven, dus het kan zijn dat er nog een misser inzit, maar het aanmaken van een oneindige lijst gaat in ieder geval goed (hij termineert dus).

Ik zal even de implementatie hier neer zetten. Het is wat veel code, maar er zit een duidelijke logica en structuur in.

De interface die alle functies moeten implementeren is nog steeds hetzelfde:
code:
1
2
3
4
5
6
package org.pandoramix.function;

public interface Function<A, R>
{
    public R apply(A argument);
}

De interface voor iets wat Lazy is ook:
code:
1
2
3
4
5
6
7
package org.pandoramix.function.lazy;

public interface Lazy<A>
{
    public A evaluate();
    public boolean isEvaluated();
}

De waarde wordt dus pas echt berekend als evaluate wordt aangeroepen. Als je een Lazy<E> in handen hebt, heb je in feite alleen een manier om de waarde te verkrijgen.

Voor de volledigheid nog even NotLazy. Deze is nodig omdat alle functies met Lazy argumenten werken. Als jij echter gewoon een primitieve wilt meegeven zoals bijvoorbeeld een Integer, dan is die waarde natuurlijk niet Lazy. Door er een NotLazy omheen te bouwen lijkt het voor de functie net alsof hij Lazy is :) .
code:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
package org.pandoramix.function.lazy;

public class NotLazy<A> implements Lazy<A>
{
    private A _value;

    public NotLazy(A value)
    {
        super();
        _value = value;
    }

    public A evaluate()
    {
        return _value;
    }

    public boolean isEvaluated()
    {
        return true;
    }
}

De Plus functie. Merk op dat deze functie dus allemaal lazy argumenten meekrijgt. Merk ook op dat het eindresultaat Lazy is. De parameters worden pas geevalueerd als het Lazy resultaat wordt aangeroepen.
code:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
package org.pandoramix.function.lazy;

import org.pandoramix.function.Function;

public class Plus implements Function<Lazy<Integer>, Function<Lazy<Integer>,Lazy<Integer>>>
{
    public Function<Lazy<Integer>, Lazy<Integer>> apply(Lazy<Integer> argument1)
    {
        return new AnonymousResult1(argument1); 
    }

    private class AnonymousResult1 implements Function<Lazy<Integer>, Lazy<Integer>>
    {
        private Lazy<Integer> _argument1;

        public AnonymousResult1(Lazy<Integer> argument1)
        {
            _argument1 = argument1;
        }

        public Lazy<Integer> apply(Lazy<Integer> argument2)
        {
            return new AnonymousResult2(argument2);         
        }

        private class AnonymousResult2 implements Lazy<Integer>
        {
            private Lazy<Integer>    _argument2;
            private Integer         _result;

            public AnonymousResult2(Lazy<Integer> argument2)
            {
                _argument2 = argument2;
                _result = null;
            }
            
            public Integer evaluate()
            {
                if(_result == null)
                {
                    _result = new Integer(_argument1.evaluate().intValue() + _argument2.evaluate().intValue());
                }

                return _result;                 
            }

            public boolean isEvaluated()
            {
                return _result != null;
            }
        }
    }
}

Dit is de interface van de gelinkte lijst. Een gelinkte lijst bestaat uiteraard uit een cons en een nil. Allebei deze elementen moet deze interface implementeren. De match methode is voor dit voorbeeld niet relevant, maar dient voor pattern-matching.
code:
1
2
3
4
5
6
7
8
9
10
11
package org.pandoramix.function.lazy.list;

public abstract class LinkedList<E>
{
    public abstract <R> R match(LinkedListFunction<E, R> function);

/*  public String toString()
    {
        return "[" + new LinkedListPrettyPrinter().apply(this) + "]";
    }*/
}

De Nil van mijn gelinkte lijst: LinkedListEnd
code:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
package org.pandoramix.function.lazy.list;

import org.pandoramix.function.Function;

public class LinkedListEnd<E> extends LinkedList<E>
{
    public LinkedListEnd()
    {
        super();
    }

    public <R> R match(LinkedListFunction<E, R> function)
    {
        return function.matchedApply(this);
    }
}

Dat doet dus helemaal niks...

En dan de kern van de zaak: LinkedListElement. Merk op dat ook deze functie weer alleen Lazy argumenten meekrijgt. De tweede Lazy parameter: LinkedList<E> rest is de kern van de oneindige lijst oplossing. Er is dus nog helemaal geen lijst als een LinkedListElement wordt aangemaakt. Pas als de gebruiker getRest() aanroept wordt de waarde van de lijst geevalueerd. Let wel: hij wordt slechts 1 element in de lijst verder geevalueerd :) .
code:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
package org.pandoramix.function.lazy.list;

import org.pandoramix.function.Function;
import org.pandoramix.function.lazy.Lazy;

public class LinkedListElement<E> extends LinkedList<E>
{
    private Lazy<E>                     _element;
    private Lazy<LinkedList<E>>         _rest;

    public LinkedListElement(Lazy<E> element, Lazy<LinkedList<E>> rest)
    {
        super();
        _element    = element;
        _rest       = rest;
    }

    public E getElement()
    {
        return _element.evaluate();
    }

    public LinkedList<E> getRest()
    {
        return _rest.evaluate();
    }

    public <R> R match(LinkedListFunction<E, R> function)
    {
        return function.matchedApply(this);
    }
}

Ok, dan nu de functie Cons. Die is ook lazy, maar dat is een stuk minder belangrijk. Cons neemt een element en een staart en maakt daar een lijst van. Het is eigenlijk gewoon een ingewikkelde manier om de LinkedListElement constructor aan te roepen :) .
code:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
package org.pandoramix.function.lazy.list;

import org.pandoramix.function.Function;
import org.pandoramix.function.lazy.Lazy;

// cons :: a -> [a] -> [a]
public class Cons<E> implements Function<Lazy<E>, Function<Lazy<LinkedList<E>>, Lazy<LinkedList<E>>>>
{
    public Function<Lazy<LinkedList<E>>, Lazy<LinkedList<E>>> apply(Lazy<E> head)
    {
        return new AnonymousResult1(head);
    }

    class AnonymousResult1 implements Function<Lazy<LinkedList<E>>, Lazy<LinkedList<E>>>
    {
        private Lazy<E> _head;

        public AnonymousResult1(Lazy<E> head)
        {
            super();
            _head = head;
        }

        public Lazy<LinkedList<E>> apply(Lazy<LinkedList<E>> tail)
        {
            return new AnonymousResult2(tail);
        }

        class AnonymousResult2 implements Lazy<LinkedList<E>>
        {
            private Lazy<LinkedList<E>> _tail;
            private LinkedList<E>       _result;

            public AnonymousResult2(Lazy<LinkedList<E>> tail)
            {
                super();
                _tail    = tail;
                _result = null;
            }

            public LinkedList<E> evaluate()
            {
                if(_result == null)
                {
                    _result = new LinkedListElement<E>(_head, _tail);
                }

                return _result;
            }

            public boolean isEvaluated()
            {
                return _result != null;
            }
        }
    }
}

Dan komt nu eindelijk de functie die oneindige lijsten aanmaakt: iterate. Iterate is een hele leuke functie. Het eerste argument is een functie van a -> a. Deze functie wordt gebruikt om steeds het volgende element van de lijst uit te rekenen. Het tweede argument is een a. Dit is de beginwaarde.

iterate (+1) 1 = [1, 2, 3, 4, 5, 6, ....
iterate (*2) 2 = [2, 4, 8, 16, 32, ....

Het is uiterst belangrijk dat het resultaat van de functie een Lazy lijst is. Anders zou het hele systeem niet werken. Uiteraard is deze functie recursief gedefinieerd.
code:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
package org.pandoramix.function.lazy.list;

import org.pandoramix.function.Function;
import org.pandoramix.function.lazy.Lazy;

//iterate :: (a -> a) -> a -> [a]
public class Iterate<E> implements Function<Function<Lazy<E>, Lazy<E>>, Function<Lazy<E>, Lazy<LinkedList<E>>>>
{
    public Function<Lazy<E>, Lazy<LinkedList<E>>> apply(Function<Lazy<E>, Lazy<E>> function)
    {
        return new AnonymousResult1(function);
    }

    class AnonymousResult1 implements Function<Lazy<E>, Lazy<LinkedList<E>>>
    {
        private Function<Lazy<E>, Lazy<E>> _function;

        public AnonymousResult1(Function<Lazy<E>, Lazy<E>> function)
        {
            super();
            _function = function;
        }

        public Lazy<LinkedList<E>> apply(Lazy<E> value)
        {
            return new AnonymousResult2(value);
        }

        class AnonymousResult2 implements Lazy<LinkedList<E>>
        {
            private Lazy<E>      _value;
            private LinkedList<E>   _result;

            public AnonymousResult2(Lazy<E> value)
            {
                super();
                _value  = value;
                _result = null;
            }

            public LinkedList<E> evaluate()
            {
                if(_result == null)
                {
                    Lazy<E>             nextValue   = _function.apply(_value);
                    Iterate<E>          recursion   = new Iterate<E>();
                    Lazy<LinkedList<E>> result      = recursion.apply(_function).apply(nextValue);
                    Cons<E>             cons        = new Cons<E>();

                    _result = cons.apply(_value).apply(result).evaluate();
                }

                return _result;
            }

            public boolean isEvaluated()
            {
                return _result != null;
            }
        }
    }
}

Ok, dan op het laast een zeer sumiere test klasse waarin ik een oneindige lijst aanmak met Iterate.
code:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
package org.pandoramix.function.lazy.list;

import org.pandoramix.function.Function;
import org.pandoramix.function.lazy.Lazy;
import org.pandoramix.function.lazy.NotLazy;
import org.pandoramix.function.lazy.Plus;

import junit.framework.Test;
import junit.framework.TestCase;
import junit.framework.TestSuite;

public class LazyListTest extends TestCase
{
    public LazyListTest(String name)
    {
        super(name);
    }

    public void testListCreate()
    {
        NotLazy<Integer>            integer     = new NotLazy<Integer>(new Integer(1));
        Plus                        plus        = new Plus();
        Iterate<Integer>            iterate     = new Iterate<Integer>();

        Lazy<LinkedList<Integer>>   lazyResult  = iterate.apply(plus.apply(integer)).apply(integer);
        LinkedList<Integer>      result     = lazyResult.evaluate();
    }

    public static Test suite()
    {
        TestSuite suite = new TestSuite(LazyListTest.class);
      return suite;
    }

}

Ik zal morgen wat betere tests schrijven. Ik ben van plan om dan de TakeWhile te implemeren zodat ik goed kan testen of de zaak werkt :) .

En nu is het tijd voor een tukkie :) .

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


Acties:
  • 0 Henk 'm!

  • mbravenboer
  • Registratie: Januari 2000
  • Laatst online: 07-10-2022
Hum, het is hier een beetje stil, maar ik begreep dat er wel mensen zijn die het met interesse lezen :) .

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


Acties:
  • 0 Henk 'm!

  • wasigh
  • Registratie: Januari 2001
  • Niet online

wasigh

wasigh.blogspot.com

lezen wel, begrijpen (nog) niet ;)
Want waarom heb je geparametizeerde typen nodig voor een oneindige linked list. Dat kan toch ook met gewone objecten en lazy evaluation?

Acties:
  • 0 Henk 'm!

  • B-Man
  • Registratie: Februari 2000
  • Niet online
Ik ga me morgen ook wat inlezen in deze materie, interessant!

Acties:
  • 0 Henk 'm!

  • mbravenboer
  • Registratie: Januari 2000
  • Laatst online: 07-10-2022
wasigh: Want waarom heb je geparametizeerde typen nodig voor een oneindige linked list. Dat kan toch ook met gewone objecten en lazy evaluation?
Dat klopt, maar om enigszins normaal functioneel te kunnen programmeren in Java heb je wel geparameterizeerde typen nodig. Zonder dat is het vrijwel onmogelijk om een mooie manier dergelijke dingen te doen. Je hebt dan te maken met generieke functies. Je kan die generieke functies echter niet typeren omdat ze voor alle objecten moeten werken. Nu kan dit echter wel omdat je ze gewoon parameterizeerd.

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


Acties:
  • 0 Henk 'm!

  • wasigh
  • Registratie: Januari 2001
  • Niet online

wasigh

wasigh.blogspot.com

Op maandag 06 augustus 2001 11:55 schreef mbravenboer het volgende:

[..]

Dat klopt, maar om enigszins normaal functioneel te kunnen programmeren in Java heb je wel geparameterizeerde typen nodig. Zonder dat is het vrijwel onmogelijk om een mooie manier dergelijke dingen te doen. Je hebt dan te maken met generieke functies. Je kan die generieke functies echter niet typeren omdat ze voor alle objecten moeten werken. Nu kan dit echter wel omdat je ze gewoon parameterizeerd.
Dat is het deel wat ik erg interresant vind :)
Write once, use everywhere! :D

Acties:
  • 0 Henk 'm!

  • mbravenboer
  • Registratie: Januari 2000
  • Laatst online: 07-10-2022
wasigh: Dat is het deel wat ik erg interresant vind :)
Write once, use everywhere! :D
Hehe :) De grap van deze implementatie is dat het precies aansluit op het FP paradigma. Een docent bij mij op de Universiteit is hier ook mee bezig, maar gebruikt geen geparameterizeerde typen. Dit zorgt voor grote problemen en code die eigenlijk zowel van OO als vanuit FP oogpunt niet erg fraai is.

Geparameterizeerde zijn echt een enorme krachtige toevoeging. Ik ben er nu al veel mee bezig en wat ik allemaal al voor mogelijkheden bedacht heb, is echt werkelijk fantastisch.

Het is alleen jammer dat ze niet hebben besloten om de Java bytecode ook aan te passen. Hopelijk bevatten de attributen zoveel informatie dat nieuwe VMs er toch op een verstandige manier mee om kunnen gaan.

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


Acties:
  • 0 Henk 'm!

  • farlane
  • Registratie: Maart 2000
  • Laatst online: 11:22
Jammer dat de opmaak niet echt lekker meegekopieerd wordt.... ;)

Somniferous whisperings of scarlet fields. Sleep calling me and in my dreams i wander. My reality is abandoned (I traverse afar). Not a care if I never everwake.


Acties:
  • 0 Henk 'm!

  • mbravenboer
  • Registratie: Januari 2000
  • Laatst online: 07-10-2022
farlane: Jammer dat de opmaak niet echt lekker meegekopieerd wordt.... ;)
Hum ja, de tab-spacing is geloof ik iets anders...

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


Acties:
  • 0 Henk 'm!

Verwijderd

Op maandag 06 augustus 2001 01:41 schreef mbravenboer het volgende:
Hier kan je er iets over lezen:

http://swen.uwaterloo.ca/~drayside/TALKS/GENERICITY/

De naam van de oplossing in Java zegt het eigenlijk al: geparameterizeerde typen. Een klasse is dus echt geparameterizeerd met een bepaald type. In C++ is een template echter in feite een generator van een familie van klassen. Echt een template dus. Type-checking van een template kan pas gebeuren nadat de klasse is gegeneerd. In Java is dit niet zo (slides vertellen het iets beter denk ik ;) , ik weet niet erg veel C++ )
Ik heb die slides bekeken, en het grote verschil dat ik kan vinden is idd. het moment waarop de typechecking gebeurt. Daarnaast zijn C++ templates niet de simpele macro-expansies die die slides doen voorkomen, anders was het parametriseren van member-functions niet mogelijk.

Het komt erop neer dat men bij Java achteraf parametrisch polymorfisme in de taal wil inbouwen net als bij C++, maar dat men bij Java bereid is dit ten koste van backwards-compatibility van de taal te doen.

(Op "templates are evil" ga ik niet in, gezien het feit dat moderne C++ geheel op template instantiaties is opgebouwd (STL).)

Acties:
  • 0 Henk 'm!

  • mbravenboer
  • Registratie: Januari 2000
  • Laatst online: 07-10-2022
mietje: Het komt erop neer dat men bij Java achteraf parametrisch polymorfisme in de taal wil inbouwen net als bij C++, maar dat men bij Java bereid is dit ten koste van backwards-compatibility van de taal te doen.
Klopt ongeveer (dit zijn ze bij C# overigens ook van plan. De eerste release zal dom genoeg geen geparameterizeerde typen bevatten |:( |:( ). De gecompileerde Java bytecode is echter wel backwards compatible omdat er anders grote problemen zouden ontstaan. In de Java bytecode worden namelijk gewoon casts toegevoegd. Er worden echter wel attributen met informatie over de geparameterizeerde typen bijgehouden zodat de nieuwe Java VMs die casts kunnen weglaten.

Overigens zitten er wel behoorlijk wat schoonheids problemen in de huidige specificatie. Er zijn dingen mogelijk of niet mogelijk die echt erg onlogisch en on-Java zijn.

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

Pagina: 1