Expression Trees - Espresso voor je code! nl

Door creator1988 op woensdag 15 december 2010 10:10 - Reacties (8)
Categorie: Backend, Views: 3.338

Eerder gepubliceerd als Expression Trees in .NET Magazine Q1 2010. Volledige artikel (PDF)

De in het .Net framework 3.5 ge´ntroduceerde ‘expression trees’, zijn absoluut het Microsoft equivalent van DeLonghi’s famous espresso: goed gedoseerd levert het een ongelooflijke boost, maar een kopje teveel en je stuitert alle kanten op.

In dit artikel gaan we in op de vraag wat expression trees zijn en hoe ze delen van je code tot honderd keer sneller kunnen maken. Laten we bij het begin beginnen: wat zijn expressions eigenlijk? Wellicht het meest eenvoudige stuk code demonstreert dit het beste:

C#:
1
1 + 2;



Dit is een expression pur sang. Het is namelijk: ‘An instruction to execute something that will return a value. ’Uiteraard kunnen we deze expression ook wat moeilijker maken, door twee variabelen te gebruiken:

C#:
1
a + b;



Omdat we soms de expression niet direct willen uitvoeren, kunnen we deze expression ook in een delegate stoppen. Een delegate is namelijk niets anders dan een expression, een uitvoerbaar stuk code, in een variabele:

C#:
1
PlusDelegate plus = delegate(int a, int b) { return a + b; };



Volledige artikel (PDF)

Volgende: Single byte string in C# 12-'10 Single byte string in C#
Volgende: Diakritische tekens en Soundex in .NET 12-'10 Diakritische tekens en Soundex in .NET

Reacties


Door Tweakers user dj_vibri, woensdag 15 december 2010 10:14

en dus een expression tree is... :/
nu ja, moet me sowieso verdiepen in "delegates", nooit het concept hiervan begrepen :)

update: nu pas gezien dat het letterlijk kopie is van de PDF, dan gaan we pdf doornemen :)

[Reactie gewijzigd op woensdag 15 december 2010 10:15]


Door Tweakers user creator1988, woensdag 15 december 2010 10:30

dj_vibri schreef op woensdag 15 december 2010 @ 10:14:
nu ja, moet me sowieso verdiepen in "delegates", nooit het concept hiervan begrepen :)
Een delegate is een variabele die een functie bevat. In Javascript is het bijvoorbeeld een heel bekend pattern:


JavaScript:
1
2
3
4
5
6
7
8
// roep de functie 'Foo' aan, met als parameter een functie
// Bij het aanroepen gebeurt er nog niets, want de functie wordt nog niet uitgevoerd
Foo ( function () { alert('hoi'); } );

function Foo (bar) {
     // bar is een functie, die kunnen we nu uitvoeren
     bar(); // alert('hoi');
}


Door Tweakers user SilentStorm, woensdag 15 december 2010 10:34

Dus eigenlijk is het 'gewoon' een closure?

In de meeste untyped talen kun je die al jaren gebruiken (bv javascript, python).

Bij java gaat er al jaren een discussie of de taal dit moet ondersteunen. Het belangrijkste tegenargument is dat de taal er behoorlijk wat complexer (en dus foutgevoeliger van wordt) en het belangrijkste argument voor is dat je bepaalde operaties nu veel efficienter kan programmeren, door de uit te voeren functie mee te geven, in plaats van een variabele, die de 'state' van een methode zet en aan de hand daarvan gaat werken.

Het gebruik van een expliciete delegate vind ik eigenlijk best een mooie oplossing, die ervoor zorgt dat je niet 'per ongelijk' tegen deze functionaliteit aanloopt, maar er wel gebruik van kan maken.

Oracle heeft net, kort na overname van Sun hun eigen (langer lopende) voorstel om closures (of 'lambda expressions') in te bouwen in de volgende versie van java doorgedrukt, dus we gaan iets soortgelijks daar ook zien over een jaar ofzo.

Het lijkt erop dat java closures meer volgens deze syntax gaan werken:


Java:
1
int i3 = #(int x)( x + 1 ).(3)


(dit is de functie en de invocatie ervan met argument (3) ineens)

Zie oa hier voor meer info.

[Reactie gewijzigd op woensdag 15 december 2010 10:34]


Door Tweakers user creator1988, woensdag 15 december 2010 10:52

SilentStorm schreef op woensdag 15 december 2010 @ 10:34:
Dus eigenlijk is het 'gewoon' een closure?
Ja delegates zijn closures, zit er in C# al vanaf C# 2.0 in. In 2007 zijn er 'Expression Trees' toegevoegd, die qua syntax hetzelfde zijn; maar in plaats van een pointer naar een functie, de functie als boom tonen. Je kunt de boom aflopen, veranderen, analyseren, etc. en daarna weer (runtime) compileren.

Dit biedt ook weer mogelijkheden voor DSL's, die C# runtime kunnen vertalen naar bijvoorbeeld SQL of XSLT (zie LINQ 2 SQL of LINQ 2 XML).
Bij java gaat er al jaren een discussie of de taal dit moet ondersteunen. Het belangrijkste tegenargument is dat de taal er behoorlijk wat complexer (en dus foutgevoeliger van wordt) en het belangrijkste argument voor is dat je bepaalde operaties nu veel efficienter kan programmeren, door de uit te voeren functie mee te geven, in plaats van een variabele, die de 'state' van een methode zet en aan de hand daarvan gaat werken.

Het gebruik van een expliciete delegate vind ik eigenlijk best een mooie oplossing, die ervoor zorgt dat je niet 'per ongelijk' tegen deze functionaliteit aanloopt, maar er wel gebruik van kan maken.

Oracle heeft net, kort na overname van Sun hun eigen (langer lopende) voorstel om closures (of 'lambda expressions') in te bouwen in de volgende versie van java doorgedrukt, dus we gaan iets soortgelijks daar ook zien over een jaar ofzo.

Het lijkt erop dat java closures meer volgens deze syntax gaan werken:


Java:
1
int i3 = #(int x)( x + 1 ).(3)


(dit is de functie en de invocatie ervan met argument (3) ineens)
Sowieso is het van de zotte dat een taal als Java op dit gebied al zo'n 7 jaar achterloopt op C#. Delegates zijn bijna wel een must als je met callbacks wilt werken etc. Ik hoor inmiddels al 3 jaar dat er volgend jaar echt closure-support komt in Java, dus ik heb de hoop een beetje opgegeven :-).

Overigens vind ik de .Net syntax wel netter, maar dat is persoonlijk:


C#:
1
2
Func<int, int> i_plus_1 = i => i + 1;
int i3 = i_plus_1(3);

[Reactie gewijzigd op woensdag 15 december 2010 10:52]


Door Tweakers user akakiwi, woensdag 15 december 2010 11:23

Even over je artikel, en dan met name de footer ervan.
Jij maakt in je vrije tijd Funda.nl?


Door Tweakers user ErikKo, woensdag 15 december 2010 12:43

En als je in zo'n expression zowel een disjunctie als een conjunctie gebruikt, Is het ook mogelijk left of right associativity te definieren? Dat lijkt me een van de eerste problemen waar je tegenop loopt wanneer je hiermee aan de slag gaat. Of is dat al gedefinieerd?

Door Tweakers user creator1988, woensdag 15 december 2010 13:02

ErikKo schreef op woensdag 15 december 2010 @ 12:43:
En als je in zo'n expression zowel een disjunctie als een conjunctie gebruikt, Is het ook mogelijk left of right associativity te definieren? Dat lijkt me een van de eerste problemen waar je tegenop loopt wanneer je hiermee aan de slag gaat. Of is dat al gedefinieerd?
Alle wiskundige operators zijn gerepresenteerd als binary expressions, waarbij je zelf de de left-side en de right-side kunt bepalen.

C#:
1
2
3
BinaryExpression test = Expression.AndAlso(Expression.Constant(false), Expression.Constant(true));

// test is nu: false AndAlso true


Zie ook het plaatje van de binary tree in het PDF doc.
akakiwi schreef op woensdag 15 december 2010 @ 11:23:
Even over je artikel, en dan met name de footer ervan.
Jij maakt in je vrije tijd Funda.nl?
Nooit author bio's serieus nemen :9

[Reactie gewijzigd op woensdag 15 december 2010 13:04]


Reageren is niet meer mogelijk