[C#] Datagridview + LINQ

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

Onderwerpen


Acties:
  • 0 Henk 'm!

  • BasSpruit
  • Registratie: September 2002
  • Laatst online: 09-04-2022
Ik heb een stukje code geschreven dat werkt.

C#:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
Person[] people = new Person[] { 
                new Person(12, "Piet"), 
                new Person(13, "Kees"), 
                new Person(10, "Jetje"), 
                new Person(15, "Miesje"), 
                new Person(22, "Piet"), 
                new Person(23, "Kees"), 
                new Person(20, "Jetje"), 
                new Person(25, "Miesje"), 
                new Person(12, "Piet"), 
                new Person(14, "Klaas"), 
                new Person(10, "Jetje"), 
                new Person(15, "Miesje")
            };

            var children = from p in people
                           orderby p.Name ascending, p.Age descending
                           select p;

            this.dataGridView1.DataSource = null;
            this.dataGridView1.DataSource = people;


ik verander bovenstaande stukje code (laatste regel), en het werkt niet meer...

C#:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
Person[] people = new Person[] { 
                new Person(12, "Piet"), 
                new Person(13, "Kees"), 
                new Person(10, "Jetje"), 
                new Person(15, "Miesje"), 
                new Person(22, "Piet"), 
                new Person(23, "Kees"), 
                new Person(20, "Jetje"), 
                new Person(25, "Miesje"), 
                new Person(12, "Piet"), 
                new Person(14, "Klaas"), 
                new Person(10, "Jetje"), 
                new Person(15, "Miesje")
            };

            var children = from p in people
                           orderby p.Name ascending, p.Age descending
                           select p;

            this.dataGridView1.DataSource = null;
            this.dataGridView1.DataSource = children;


wat doe ik fout? (of kan dit gewoon niet?)

Acties:
  • 0 Henk 'm!

  • TeeDee
  • Registratie: Februari 2001
  • Laatst online: 16:19

TeeDee

CQB 241

Krijg je een foutmelding?

Heart..pumps blood.Has nothing to do with emotion! Bored


Acties:
  • 0 Henk 'm!

  • BasSpruit
  • Registratie: September 2002
  • Laatst online: 09-04-2022
Nee, ik krijg geen foutmelding

Acties:
  • 0 Henk 'm!

  • TeeDee
  • Registratie: Februari 2001
  • Laatst online: 16:19

TeeDee

CQB 241

Wat heb je zoal al geprobeerd? Gezocht? Gevonden?
Moet je toevallig niet nog een DataBind ergens inplempen?

Heart..pumps blood.Has nothing to do with emotion! Bored


Acties:
  • 0 Henk 'm!

  • BasSpruit
  • Registratie: September 2002
  • Laatst online: 09-04-2022
TeeDee schreef op donderdag 10 januari 2008 @ 11:28:
Wat heb je zoal al geprobeerd? Gezocht? Gevonden?
Moet je toevallig niet nog een DataBind ergens inplempen?
zoeken heeft niks opgeleverd, vragen ook niet (hier lokaal)
en databind kan / hoeft niet in winforms

Acties:
  • 0 Henk 'm!

  • Mastermind
  • Registratie: Februari 2000
  • Laatst online: 01-09 22:18
people is een array, waar je inderdaad een datagridview aan kan binden, maar je wilt de datasource op children zetten. Wat staat er in children? Wat is 'var' voor iets :?

Acties:
  • 0 Henk 'm!

  • TeeDee
  • Registratie: Februari 2001
  • Laatst online: 16:19

TeeDee

CQB 241

offtopic:
.Net 3.5 afaik. Nog geen ervaring mee...
ChaosDream schreef op donderdag 10 januari 2008 @ 11:30:
[...]
zoeken heeft niks opgeleverd, vragen ook niet (hier lokaal)
en databind kan / hoeft niet in winforms
Define (hier lokaal). De GoT search? Ik vermoed dat deze na de upgrade nog gemaakt moet worden.

Moet je die var niet nog casten naar iets anders?

het is wel dat de info eruit getrokken moet worden he?

[ Voor 54% gewijzigd door TeeDee op 10-01-2008 11:38 ]

Heart..pumps blood.Has nothing to do with emotion! Bored


Acties:
  • 0 Henk 'm!

  • BasSpruit
  • Registratie: September 2002
  • Laatst online: 09-04-2022
Mastermind schreef op donderdag 10 januari 2008 @ 11:31:
people is een array, waar je inderdaad een datagridview aan kan binden, maar je wilt de datasource op children zetten. Wat staat er in children? Wat is 'var' voor iets :?
var dat heeft met LINQ te maken. en na een stukje klooien heeft eindelijk iemand mij naar het BindingSource object gewezen. nu werkt het wel

C#:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
Person[] people = new Person[] { 
                new Person(12, "Piet"), 
                new Person(13, "Kees"), 
                new Person(10, "Jetje"), 
                new Person(15, "Miesje"), 
                new Person(22, "Piet"), 
                new Person(23, "Kees"), 
                new Person(20, "Jetje"), 
                new Person(25, "Miesje"), 
                new Person(12, "Piet"), 
                new Person(14, "Klaas"), 
                new Person(10, "Jetje"), 
                new Person(15, "Miesje")
            };

            var children = from p in people
                           orderby p.Name ascending, p.Age descending
                           select p;

            BindingSource bs = new BindingSource();
            bs.DataSource = children;
            this.dataGridView1.DataSource = null;
            this.dataGridView1.DataSource = bs;

Acties:
  • 0 Henk 'm!

  • whoami
  • Registratie: December 2000
  • Laatst online: 13:23
var is in dit geval een variable van het type IEnumerable<Person>

https://fgheysels.github.io/


Acties:
  • 0 Henk 'm!

Verwijderd

Juist, dat var is voor de luiheid voor de programmeur in dit geval. Var is eigenlijk bedoeld voor anonymous types, waar het type dus niet van bekend is. In alle andere gevallen kun je var voorkomen.

Als je nog even ToList() had gedaan met je query, dus:
C#:
1
2
3
    List<Person> children = (from p in people 
                             orderby p.Name ascending, p.Age descending 
                             select p).ToList();

Dan werkt het wel.

Acties:
  • 0 Henk 'm!

  • whoami
  • Registratie: December 2000
  • Laatst online: 13:23
Idd.

Weet wel dat, in jouw voorbeeld (negerzoen), je 'linq query' al uitgevoerd wordt doordat je 'ToList()' doet.
In het geval van de topicstarter, zal de linq query pas uitgevoerd worden bij de creatie van de bindingsource of bij het databinden (zou eens moeten testen wanneer precies).

Als de topicstarter dit doet:
code:
1
2
3
4
5
6
7
8
string criteria = 'piet';

var result = from p in people where p.Name == criteria select p;

criteria = 'jan';

BindingSource s = new BindingSource(result);
dataGrid1.DataSource = s;
Zou hij wel eens onverwachte resultaten kunnen krijgen. :)

https://fgheysels.github.io/


Acties:
  • 0 Henk 'm!

  • BasSpruit
  • Registratie: September 2002
  • Laatst online: 09-04-2022
whoami schreef op donderdag 10 januari 2008 @ 13:52:
Idd.

Weet wel dat, in jouw voorbeeld (negerzoen), je 'linq query' al uitgevoerd wordt doordat je 'ToList()' doet.
In het geval van de topicstarter, zal de linq query pas uitgevoerd worden bij de creatie van de bindingsource of bij het databinden (zou eens moeten testen wanneer precies).

Als de topicstarter dit doet:
code:
1
2
3
4
5
6
7
8
string criteria = 'piet';

var result = from p in people where p.Name == criteria select p;

criteria = 'jan';

BindingSource s = new BindingSource(result);
dataGrid1.DataSource = s;
Zou hij wel eens onverwachte resultaten kunnen krijgen. :)
hier had ik dus nog niet eens aan gedacht...

Acties:
  • 0 Henk 'm!

Verwijderd

Wat whoami zegt over deferred execution in Linq kan inderdaad tot onverwachte resultaten leiden. In feite is zo'n query enkel een beschrijving met interface IEnumerable, waarin je dus ook variabelen als referentie kunt opnemen. Referenties naar variabelen die ineens buiten de scope vallen (bijvoorbeeld na het verlaten van een method) blijven netjes in stand.

Op het moment van het roepen van GetEnumerator van IEnumerable aanroept (impliciet met bijvoorbeeld een foreach statement) wordt de query uitgevoerd. Dit is op elk moment van databinding; de BindingSource houdt niet lokaal een gekopieerde lijst bij waardoor filteren en sorteren ook een taak is voor de achterliggende collection (of Linq statement dus). BindingList<T> wordt in een klap overbodig door Linq.

Als je het idee hebt dat deferred execution eerder tegen je kan werken dan in je voordeel, dan raad ik aan om gewoon ToList() te gebruiken. Je krijgt hiermee wel een tweede collectie van referenties naar je originele collectie (geen deep clone dus) en heeft daarom weinig overhead.

Acties:
  • 0 Henk 'm!

  • farlane
  • Registratie: Maart 2000
  • Laatst online: 11-09 12:01
Verwijderd schreef op donderdag 10 januari 2008 @ 13:43:
Juist, dat var is voor de luiheid voor de programmeur in dit geval. Var is eigenlijk bedoeld voor anonymous types, waar het type dus niet van bekend is.
Was var niet gewoon een shorthand voor <Het type van wat ik eraan toeken> als in:

C#:
1
var Blaat = new List<Person>();

ipv
C#:
1
List<Person> Blaat = new List<Person>();


Volgens mij is er niets onbekends en/of anonymous aan var. ( in C# anyway )

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!

  • whoami
  • Registratie: December 2000
  • Laatst online: 13:23
Het is idd mogelijk om dat te doen, maar, het is -imho- bad practice om dat te doen als je het type kent.
Waarom zou je , in jouw voorbeeld die Blaat als var declareren als je het type kent ?
Als var enkel zou bedoeld zijn als 'shorthand', dan zie ik er het nut niet van in, en dan hadden ze eigenlijk var gewoon uit de specs kunnen halen.

var is inderdaad bedoeld om, zoals negerzoen zegt, een oplossing te bieden voor 'anonymous types'. Stel dat je deze class hebt:
geen best practice die class, maar gewoon een kort illustratie-tje
code:
1
2
3
4
5
6
public class Person
{
     public int Id;
     public stirng Name;
     public DateTime DateOfBirth;
}

Stel, je hebt een collectie van Persons:
code:
1
2
List<Person> list = new List<Person>();
...


Als je nu een LINQ query wilt uitvoeren op die lijst, waarbij je bv enkel de naam en de geboortedatum van iedere persoon wilt, dan zal je moeten gebruik maken van var:
code:
1
var result = from p in list select p.Name, p.DateOfBirth

Je wilt hier nl. 2 gegevens per Person. Er is geen enkel type gedefinieerd waarin deze gegevens kunnen opgeslagen worden.
De compiler zal hier dus een nieuw type (anonymous type) genereren waarin deze gegevens opgeslagen worden. Je weet dus niet hoe dit type zal gaan noemen, en je hebt er ook geen definitie voor, dus: anonymous. Dus: var.

Als je dan dit doet:
code:
1
Console.WriteLine (result.GetType().ToString());

doet, dan zal je zien dat het idd een door de compiler gegeneerd type bevat.

[ Voor 5% gewijzigd door whoami op 11-01-2008 09:07 ]

https://fgheysels.github.io/


Acties:
  • 0 Henk 'm!

  • _Thanatos_
  • Registratie: Januari 2001
  • Laatst online: 05-09 14:39

_Thanatos_

Ja, en kaal

Juist, dat var is voor de luiheid voor de programmeur in dit geval
Dat moet je ff nuanceren, want het is niet voor de luiheid bedoeld. Het is bedoeld voor een programmeur die niet van tevoren weet (niet kan/mag weten) wat het type wordt, of het type simpelweg niet op te schrijven is. Dat laatste geval is vooral handig als je met LINQ (of zonder LINQ ;)) een anonymous class selecteert. Voorbeeldje:
C#:
1
var items = from n in foobar select new { n.foo, n.bar };

Zonder implicit variable declarations kom je daar nooit en te nimmer uit. Dus het is gewoon een noodzaak ;)

Ik zie dat de syntax highlighter van GoT nog op C# 3.0 aangepast moet worden

日本!🎌


Acties:
  • 0 Henk 'm!

  • farlane
  • Registratie: Maart 2000
  • Laatst online: 11-09 12:01
Ah ok, duidelijk. :)

Maar : Er is niets onbekends aan het resultaat van die LINQ query, anders zou de compiler er ook geen type voor kunnen genereren : Het zal hier dus iets van IEnumerable< Anonymous( string, DateTime ) > opleveren. In dat opzicht is het niet anders dan het voorbeeld dat ik geef.
Als var enkel zou bedoeld zijn als 'shorthand', dan zie ik er het nut niet van in, en dan hadden ze eigenlijk var gewoon uit de specs kunnen halen.
Dat kunnen ze ook, var is alleen maar verzonnen om te voorkomen dat je zelf types moet maken die enkel in een bepaalde situatie voorkomt. Het is een compleet overbodig keyword.

Je kunt alle situaties waarin var voorkomt omschrijven naar iets waar je het niet in nodig hebt.
_Thanatos_ schreef op zaterdag 12 januari 2008 @ 02:21:
Dat moet je ff nuanceren, want het is niet voor de luiheid bedoeld. Het is bedoeld voor een programmeur die niet van tevoren weet (niet kan/mag weten) wat het type wordt, of het type simpelweg niet op te schrijven is. Dat laatste geval is vooral handig als je met LINQ (of zonder LINQ ;)) een anonymous class selecteert. Voorbeeldje:
C#:
1
var items = from n in foobar select new { n.foo, n.bar };

Zonder implicit variable declarations kom je daar nooit en te nimmer uit. Dus het is gewoon een noodzaak ;)
Hoe kan een programmeur nou niet weten wat hier uitkomt ? Het is een type met 2 velden van het type van n.foo en n.bar. ( IEnumerable< Anonymous { typeof( n.foo ), typeof( n.bar ) } > )

Nogmaals, als de programmeur niet kan weten wat voor een type er uit komt, kan de compiler het ook niet.En aangezien C# een strong typed taal is kan het altijd.

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!

  • whoami
  • Registratie: December 2000
  • Laatst online: 13:23
Het type heet echt niet 'anonymous' ofzo; het type wordt gecreeërd door de compiler.

Kijk, als je dit eens laat lopen:
code:
1
2
3
4
5
6
7
8
9
10
11
12
13
List<Person> list = new List<Person>{
                                      new Person("whoami", "belgium", new DateTime(1978,12,14)),
                                      new Person("farlane", "holland",new DateTime(1978,5,7))
                                      };

var result = from p in list
                 select new
                  {
                      p.Name,
                      p.DateOfBirth
                 };

Console.WriteLine (result.GetType ().ToString ());


dan is de output:
code:
1
System.Linq.Enumerable+<SelectIterator>d__d`2[System.Int32,System.Int32]

Je kan niet weten welke naam er door de compiler aan gegeven wordt, en die naam kan ook niet voor ieder anonym type hetzelfde zijn. Het is nl. niet mogelijk om een variable die van een bepaald anoniem type is, toe te kennen aan een variable die een ander anoniem type is.

En, jij weet -als programmeur- ook niet welke naam de compiler aan dat type gaat geven.

Je hoeft zelfs zo moeilijk niet te doen om dat eens te testen; gewoon zo bv:
code:
1
2
var SomeType = new { FirstName = "melp", LastName="bliep" };
Console.WriteLine (SomeType.GetType().ToString());


Er gaat hier dus echt een nieuw, anoniem type gecreeërd worden; en deze feature is noodzakelijk om queries als bovenstaande mogelijk te maken.


(Ik vraag me, nu ik dat hier type, zelfs af of het mogelijk is om 2 variablen te creeëren die van een zelfde anonym type zijn ...)
edit:
ja dus, de compiler is wel zo slim:

code:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
var myVar = new
            {
                FirstName = "foo",
                LastName = "bar"
            };

var myVar2 = new
            {
                FirstName = "melp",
                LastName = "bliep"
            };

            
Console.WriteLine ("myVar: " + myVar.GetType ().ToString ());
Console.WriteLine ("myVar2: " + myVar2.GetType ().ToString ());

code:
1
2
myVar: <>f__AnonymousType0`2[System.String,System.String]
myVar2: <>f__AnonymousType0`2[System.String,System.String]



Gelukkig moet je een var - type initializeren bij de declaratie, en kan je, eens gedeclareerd ook geen variable van een ander type er aan toewijzen. :)

edit:
edit knop FTW

[ Voor 81% gewijzigd door whoami op 12-01-2008 10:17 ]

https://fgheysels.github.io/


Acties:
  • 0 Henk 'm!

  • farlane
  • Registratie: Maart 2000
  • Laatst online: 11-09 12:01
whoami schreef op zaterdag 12 januari 2008 @ 10:04:
Het type heet echt niet 'anonymous' ofzo; het type wordt gecreeërd door de compiler.
Da's duidelijk, gebruikte het alleen maar om aan te geven dat de naam van het type niet bekend is :)
Er gaat hier dus echt een nieuw, anoniem type gecreeërd worden; en deze feature is noodzakelijk om queries als bovenstaande mogelijk te maken.
Makkelijk ja, noodzakelijk niet. Als de compiler een type kan genereren kan ik dat ook :)

Het enige dat var je bespaart is het maken van types die je maar 1keer gebruikt ( bij bijvoorbeeld zo'n LINQ query ).

Er zijn overigens nog meer van dat soort dingen in 3.0 verzonnen. Die type initialisatie syntax bjvoorbeeld
code:
1
var items = from n in foobar select new { n.foo, n.bar };

is alleen maar verzonnen om te voorkomen dat je constructors moet gaan schrijven met typeof( n.foo ) en typeof( n.bar ) parameters in dit geval.

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!

  • whoami
  • Registratie: December 2000
  • Laatst online: 13:23
Al die dingen 'var / object initializers / etc...' zijn allemaal verzonnen omdat het nodig was om LINQ queries te maken zoals het nu mogelijk is.
Als je voor iedere keer je een dergelijke query wil gaan schrijven, types moet gaan creeëren, dan ben je wel even bezig ...

Stel eens dat deze features er niet waren, hoe ging een LINQ query er dan uit zien ?

https://fgheysels.github.io/


Acties:
  • 0 Henk 'm!

Verwijderd

_Thanatos_ schreef op zaterdag 12 januari 2008 @ 02:21:
[...]
Dat moet je ff nuanceren, want het is niet voor de luiheid bedoeld. Het is bedoeld voor een programmeur die niet van tevoren weet (niet kan/mag weten) wat het type wordt, of het type simpelweg niet op te schrijven is.
Klopt, maar er staat "in dit geval". Wat jij zegt klopt trouwens niet: je kunt áltijd het type weten, tenzij je een anonymous type constructor gebruikt wat nooit nodig is. Wat ik bedoel is dat je in alle gevallen var kunt gebruiken als je lui bent, en dat vind ik persoonlijk afdoen aan de striktheid van C#. Hier even het geval van "in dit geval":
C#:
1
2
3
var children = from p in people 
               orderby p.Name ascending, p.Age descending 
               select p;
Hier is het pure luiheid.

C#:
1
var i = 5;
Hier ook, maar niets mis mee. Vandaar luiheid.

Ze hadden eigenlijk var moeten verbieden voor niet anonymous types, maar daar worden dingen misschien helemaal onoverzichtelijk van. Anonymous types zijn gewoon ontstaan uit luiheid. Sowieso kun je gewoon ouderwets classes gebruiken, en sinds .NET 3.0 zit je al niet meer vast aan constructors en kun je nog makkelijker classes declareren, bijvoorbeeld:
C#:
1
2
3
4
5
public class Persoon
{
    public string Naam { get; set; }
    public int Leeftijd { get; set; }
}

En als volgt initialiseren:
C#:
1
Persoon persoon = new Persoon { Naam = "Johan", Leeftijd = 20 };

Dit maakt het allemaal al stukken eenvoudiger en stukken flexibeler, daar je niet aan var's vastzit die slechts geldig zijn binnen zijn scope.

Natuurlijk wil je alleen uit de database halen wat nodig is, en om voor elke query een eigen class te maken kost gewoon even tijd. Je selecteert wat je nodig hebt uit een database, zet dat in een var doet er het nodige mee. Dát is waar var voor mijn ogen voor is, maar je ziet nu al enorm veel "misbruik", ook in dit topic.
Stel eens dat deze features er niet waren, hoe ging een LINQ query er dan uit zien ?
Zo:
C#:
1
from k in klanten select new Persoon { Naam = k.Naam, Leeftijd = k.Leeftijd }

Geen anonymous types en een kleine moeite, maar met honderden (grote) queries is het gebruik van var wel erg aantrekkelijk en daar ook voor bedoeld.

[ Voor 7% gewijzigd door Verwijderd op 12-01-2008 14:53 ]


Acties:
  • 0 Henk 'm!

  • whoami
  • Registratie: December 2000
  • Laatst online: 13:23
Verwijderd schreef op zaterdag 12 januari 2008 @ 14:49:
[...]
sinds .NET 3.0 zit je al niet meer vast aan constructors en kun je nog makkelijker classes declareren, bijvoorbeeld:
C#:
1
2
3
4
5
public class Persoon
{
    public string Naam { get; set; }
    public int Leeftijd { get; set; }
}

En als volgt initialiseren:
C#:
1
Persoon persoon = new Persoon { Naam = "Johan", Leeftijd = 20 };

Dit maakt het allemaal al stukken eenvoudiger en stukken flexibeler, daar je niet aan var's vastzit die slechts geldig zijn binnen zijn scope.
Niet altijd .... Object initializers zoals in dit voorbeeld, kan je enkel gebruiken als je class een public default constructor heeft.
Natuurlijk wil je alleen uit de database halen wat nodig is, en om voor elke query een eigen class te maken kost gewoon even tijd. Je selecteert wat je nodig hebt uit een database, zet dat in een var doet er het nodige mee. Dát is waar var voor mijn ogen voor is
eens.
maar je ziet nu al enorm veel "misbruik", ook in dit topic.
Zoals ? Bijna alles in dit topic zijn ondertussen illustraties.

https://fgheysels.github.io/


Acties:
  • 0 Henk 'm!

  • whoami
  • Registratie: December 2000
  • Laatst online: 13:23
Verwijderd schreef op zaterdag 12 januari 2008 @ 14:49:
[...]

Zo:
C#:
1
from k in klanten select new Persoon { Naam = k.Naam, Leeftijd = k.Leeftijd }

Geen anonymous types en een kleine moeite, maar met honderden (grote) queries is het gebruik van var wel erg aantrekkelijk en daar ook voor bedoeld.
Ja, als je al een class Persoon hebt. Als je echter gewoon een paar gegevens wilt hebben, die niet passen binnen een reeds gedefinieerd type, dan kan je niet zonder var (tenzij je natuurlijk een type gaat maken, etc.. )

https://fgheysels.github.io/


Acties:
  • 0 Henk 'm!

  • KoW
  • Registratie: Juli 2001
  • Laatst online: 17-08-2022

KoW

Parse parsed te veel

offtopic:
Dit is waar ik nu al een tijdje naar op zoek ben. Eerder werkte ik met een database georienteerde taal en de meeste gemaakte programma's bestonden ook voor een groot deel uit SQL statements. Die eenvoud om SQL in je code te gebruiken was wat ik miste in .NET.

Acties:
  • 0 Henk 'm!

Verwijderd

whoami schreef op zaterdag 12 januari 2008 @ 14:54:
[...]
Niet altijd .... Object initializers zoals in dit voorbeeld, kan je enkel gebruiken als je class een public default constructor heeft.
Klopt, dat heeft een anonymous type net zo goed. Het nadeel daarvan, weet niet of je dat bedoelde, is dat je geen controle hebt over wat er precies in je class terecht komt. Met een constructor kan je velden verplicht maken door ze als parameters op te geven en ArgumentNullException te gooien als er iets null is wat niet mag. In die zin een pluspunt van anonymous types, omdat er alleen in komt wat je definieert. Maargoed, het heeft de nodige nadelen zoals het niet kunnen uitwisselen met code buiten de scope.
whoami schreef op zaterdag 12 januari 2008 @ 14:54:
[...]
Zoals ? Bijna alles in dit topic zijn ondertussen illustraties.
Ik doel daarmee op het gebruik van var waar het type wél bekend is in de vorm van IEnumerable<T> of IQueryable<T>. Of je het misbruik noemt is maar net hoe je het bekijkt. Ik had graag gezien dat de compiler een warning gaf bij gebruik van var waarvan het type wél bekend is.
whoami schreef op zaterdag 12 januari 2008 @ 14:55:
[...]
Ja, als je al een class Persoon hebt. Als je echter gewoon een paar gegevens wilt hebben, die niet passen binnen een reeds gedefinieerd type, dan kan je niet zonder var (tenzij je natuurlijk een type gaat maken, etc.. )
Daar zit hem net de crux: wil je nog wat met je data kunnen doen buiten je scope (bijvoorbeeld als je een class hebt voor data access) dan kan je geen anonymous types gebruiken en moet je zelf entities gaan maken. In alle andere gevallen kun je voor gemak gaan met var en aangezien tijd geld is, is dat vaak de beste keuze :)

Acties:
  • 0 Henk 'm!

  • whoami
  • Registratie: December 2000
  • Laatst online: 13:23
KoW schreef op zaterdag 12 januari 2008 @ 15:41:
offtopic:
Dit is waar ik nu al een tijdje naar op zoek ben. Eerder werkte ik met een database georienteerde taal en de meeste gemaakte programma's bestonden ook voor een groot deel uit SQL statements. Die eenvoud om SQL in je code te gebruiken was wat ik miste in .NET.
LINQ is geen vervanger voor SQL ofzo. Je hebt natuurlijk wel LINQ to SQL en LINQ for entities (net zoals je bv mappers hebt als NHibernate).

https://fgheysels.github.io/


Acties:
  • 0 Henk 'm!

  • KoW
  • Registratie: Juli 2001
  • Laatst online: 17-08-2022

KoW

Parse parsed te veel

Nee, maar je kunt wel query's loslaten op arrays van objecten.
* KoW heeft een aantal listview objecten en een serie (array) van eigen objecten.
met de data uit die eigen objecten wil ik wat leuke dingen doen.

Acties:
  • 0 Henk 'm!

Verwijderd

Ik denk dat de kracht van .NET 3.0 hem vooral zit in expression trees en extension methods; LINQ-to-* drijft op lambda expressions.

Acties:
  • 0 Henk 'm!

  • KoW
  • Registratie: Juli 2001
  • Laatst online: 17-08-2022

KoW

Parse parsed te veel

Dit artikel geeft erg duidelijk aan hoe het een en ander in elkaar steekt.

Erg leuk en krachtig wat je er allemaal mee kunt doen.

Acties:
  • 0 Henk 'm!

  • prototype
  • Registratie: Juni 2001
  • Niet online

prototype

Cheer Bear

LINQ is in essentie gewoon setnotation. Het interessante imho is dat het een universele manier hiermee aanbiedt voor setcomprehension, waarbij de implementatie er niet zoveel toe doet: of het nou een array is waar je mee werkt of een dataset, je behandelt ze op dezelfde abstractieniveau met LINQ.

Acties:
  • 0 Henk 'm!

  • EfBe
  • Registratie: Januari 2000
  • Niet online
prototype schreef op zaterdag 12 januari 2008 @ 23:34:
LINQ is in essentie gewoon setnotation. Het interessante imho is dat het een universele manier hiermee aanbiedt voor setcomprehension, waarbij de implementatie er niet zoveel toe doet: of het nou een array is waar je mee werkt of een dataset, je behandelt ze op dezelfde abstractieniveau met LINQ.
Nee, LINQ heeft niets met sets te maken, LINQ is sequence based, niet set based. Dit is een verschil, omdat bij sets bv je niet 'takewhile' kunt doen maar bij sequences juist wel.

Creator of: LLBLGen Pro | Camera mods for games
Photography portfolio: https://fransbouma.com


Acties:
  • 0 Henk 'm!

  • prototype
  • Registratie: Juni 2001
  • Niet online

prototype

Cheer Bear

EfBe schreef op zondag 13 januari 2008 @ 11:14:
[...]

Nee, LINQ heeft niets met sets te maken, LINQ is sequence based, niet set based. Dit is een verschil, omdat bij sets bv je niet 'takewhile' kunt doen maar bij sequences juist wel.
Als je met sequence based bedoelt lijst gebaseerd dan is dit alsnog uit te drukken in setnotatie, namelijk een set van 2-tuples (K,V), waarbij K de index aanduidt en V de waarde. Die takewhile is prima te beschrijven met setcomprehension: de set van (K,V) met een predicaat P en waarbij K vanaf 0 'continu' verloopt.

Acties:
  • 0 Henk 'm!

Verwijderd

Deze termen zeggen mij vrij weinig, maar met een beetje common sense is dit hetzelfde onderscheid als tussen for en foreach? Waar je bij een for-loop dus met een index werkt met een bepaalde conditie (bijv i < count), en met foreach met een enumerator die niets van lengte hoeft te weten en alleen de volgende pakt als die er is (sequence). Als dat is wat jullie bedoelen, dan is LINQ puur gebaseerd op sequences. In theorie kan LINQ die sequences asynchroon opbouwen, net als dat yield return in theorie asynchroon zou kunnen. Dit kan met sets niet.

[ Voor 14% gewijzigd door Verwijderd op 13-01-2008 15:30 ]


Acties:
  • 0 Henk 'm!

  • prototype
  • Registratie: Juni 2001
  • Niet online

prototype

Cheer Bear

Verwijderd schreef op zondag 13 januari 2008 @ 15:28:
Deze termen zeggen mij vrij weinig, maar met een beetje common sense is dit hetzelfde onderscheid als tussen for en foreach? Waar je bij een for-loop dus met een index werkt met een bepaalde conditie (bijv i < count), en met foreach met een enumerator die niets van lengte hoeft te weten en alleen de volgende pakt als die er is (sequence). Als dat is wat jullie bedoelen, dan is LINQ puur gebaseerd op sequences. In theorie kan LINQ die sequences asynchroon opbouwen, net als dat yield return in theorie asynchroon zou kunnen. Dit kan met sets niet.
Het is jammer dat deze termen je vrij weinig zeggen, want deze komen gewoon uit de discrete wiskunde (dat in het basispakkket hoort van elke informaticus).

Sequences zijn uit te drukken in sets, net als dat functies uit te drukken zijn in sets. Misschien wordt het duidelijker met een concreet voorbeeld (formeel in Z genoteerd naar mijn beste herinnering er nog van, wat ook imho in het basispakket hoort van elke informaticus):
code:
1
2
3
4
5
6
7
8
9
10
foobar:SEQ
______________________
foobar = <a, b, c, ...>

Is equivalent met:

foobar2: N1 ---> VALUES
______________________

foobar2 = {(1,a), (2,b),(3,c),...}


Hierin stelt foobar dus een sequence voor, en wel zo dat a gevolgd wordt door b die vervolgens weer gevolgd wordt door c etc...
In foobar2 heb ik dit herschreven naar een set van paren, waarbij de eerste veld van het paar de index aanduidt en de tweede veld van het paar de waarde. In het bijzonder is foobar2 een volledige functie die een element uit het domein N1 (natuurlijke getallen vanaf 1 inclusief) mapped naar een element uit het bereik VALUES. (Met wat common sense is in te zien dat dit gewoon een wiskundige functie is).

Hieruit volgt dus dat alles wat je op sequences toe kan passen, je ook kan toepassen op de equivalente setuitdrukking...

De geinteresseerde lezer doet er goed aan om zich te verdiepen in formele methoden. ;)

P.S. Je analogie ontgaat mij, ik weet wel wat je zegt, maar ik zie niet wat voor relevantie dit heeft, maar dat kan ook misschien aan mijn common sense liggen :P ;)

Acties:
  • 0 Henk 'm!

  • RayNbow
  • Registratie: Maart 2003
  • Nu online

RayNbow

Kirika <3

LINQ is gewoon monadic. :Y)

Iets als dit...
C#:
1
2
3
IEnumerable<string> justNames =
    from e in x.Descendants("Person")
    select e.Value;
...kan je herschrijven naar dit in Haskell:

Haskell:
1
2
justNames = do e <- (x `descendants` "Person")
               return (value e)


...wat syntactische suiker is voor:

Haskell:
1
justNames = (x `descendants` "Person")   >>=   \e -> return (value e)



Voor een introductie wat Monads precies zijn, zie o.a. Brian Beckman: Don't fear the Monads (video).

Edit: en nog een linkje, Monads and Schroedinger’s cat

[ Voor 9% gewijzigd door RayNbow op 14-01-2008 00:23 . Reden: (3 missende spaties in code) ]

Ipsa Scientia Potestas Est
NNID: ShinNoNoir


Acties:
  • 0 Henk 'm!

  • KoW
  • Registratie: Juli 2001
  • Laatst online: 17-08-2022

KoW

Parse parsed te veel

offtopic:
* KoW heeft het idee dat er een beetje veel met wetenschappelijke termen gegooid wordt en dat de inhoud wat naar de achtergrond verdwijnt.

Acties:
  • 0 Henk 'm!

  • EfBe
  • Registratie: Januari 2000
  • Niet online
prototype schreef op zondag 13 januari 2008 @ 13:53:
[...]
Als je met sequence based bedoelt lijst gebaseerd dan is dit alsnog uit te drukken in setnotatie, namelijk een set van 2-tuples (K,V), waarbij K de index aanduidt en V de waarde. Die takewhile is prima te beschrijven met setcomprehension: de set van (K,V) met een predicaat P en waarbij K vanaf 0 'continu' verloopt.
Dat kan niet, want je zou dan vooraf de order van de set moeten bepalen, en een set heeft geen order. Wat jij beschrijft is een projectie uitlezen middels een zekere operatie. Prima, maar dat is geen set, maar een sequence. Dit is ook de reden waarom een tabel per definitie geen order heeft, een projectie kan een order hebben, maar dan alleen als operatie na de projectie.

Geloof me, als je Linq bouwstenen als sets gaat zien loop je echt vast. Zie ze als sequences.

Creator of: LLBLGen Pro | Camera mods for games
Photography portfolio: https://fransbouma.com


Acties:
  • 0 Henk 'm!

  • prototype
  • Registratie: Juni 2001
  • Niet online

prototype

Cheer Bear

EfBe schreef op zondag 13 januari 2008 @ 21:41:
[...]

Dat kan niet, want je zou dan vooraf de order van de set moeten bepalen, en een set heeft geen order. Wat jij beschrijft is een projectie uitlezen middels een zekere operatie. Prima, maar dat is geen set, maar een sequence. Dit is ook de reden waarom een tabel per definitie geen order heeft, een projectie kan een order hebben, maar dan alleen als operatie na de projectie.

Geloof me, als je Linq bouwstenen als sets gaat zien loop je echt vast. Zie ze als sequences.
Zoals ik in mijn eerste en tweede post duidelijk probeer te maken is een sequence uit te drukken als een set: de Set doet welliswaar geen uitspraak over volgorde, maar de WAARDEN van de set wel (niet om te schreeuwen, maar om te benadrukken :)).

De 'order' (i.e. volgorde) wordt in het bijzonder opgeslagen in de eerste veld van de 2-tuple, namelijk de index. Voor een tabel gaat hetzelfde verhaal op, namelijk dat deze equivalent uit te drukken is in setnotatie, namelijk de set van n-tuples... (e.g. FooBarTabel(Id, Sjaak, Trekhaak) === {(Id, Sjaak, Trekhaak)}). Alle queries die je hierop los kan laten ook, zie: Gegevensbanken sheets van Dr. Fokkinga.

Overigens refereer ik nergens naar 'operaties', maar daar later meer over in de P.S. In mijn Z voorbeelden is enkel tot op heden sprake van declaraties en axioma's.

Laat ik het iig in concretere woorden stellen: kan jij een List implementeren met een Set? In (verkorte) pseudo javacode (ligt me beter) zal het er ongeveer zo uitzien, aangezien ik geen zin heb om de hele List interface te implementen ;-):

Java:
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
63
64
65
66
67
68
69
70
71
72
73
74
75
76
/**
 * @author prototype of #devschuur / gathering.tweakers.net ;-)
 */
public class SetList<T> implements List<T> {

    private Set<Tuple<T>> collection;

    public static class Tuple<T> {
        public int index;
        public T value; 
        
        @Override
        public boolean equals(Tuple<T> t) {
            return this.index == t.index
                    && this.value.equals(t.value);
        }
    }

    public <T> SetList() {
        this.collection = new HashSet<Tuple<T>>();
    }

    public void add(T o) {
        Tuple<T> kv = new Tuple<T>();
        kv.index = this.collection.size();
        kv.value = o;
        
        this.collection.add(kv);
    }
    
    /**
     * @require 0 <= i < this.size();
     */
    public T get(int i) {
        if (i < 0 || i >= this.collection.size()) {
            throw new IndexOutOfBoundsException();
        }
        
        for(Tuple<T> kv : this.collection) {
            if (kv.index == i) {
                return kv.value;
            }
        }
        
        return null;
    }

    public boolean contains(T o) {
        for(Tuple<T> kv : this.collection) {
            if (kv.value.equals(o)) {
                return true;
            }
        }
        
        return false;
    }

    public void remove(T o) {
        for(Tuple<T> kv : this.collection) {
            if (kv.value.equals(o)) {
                this.collection.remove(kv);
                for(Tuple<T> kv2 : this.collection) {
                    if(kv2.index > kv.index) {
                        kv2.index--;
                    }
                }
            }
        }
    }

    public int size() {
        return this.collection.size();
    }
    
    // ...
}


Zoals je ziet is mijn SetList gewoon gebacked met een Set van paren zoals ik dit ook gespecificeerd heb in m'n Z schema: een sequence is equivalent aan de set van 2-tuples (K,V), waarvan de code hierboven een implementatie van is. Q.E.D. dacht ik zo :)

Misschien wordt m'n punt kristalhelder wanneer ik een LINQ statement als:
C#:
1
2
3
from p in people
where p.Age >= 22
select p; 


Equivalent herschrijf naar setnotatie:
{ p:people | p.Age >= 22 @ p }

Ook 'projecties' zoals jij ze noemt zijn uit te drukken in sets. Een projectie van het ene domein naar het andere, e.g. f:Z-->N0( x ) = x^2 is immers niks anders dan {..., (-2, 4), (-1, 1), (0, 0), (1, 1), (2, 4), (3, 9), ...}

Zoals ik al zei, LINQ is in essentie een mechanisme om te faciliteren in setcomprehension. Order by, takewhile etc... zijn iets lastiger, maar zeker te doen: de geinteresseerde lezer verwijs ik naar "the way of Z" boek (voor formele methoden in software engineering) en functioneel programmeren (zie Raynbow ;)).

P.S. Even om m'n studie ontwijkend gedrag tegemoet te komen en terugkomend op:
EfBe schreef op zondag 13 januari 2008 @ 11:14:
[...]

Nee, LINQ heeft niets met sets te maken, LINQ is sequence based, niet set based. Dit is een verschil, omdat bij sets bv je niet 'takewhile' kunt doen maar bij sequences juist wel.
Voor de volledigheid ditmaal heel concreet en om RayNbow tegemoet te komen met z'n Haskell obsessie:
Haskell:
1
takeWhile(<3)[1,2,3,4,5,2,1]


Bovenstaande stelt een takewhile voor op een lijst <1,2,3,4,5,2,1> met de voorwaarde dat een waarde uit de lijst kleiner is dan 3. Als result zou je dus moeten krijgen <1,2> en dat is zoals nu hopelijk duidelijk is in dit geval equivalent aan {(1,1), (2,2)}

Zou zich in setnotatie vertalen naar:
code:
1
2
3
4
5
6
7
neem nummers = { (k,v) }, dan:

nummers = { (1,1), (2,2), (3,3), (4,4), (5,5), (6,2), (7,1) }

{n:nummers | n.v < 3 & "n.k verloopt continu vanaf 1"
{n:nummers | n.v < 3 & "er bestaat niet een natuurlijke getal x vanaf 1 waarvoor geldt: x < n.k en er bestaat een n2 uit nummers waarvoor geldt: n2.k = x en n2.v >= 3" @ n }
{n:nummers | n.v < 3 & (NOT EXISTS x:N1 @ x < n.k & (EXISTS n2:nummers @ n2.k = x & n2.v >= 3)) @ n }


Dit kan ik natuurlijk generaliseren door takewhile te specificeren als een operatie in een taal als Z, maar je ziet nu dat het dus wel degelijk mogelijk is om met alleen setcomprehension een takewhile te doen (doordat sequences uit te drukken zijn in sets). Op vergelijkbare wijze kan ik de rest van de standard query operators van LINQ e.g. concat etc... ook herschrijven naar setnotatie, en wanneer ik tijd teveel heb zal ik dat ook wel een keer bloggen ;) Ik zie dus iig niet hoe ik zou moeten vastlopen dus ;) Misschien kan je een tegenvoorbeeld geven?

Ik heb iig de 'takewhile' getest met SQL door de setnotatie te herschrijven naar SQL, en dit geeft:

Content van nummers(id:Integer, value:Integer):
Afbeeldingslocatie: http://ninh.nl/linq1.png

Content van N1(id:Integer)
Afbeeldingslocatie: http://ninh.nl/linq2.png

Resultaat 'takewhile' query
Afbeeldingslocatie: http://ninh.nl/linq3.png

Q.E.D. numero duo dacht ik zo ;)

[ Voor 90% gewijzigd door prototype op 14-01-2008 09:27 . Reden: Even voorbeeld erbij gezet van LINQ statements naar setnotatie, takewhile in setnotatie + predicaten etc... + foutje in code gefixed. ]


Acties:
  • 0 Henk 'm!

  • farlane
  • Registratie: Maart 2000
  • Laatst online: 11-09 12:01
Hehe, ik vraag me af of de discussie tussen jullie twee wel geheel onopic is maar van mij krijgt je in ieder geval een publieksprijs voor de volledigheid en uitvoering van je onderbouwing.

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!

  • prototype
  • Registratie: Juni 2001
  • Niet online

prototype

Cheer Bear

farlane schreef op maandag 14 januari 2008 @ 09:03:
Hehe, ik vraag me af of de discussie tussen jullie twee wel geheel onopic is maar van mij krijgt je in ieder geval een publieksprijs voor de volledigheid en uitvoering van je onderbouwing.
Hehe, daar deed ik 't ook voor :+ ;), maar eigenlijk meer om m'n minor huiswerkopdrachten te ontwijken ugh.... misschien trouwens een goed idee om dit topic even te splitsen ;)

Acties:
  • 0 Henk 'm!

  • EfBe
  • Registratie: Januari 2000
  • Niet online
Het probleem met deze discussie is dat deze uitmond in geneuzel. Als jij wilt blijven volhouden dat Linq een set based systeem is, prima, maar het is niet een setbased systeem, maar een sequence based systeem. TakeWhile kan alleen als je je de sortering van de projected results zelf kunt bepalen (nl. op de elements in de predicate operand van TakeWhile). Het gaat fout wanneer je sorteert op een related element, bv. je sorteert orders op het land van hun related customer. Als je dan TakeWhile loslaat op de projected set van orders, dan werkt het niet, want je kunt niet werken met een predicate in de SQL query, je moet sequentieel door de projected results heen. M.a.w.: het gaat dan dus mis. Er zijn meerdere voorbeelden: bv Last, en ElementAt. Last lijkt wel te doen, maar is het niet, je moet nl. de order by uit de linq query knippen en inverten, en dat is niet altijd mogelijk, bv wanneer je sorteert op een related entity. Maak niet de fout dat je middels een sequence het antwoord gaat vinden, want dat is niet de bedoeling.

Ook ik maakte eerst de fout door te denken dat het set-oriented was, maar dat bleek niet waar. Linq heeft bv GroupJoin, welke een pure sequence oriented operatie is. je kunt hem wel simuleren tot op zekere hoogte met een set oriented taal, maar toch ook weer niet. In Linq vind je bv geen left / right outer join operaties. Je vindt er een test op een lege sequence, die dienst doet als left join simulatie, je kunt hem nl. gebruiken om een cross join om te zetten in een left join, maar triviaal is dat niet, immers het is een operatie op een sequence (IEnumerable): DefaultIfEmpty, niet op een set.

MS zelf zegt dat het sequence based is, maar jij mag van mij best blijven volhouden dat het set based is. Zelf ben ik al meer dan 3 maanden bezig met een linq provider en met een set oriented aanpak kom je er helaas niet: je moet telkens zoeken naar hoe je de linq operands omschrijft naar sets en de operaties naar set operaties en dat lukt gewoon niet altijd. Linq to Sql geeft bv ook gewoon op bij ElementAt en Last en dat is logisch: er is nl. geen oplossing mogelijk in SQL. Dit is geen limitatie van SQL, je kunt de set die resulteert van de query alleen gebruiken voor de oplossing als je hem ziet als een sequence. Maar helaas voor de set, een sequence heeft een eigenschap die de set niet heeft: hij kan in een bepaalde volgorde doorlopen worden met een operatie.

(edit) Nog even een voorbeeld voor TakeWhile en waarom het misgaat bij sets. Stel je hebt orders, en je sorteert deze op het land van de related Customer, ascending. Nu wil je alle Orders inlezen waarbij het EmployeeID attribute van de order < 4. Het gaat even niet om de zinnigheid van het voorbeeld, maar om het feit of het mogelijk is.

Stel de projected set van orders heeft, door de sortering op customer.Country, de volgende volgorde voor EmployeeID: 1, 2, 3, 1, 4, 1, 2

In een set oriented taal, pas je een operatie toe op de set en daaruit verkrijg je een nieuwe set, het resultaat van de operatie. De predicate, order.EmployeeId < 4 kan niet toegepast worden op deze set, want je krijgt dan 6 resultaten, terwijl TakeWhile maar 4 resultaten oplevert!

In Linq is TakeWhile echter gewoon gedefinieerd. Dit kan ook, want Linq is gebaseerd op sequences en wanneer je ipv een set een sequence neemt van orders die gesorteerd is op customer.Country, dan werkt TakeWhile gewoon: je doorloopt de sequence totdat de predicate niet meer waar is, wat dus 4 resultaten oplevert in het bovenstaande voorbeeld.

Verder is jouw SQL query flawed, want je bouwt een check in op id, en dat daarop gesorteerd is. Maar dat is niet altijd het geval, en in de gevallen dat dat dus NIET het geval is, moet TakeWhile OOK werken, en dat is dan niet zo (zie boven).

Ik moet er bij zeggen dat als mensen met QED beginnen, ik eigenlijk al bij voorbaat afhaak (vanwege de potentiele ellenlange discussie), maar omdat ik weet dat het belangrijk is dat mensen begrijpen dat Linq niet set based is maar sequence based heb ik deze reply geschreven. Wanneer mensen onthouden dat Linq sequence based is, hebben ze minder problemen met het schrijven van Linq queries en het begrijpen waarom sommige linq queries niet kunnen in een database bijvoorbeeld, waarom er geen left/right join in zit, waarom er een groupjoin in zit, waarom linq een serie van extension method calls is die de input sequentieel processed en de output als een sequence oplevert, etc.

[ Voor 28% gewijzigd door EfBe op 14-01-2008 10:54 ]

Creator of: LLBLGen Pro | Camera mods for games
Photography portfolio: https://fransbouma.com


Acties:
  • 0 Henk 'm!

  • prototype
  • Registratie: Juni 2001
  • Niet online

prototype

Cheer Bear

Even snel tussendoor EfBe, ik weet niet hoe het met jou zit, maar ik geniet zeer van deze discussie :) en zou dit dan graag ook voort willen zetten. Ik weet niet hoe jij erover voelt, want ik vermoed dat dit een ellenlange discussie gaat worden, en zou dan ook een mod willen vragen om dit te splitten aangezien het behoorlijk OT is geworden tov de TS post, leerzaam wel ;).

Momenteel ben ik even bezig met m'n minor opdracht, en van wat je als laatste hebt gepost heb ik veel op aan te merken nog en zou dat graag nu willen doen, maar 'k heb een deadline dus dat hou je van me tegoed, hopelijk kom ik er vandaag nog aan toe.

In a nutshell is mijn punt ook geweest dat doordat je een sequence equivalent kan uitdrukken in een set, alle operaties waarvan jij nu zegt dat ze alleen weggelegd zijn voor sequences, ook toepasbaar zijn op de equivalente set notatie van de sequence. Wat ik in feite hiermee zeg is dat het even setgebaseerd is als dat het sequencegebaseerd is. Daar heb ik dan ook alle afleidingen er voor bij geleverd.

Wel wil ik snel inhaken op:
EfBe schreef op maandag 14 januari 2008 @ 09:58:
(edit) Nog even een voorbeeld voor TakeWhile en waarom het misgaat bij sets. Stel je hebt orders, en je sorteert deze op het land van de related Customer, ascending. Nu wil je alle Orders inlezen waarbij het EmployeeID attribute van de order < 4. Het gaat even niet om de zinnigheid van het voorbeeld, maar om het feit of het mogelijk is.

Stel de projected set van orders heeft, door de sortering op customer.Country, de volgende volgorde voor EmployeeID: 1, 2, 3, 1, 4, 1, 2

In een set oriented taal, pas je een operatie toe op de set en daaruit verkrijg je een nieuwe set, het resultaat van de operatie. De predicate, order.EmployeeId < 4 kan niet toegepast worden op deze set, want je krijgt dan 6 resultaten, terwijl TakeWhile maar 4 resultaten oplevert!

In Linq is TakeWhile echter gewoon gedefinieerd. Dit kan ook, want Linq is gebaseerd op sequences en wanneer je ipv een set een sequence neemt van orders die gesorteerd is op customer.Country, dan werkt TakeWhile gewoon: je doorloopt de sequence totdat de predicate niet meer waar is, wat dus 4 resultaten oplevert in het bovenstaande voorbeeld.
Het voorbeeld dat je hier plaatst heb ik reeds behandeld in mijn voorgaande post (inclusief wiskundige afleiding). :) En zoals je ook in de screenshots ziet krijg ik bij mijn takewhile 2 resultaten terug ipv 4, en dat is bewerkstelligd mbv quantorpredicaten. Vanzelfsprekend zou je zonder die non-existentiele icm existentiele quantor 4 resultaten terugkrijgen. Hier hou je dus geen rekening bij jouw uitleg over 'het probleem' :).
Verder is jouw SQL query flawed, want je bouwt een check in op id, en dat daarop gesorteerd is. Maar dat is niet altijd het geval, en in de gevallen dat dat dus NIET het geval is, moet TakeWhile OOK werken, en dat is dan niet zo (zie boven).
Sorry, ik snap even niet wat je bedoelt met dat hier iets flawed aan is. De id column hier is niets anders dan de positie van het element in de sequence, en wanneer we een sequence gaan beschrijven als zijnde een functie/projectie/set van 2-tuples, dan moet de index veld vanzelfsprekend continu oplopend zijn vanaf een bepaalde waarde, e.g. 0 (of 1 zoals ik nu doe omdat dit conform is aan Z conventie) (dat is bij een List<T> toch ook niet anders? :)).

Acties:
  • 0 Henk 'm!

  • EfBe
  • Registratie: Januari 2000
  • Niet online
prototype schreef op maandag 14 januari 2008 @ 11:26:
Even snel tussendoor EfBe, ik weet niet hoe het met jou zit, maar ik geniet zeer van deze discussie :) en zou dit dan graag ook voort willen zetten. Ik weet niet hoe jij erover voelt, want ik vermoed dat dit een ellenlange discussie gaat worden, en zou dan ook een mod willen vragen om dit te splitten aangezien het behoorlijk OT is geworden tov de TS post, leerzaam wel ;).
Nou, een discussie waarbij het een herhaling van zetten wordt is niet meer zo aan me besteed ;)
Momenteel ben ik even bezig met m'n minor opdracht, en van wat je als laatste hebt gepost heb ik veel op aan te merken nog en zou dat graag nu willen doen, maar 'k heb een deadline dus dat hou je van me tegoed, hopelijk kom ik er vandaag nog aan toe.
Veel op aan te merken? Wat valt er op aan te merken? _ALLES_ in linq is een sequence, niet een set. Een sequence is wel een set, maar een set is geen sequence. Als je Linq gaat beschouwen als set based, dan MOET je dus de operaties kunnen uitvoeren zonder terug te vallen op sequence-eigenschappen, en sorry, maar dat kan niet altijd. Het is om deze reden dat ik uberhaupt nog heb gereplied: mensen moeten doorhebben dat Linq sequence oriented is, en dus dat linq werkt omdat het met sequences werkt en niet met sets, m.a.w.: het bouwt op de eigenschap dat een sequence een volgorde heeft en dat heeft een set nu eenmaal niet.
In a nutshell is mijn punt ook geweest dat doordat je een sequence equivalent kan uitdrukken in een set, alle operaties waarvan jij nu zegt dat ze alleen weggelegd zijn voor sequences, ook toepasbaar zijn op de equivalente set notatie van de sequence. Wat ik in feite hiermee zeg is dat het even setgebaseerd is als dat het sequencegebaseerd is. Daar heb ik dan ook alle afleidingen er voor bij geleverd.
Als het set-gebaseerd is, dan moet je middels set algebra kunnen beschrijven hoe Reverse werkt op een willekeurige set van orders gesorteerd op order.Customer.Country. Dat gaat je niet lukken.
Evenals ElementAt(n). Het is nl. zo dat je ElementAt(n) alleen kunt uitvoeren wanneer je de input beschouwt als een sequence, want je doorloopt de sequence tot element n. Een set heeft geen sequentiele consumer, enumerator.
Wel wil ik snel inhaken op:
[...]
Het voorbeeld dat je hier plaatst heb ik reeds behandeld in mijn voorgaande post (inclusief wiskundige afleiding). :)
Nee, jouw voorbeeld doet een aanname die niet opgaat in mijn voorbeeld.
En zoals je ook in de screenshots ziet krijg ik bij mijn takewhile 2 resultaten terug ipv 4, en dat is bewerkstelligd mbv quantorpredicaten. Vanzelfsprekend zou je zonder die non-existentiele icm existentiele quantor 4 resultaten terugkrijgen. Hier hou je dus geen rekening bij jouw uitleg over 'het probleem' :).
Jij moet een aparte set erbij betrekken die een sequence formuleert. Sorry, maar dat gaat niet op. In mijn voorbeeld heb ik die sequence niet en dan lukt jouw voorbeeld dus niet. Tja, ik kan ook roepen dat ik het resultaat in een temptable dump en met een cursor het geheel eruit haal, maar dat was niet het punt, het punt was dat met louter set operaties ik die elementen er niet uitkrijg. Jij hebt een extra set nodig, N1, en OOK nog de aanname dat de elements in de resultset met een oplopende id zijn gerangschikt. Wat als ik GUIDs als key gebruik in mijn Order entity ?
[...]
Sorry, ik snap even niet wat je bedoelt met dat hier iets flawed aan is. De id column hier is niets anders dan de positie van het element in de sequence, en wanneer we een sequence gaan beschrijven als zijnde een functie/projectie/set van 2-tuples, dan moet de index veld vanzelfsprekend continu oplopend zijn vanaf 0 (of 1 zoals ik nu doe omdat dit conform is aan Z conventie) (dat is bij een List<T> toch ook niet anders? :)).
Jij doet aannames en zet je test zo op dat in JOUW geval het geheel werkt. Maar wat je op je studie wellicht hebt meegekregen is dat je zo juist niet het probleem moet benaderen. Je moet kijken wanneer je NIET met set operaties een TakeWhile kunt uitvoeren. Als ik jouw N1 tabel weghaal (want ik heb bv 10 miljoen rijen in numbers) en de rows zijn na projectie niet gesorteerd op 'id', hoe werkt TakeWhile dan?

Als je kijkt hoe linq werkt intern is het heel simpel te zien:
sequence.ExtensionMethod(parameters).ExtensionMethod(parameters)
.ExtensionMethod(parameters).ExtensionMethod(parameters)....ExtensionMethod(parameters);
Dat is een linq query. Iedere extension method levert een nieuwe sequence op, waarop de volgende extension method wordt uitgevoerd. Kijk maar naar de Queryable extension method documentatie. Die praten niet over sets hoor, maar puur over sequences.

Ik beweer niet dat een sequence geen set is, ik zeg dat als je linq als set-oriented gaat beschouwen, je dus met setoperaties een linq query kunt beschrijven, maar dat kan niet altijd, alleen in een subset van de linq methods kan dat.
Last, LastOrDefault, TakeWhile, Reverse, SkipWhile, het zijn operaties waarbij een of meerdere queries te formuleren zijn die niet in SQL / set operaties zijn uit te drukken. ElementAt(n) kan eventueel nog met een paging trick: ElementAt(n) == Get page n of size 1. Echter, paging is het sequentieel een set consumeren, door het veronderstellen van een volgorde. Idem als Take(n).

Bv als ik doe: Take(10) op Customers gejoined met orders.
SELECT TOP 10 FROM Customers C INNER JOIN Orders O ON C.CustomerID = O.CustomerID
dan zegt dit helemaal niks: het is niet gedefinieerd welke 10 customers hier geselecteerd worden, of dat er uberhaupt 10 geselecteerd worden. Aangezien Customer - Order 1:n is, is de kans zeer groot dat ik 10 keer dezelfde customer terugkrijg in mn set. En welke dat is is ook niet gedefninieerd.

Wat ik dus moet doen is het toevoegen van een order EN het toevoegen van een operatie om duplicate projection rows uit te filteren, bv DISTINCT. Echter in Linq zijn dit aparte sequence operaties. In een set oriented taal zijn dat parameters van 1 operatie (de projection).

Met de extension method Queryable.ThenBy zie je het karakter van de sequence.ExtensionMethod()... methodiek: er zit een volgorde in hoe de operaties worden uitgevoerd. Als ik op 2 columns wil sorteren, kan ik niet beginnen met ThenBy(). Het zijn aparte operaties op de sequences, het resultaat van 1 operatie is de source van de ander en wel op een sequentiele manier: de source wordt sequentieel doorlopen.

Maar goed, ik heb hier genoeg tijd aan besteed nu. Als jij hier verder nog tijd aan wil verdoen met het aantonen dat Linq set oriented is, dan moet je dat vooral doen. Ik zie je Reverse, Last, SkipWhile en TakeWhile SQL code over een set van Orders gesorteerd op Customer.Country, met Order.ID een GUID met spanning tegemoet. :) (En ik denk Microsoft ook, want op dit moment doet Linq to Sql niets met deze methods om de redenen die ik hierboven geschetst heb. Let wel: queries moeten altijd werken, dus niet alleen wanneer ze toevallig samenvallen met een cleanroom opstelling zoals de jouwe die toevallig wel werkt.

Creator of: LLBLGen Pro | Camera mods for games
Photography portfolio: https://fransbouma.com


Acties:
  • 0 Henk 'm!

  • RayNbow
  • Registratie: Maart 2003
  • Nu online

RayNbow

Kirika <3

De miscommunicatie is heel simpel weer te geven :+.
In a nutshell is mijn punt ook geweest dat doordat je een sequence equivalent kan uitdrukken in een set, alle operaties waarvan jij nu zegt dat ze alleen weggelegd zijn voor sequences, ook toepasbaar zijn op de equivalente set notatie van de sequence. Wat ik in feite hiermee zeg is dat het even setgebaseerd is als dat het sequencegebaseerd is. Daar heb ik dan ook alle afleidingen er voor bij geleverd.
versus
EfBe schreef op maandag 14 januari 2008 @ 12:02:
Als het set-gebaseerd is, dan moet je middels set algebra kunnen beschrijven hoe Reverse werkt op een willekeurige set van orders gesorteerd op order.Customer.Country. Dat gaat je niet lukken.
Evenals ElementAt(n). Het is nl. zo dat je ElementAt(n) alleen kunt uitvoeren wanneer je de input beschouwt als een sequence, want je doorloopt de sequence tot element n. Een set heeft geen sequentiele consumer, enumerator.
Het rode geeft de mismatch aan. Beide berichten zijn waar. Een sequence heeft een equivalente set-notatie en een willekeurige set heeft geen volgorde. Het is alleen zo dat er niet gereageerd wordt op datgene wat wordt gezegd.
EfBe schreef op maandag 14 januari 2008 @ 12:02:
Veel op aan te merken? Wat valt er op aan te merken? _ALLES_ in linq is een sequence, niet een set. Een sequence is wel een set, maar een set is geen sequence.
Hier zit een tegenspraak in. Een willekeurige sequence is inderdaad een set. Een set hoeft geen sequence te zijn. So far, so good. Het probleem zit hem echter in de derde zin. Als alles in LINQ een sequence is, dan moet ook alles een set zijn. Dat het speciale sets zijn waarin de elementen zo gecodeerd zijn dat ze een volgnummer hebben doet niet ter zake.

Bijbehorende predicaten logica:

x ∈LINQ . SEQ(x)
x . SEQ(x) → SET(x)
-------------------------------------------
x ∈ LINQ . SET(x)

(Als de tekst niet te lezen valt, gebruik een unicode-enabled font)


Maar goed, het is jammer dat LINQ niet werkt op willekeurige sets, maar dit komt eigenlijk door het opleggen dat datatypen operaties als First e.d. moeten ondersteunen.
The LINQ framework defines a basic pattern of so-called Standard Sequence Operators, which are monadic primitives for filtering, transforming, joining, grouping, and aggregating over arbitrary collections of arbitrary types:
Zoals hier aangegeven, LINQ zou eigenlijk over elke collectie moeten kunnen werken. Net zoals dat je in principe van elke type constructor in Haskell een monad kunt maken, zo lang je maar een zinnige invulling kunt geven aan de bind en unit operaties. Wil je LINQ ondersteuning geven aan willekeurige sets, dan moet je dus een zinnige invulling moeten kunnen geven aan een operatie als First().

Als laatste nog een kort, informatief stukje (uit dezelfde paper) over monads :p:
Mathematicians recognized this “design pattern” many decades ago, and say that
each data model defines a monoid, or more generally, a monad, and each query is an example of a monad comprehension.

Using monads and comprehensions to query arbitrary data sources was first introduced in the functional language Haskell, where they are primarily used to deal with imperative side-effecting computation. Many people wonder what the connection is between side-effects and collections, but if you think about it, it is not far-fetched to consider a whole side-effecting computation that returns say strings, as a some kind of collection that contains strings that yields a new string each time the computation is executed. The idea of using monads and comprehensions to bridge the impedance mismatch between data models is also the basis of the Language Integrated Query (LINQ technology developed by Microsoft.

Ipsa Scientia Potestas Est
NNID: ShinNoNoir


Acties:
  • 0 Henk 'm!

  • prototype
  • Registratie: Juni 2001
  • Niet online

prototype

Cheer Bear

RayNbow schreef op maandag 14 januari 2008 @ 14:06:
Hier zit een tegenspraak in. Een willekeurige sequence is inderdaad een set. Een set hoeft geen sequence te zijn. So far, so good. Het probleem zit hem echter in de derde zin. Als alles in LINQ een sequence is, dan moet ook alles een set zijn. Dat het speciale sets zijn waarin de elementen zo gecodeerd zijn dat ze een volgnummer hebben doet niet ter zake.
Grrrr ;)
[13:19] <RayNbow> ik kwoot anders die beide stukjes :+
[13:19] <prototype> quote dan ook:
[13:20] <prototype> Veel op aan te merken? Wat valt er op aan te merken? _ALLES_ in linq is een sequence, niet een set. Een sequence is wel een set, maar een set is geen sequence.
[13:20] <prototype> van EfBe
[13:20] <prototype> daar zit contradictie in
[13:20] <prototype> als alles in linq een sequence is
[13:20] <prototype> en een sequence een set is
[13:20] <prototype> (en een set kan overigens een sequence zijn)
[13:20] <prototype> wat is _ALLES_ dan in linq volgens transitive property? :P
[13:21] <RayNbow> een set :+
[13:21] <prototype> juistem.
[13:21] <prototype> quote dit irc gesprek maar :P
[13:21] <RayNbow> neuh, dan krijg je die lelijke <> haken :p
Heb je alsnog je lelijke haken :@ ;) Back to work though, deadline al gemist door deze topic :+, 1 punt aftrek moet niet 2 punten aftrek worden. :'( Ik kom hier vanavond wel even wat op terug, maar RayNBow's post summarized 't volgens mij wel goed.

Acties:
  • 0 Henk 'm!

  • EfBe
  • Registratie: Januari 2000
  • Niet online
Hier zit een tegenspraak in. Een willekeurige sequence is inderdaad een set. Een set hoeft geen sequence te zijn. So far, so good. Het probleem zit hem echter in de derde zin. Als alles in LINQ een sequence is, dan moet ook alles een set zijn. Dat het speciale sets zijn waarin de elementen zo gecodeerd zijn dat ze een volgnummer hebben doet niet ter zake.
Ik denk dat het wel ter zake doet. Het punt is nl, dat dat volgnummer bij jouw voorbeeld bv essentieel is om het uberhaupt via set operaties op te lossen, maar dat het niet gegeven is dat zo'n volgnummer ook aanwezig is in de set die je aangereikt krijgt.

Als je er vanuit gaat dat iedere tuple in een set in een linq query (laten we even er vanuit gaan dat het set based is) ook daadwerkelijk dit volgorde attribute heeft, dan ja, dan kan het. Het punt is echter dat dit niet gesteld kan worden, want indien je dit wel doet, zou een database query op bv sqlserver al niet meer een kandidaat zijn, omdat sqlserver dit attribute ontbeert op alle tuples die het oplevert, itt bv oracle.

Omdat dit zo is, kan ik een zekere linq query Q maken die wel met sequences werkt (immers, door het sequentiele karakter hebben ze per definitie een volgorde) maar niet is op te schrijven in SQL. Zo'n query heeft bv een of meerdere calls naar TakeWhile, Last, LastOrDefault, SkipWhile. Door te beweren dat Linq set oriented is (mijn enige ageerpunt in deze) ga je dus de mist in, want dat kan per definitie niet. Jouw 'bewijs' leunt op het feit dat een volgorde gegeven IN de set omsloten zit, maar dat is dus niet een gegeven waar je vanuit mag gaan, en dus ook niet mag opnemen als motivatie voor je argument. Immers, als het WEL set based zou zijn (wat dus inhoudt: het leunt niet op het sequentiele karakter van sequences) zouden ALLE linq queries op te schrijven zijn in set operaties, zonder aannames van aanwezigheid van data die niet toebehoort tot de set zelf!

Dat Linq over elke collectie werkt is logisch, iedere collectie implementeert IEnumerable, wat per definitie een sequence is. Alle Linq bouwstenen, de extension methods, zijn geimplementeerd op Enumerable en een derived type daarvan, Queryable.

Dat monads gebruikt worden is niet zo raar, aangezien Haskell en Linq een persoon gemeenschappelijk hebben ;). het is echter wel zo dat ze imperatieve operaties inhouden, PRECIES wat sequences impliceren maar sets juist niet. Dat een query een monad is ook logisch, of althans, in general gezien wordt als een monoid operation: je wordt hoe dan ook geconfronteerd met rijen, met een al dan niet geforceerde volgorde.

Echter, een equi-join bv is geen operatie die een monad nodig heeft, ookal houdt het in de praktijk in dat intern in de DB twee sequences worden afgesjouwd met een hashtable: we praten hier niet op het abstractieniveau van de interne RDBMS query engine, we praten hier op het abstractieniveau van de set operaties zelf en die zijn niet imperative.

Creator of: LLBLGen Pro | Camera mods for games
Photography portfolio: https://fransbouma.com


Acties:
  • 0 Henk 'm!

  • EfBe
  • Registratie: Januari 2000
  • Niet online
Btw..
[13:20] <prototype> van EfBe
[13:20] <prototype> daar zit contradictie in
[13:20] <prototype> als alles in linq een sequence is
[13:20] <prototype> en een sequence een set is
[13:20] <prototype> (en een set kan overigens een sequence zijn)
[13:20] <prototype> wat is _ALLES_ dan in linq volgens transitive property? :P
[13:21] <RayNbow> een set :+
Dit is echt onzin. Transitive property of equality gaat hier niet op, want set ontbeert een eigenschap van sequence, essentieel voor hoe linq werkt. Leuke woordspelletjes voor in de pauze, maar structureel los je het hier niet mee op: voor de Linq operaties heb je de sequence eigenschappen nodig. Dan mag de sequence wel als set gezien kunnen worden wanneer deze los van de query wordt beschouwd, dat neemt niet weg dat bv Liskov hier opgaat want dat is niet zo: ik MOET parameters voor de operaties als sequences specifieren en niet als sets, want sommige operaties leunen op sequentiele eigenschappen. Zouden de operaties op sets kunnen werken, dan zou je Liskov kunnen toepassen om aan te geven dat je sequences dan wel sets zou kunnen gebruiken, maar met sets alleen kom je er niet.

Maar goed, zoals gezegd, het mondde idd toch uit in geneuzel over woordjes. Ik wacht nog steeds op je SQL query die takewhile doet op die orders, gesorteerd op customer.Country en een GUID als pk.

[ Voor 8% gewijzigd door EfBe op 14-01-2008 14:39 ]

Creator of: LLBLGen Pro | Camera mods for games
Photography portfolio: https://fransbouma.com


Acties:
  • 0 Henk 'm!

  • RayNbow
  • Registratie: Maart 2003
  • Nu online

RayNbow

Kirika <3

EfBe schreef op maandag 14 januari 2008 @ 14:28:
[...]

Ik denk dat het wel ter zake doet. Het punt is nl, dat dat volgnummer bij jouw voorbeeld bv essentieel is om het uberhaupt via set operaties op te lossen, maar dat het niet gegeven is dat zo'n volgnummer ook aanwezig is in de set die je aangereikt krijgt.
Het "niet ter zake doen" sloeg op het feit dat de werkelijke structuur van de set niet uitmaakt voor het bestaan van de tegenspraak in de tekst die ik toen citeerde:
EfBe schreef op maandag 14 januari 2008 @ 12:02:
Veel op aan te merken? Wat valt er op aan te merken? _ALLES_ in linq is een sequence, niet een set. Een sequence is wel een set, maar een set is geen sequence.
    "_ALLES_ in linq is een sequence, niet een set."
    "Een sequence is wel een set"


Dat is de tegenspraak. Deze twee zinnen spreken elkaar tegen.

Kijk, een sequence heeft een equivalente set-notatie. Verder is het zo dat als alles in LINQ een sequence is, dat dan ook alles in LINQ een set is. In deze bewering wordt niets gezegd over de structuur van de set omdat in deze bewering dat helemaal niet nodig.

Let op dat de volgende bewering anders en onjuist is:
    "Alles in LINQ is een willekeurige set".

Dit schijn jij telkens te lezen wanneer iemand beweert dat LINQ gebaseerd is op de set theory, maar dit wordt nergens gezegd. In deze bewering wordt er iets gezegd over hoe de sets eruit zien.

Vergelijk het anders met de volgende situatie. Als jij zegt dat alle hokjes in mijn schrift vierkant zijn, dan kan ik zeggen dat alle hokjes rechthoekig zijn. Dit is correct omdat een vierkant ook een rechthoek is. Het zou alleen fout zijn als ik zou zeggen dat alle hokjes in mijn schrift een willekeurige rechthoekige vorm hebben, want dit is in strijd met de bewering dat ze vierkant zijn.

Ipsa Scientia Potestas Est
NNID: ShinNoNoir


Acties:
  • 0 Henk 'm!

  • prototype
  • Registratie: Juni 2001
  • Niet online

prototype

Cheer Bear

EfBe, het valt me op dat jij elke keer wil lezen dat het over willekeurige sets gaat, terwijl ik daar keer op keer mezelf op herhaal dat het niet over willekeurige sets gaat, maar over "sets van paren" om sequences te vertegenwoordigen. Al mijn wiskundige afleidingen en beredeneringen berusten hier dan ook op.

Natuurlijk kan je takewhile, etc... niet met willekeurige sets bewerkstelligen, maar dat heb ik dan ook nooit beweerd! Lees m'n posts opnieuw met dit in het achterhoofd, en je zult zien dat we eigenlijk langs elkaar heen praten. :)

Ik spreek je dan ook nergens op tegen als het over willekeurige sets gaat, en jij spreekt mij ook niet tegen als het over 'mijn set van paren' gaat (dat klonk fouter dan ik het meende :+). Dit is wat RayNBow je ook duidelijk probeerde te maken, die zag 't als toeschouwer wat duidelijker.

Verder moet je mijn opmerking over transitive property niet te serieus nemen :) Het was in eerste instantie meer bedoelt voor de luchtigheid en om een tegenspraak in je verwoording aan te duiden. ;)

Acties:
  • 0 Henk 'm!

  • EfBe
  • Registratie: Januari 2000
  • Niet online
RayNbow schreef op maandag 14 januari 2008 @ 15:02:
[...]
Het "niet ter zake doen" sloeg op het feit dat de werkelijke structuur van de set niet uitmaakt voor het bestaan van de tegenspraak in de tekst die ik toen citeerde:

[...]

    "_ALLES_ in linq is een sequence, niet een set."
    "Een sequence is wel een set"


Dat is de tegenspraak. Deze twee zinnen spreken elkaar tegen.
het is maar hoe je het wilt lezen natuurlijk. Ik bedoelde NIET dat een sequence NIET een set is, ik bedoelde dat ALLES in linq een SEQUENCE is en dat er dus niet gewerkt wordt met sets. Hoe het er letterlijk staat, helemaal gelijk, maar je kon ook met mijn vorige posts in de hand begrijpen wat ik bedoelde.
Kijk, een sequence heeft een equivalente set-notatie. Verder is het zo dat als alles in LINQ een sequence is, dat dan ook alles in LINQ een set is. In deze bewering wordt niets gezegd over de structuur van de set omdat in deze bewering dat helemaal niet nodig.
Het zou raar zijn als dat inderdaad niet zo zou zijn. :) Dat beweer ik ook niet. Wellicht komt het door de verschillende POV's die we hebben wanneer we naar de materie kijken. Daarom even waarom ik er op ageerde:
In de 'volksmond', dus hoe Joe Mort denkt achter zn toetsenbord, heb je 'set oriented' en 'sequence oriented'. Als men leest: "Oh, linq is set oriented", dan kan men in de valkuil vallen dat men denkt dat de operatoren in Linq, die sterke overeenkomst vertonen met SQL, net zo werkt als SQL, immers die heeft dezelfde operatoren en is set oriented. _DAT_ is dus niet zo.

Dat subtiele verschil is echt erg belangrijk wanneer je met Linq bezig gaat. We kunnen nog uren bomen over formele details, maar dat lost niets op mbt wat ik bedoelde: als je beweert dat Linq set oriented is, m.a.w. een taal is die met set operatoren werkt en set algebra, dan is dat niet zo. Ik kreeg de indruk dat dat beweert werd en daarom reageerde ik.
Let op dat de volgende bewering anders en onjuist is:
    "Alles in LINQ is een willekeurige set".
Dit schijn jij telkens te lezen wanneer iemand beweert dat LINQ gebaseerd is op de set theory, maar dit wordt nergens gezegd. In deze bewering wordt er iets gezegd over hoe de sets eruit zien.
Maar dat zijn dan toch overbodige trivialiteiten? Dat een sequence een set is weet ik ook wel, maar dat is verder niet ter zake doende. Immers, als je gaat beweren dat Linq daarmee DUS set oriented is, ga je de fout in. Om maar in OO termen te blijven, je cast dan een supertype (set) naar zn subtype (sequence), maar dat hoeft niet op te gaan voor die set.
prototype schreef op maandag 14 januari 2008 @ 15:17:
EfBe, het valt me op dat jij elke keer wil lezen dat het over willekeurige sets gaat, terwijl ik daar keer op keer mezelf op herhaal dat het niet over willekeurige sets gaat, maar over "sets van paren" om sequences te vertegenwoordigen. Al mijn wiskundige afleidingen en beredeneringen berusten hier dan ook op.

Natuurlijk kan je takewhile, etc... niet met willekeurige sets bewerkstelligen, maar dat heb ik dan ook nooit beweerd! Lees m'n posts opnieuw met dit in het achterhoofd, en je zult zien dat we eigenlijk langs elkaar heen praten. :)

Ik spreek je dan ook nergens op tegen als het over willekeurige sets gaat, en jij spreekt mij ook niet tegen als het over 'mijn set van paren' gaat (dat klonk fouter dan ik het meende :+). Dit is wat RayNBow je ook duidelijk probeerde te maken, die zag 't als toeschouwer wat duidelijker.

Verder moet je mijn opmerking over transitive property niet te serieus nemen :) Het was in eerste instantie meer bedoelt voor de luchtigheid en om een tegenspraak in je verwoording aan te duiden. ;)
Wat was dan je punt toen je zei: "LINQ is in essentie gewoon setnotation." ? Enig idee wat het betekent voor de mensen die niet zo onderlegt zijn met de achterliggende wiskunde maar wel jouw posts lezen? Die zich afvragen of Linq niet gewoon SQL is in C# en hoe het toch kan dat het niet hetzelfde werkt? Ga jij die uitleggen dat jouw set verhaal ook gewoon betekent dat het sequence oriented is, of laat je dat aan anderen over?

Dat jij je set-verhaal dan puur houdt over het feit dat de sets die jij gebruikt in je verhaal sequences zijn geeft dus aan dat je niets toevoegde en er dus geen discussie was toen ik zei dat Linq sequence oriented was en niet set oriented. Dat jij dan aankomt met 'Ja maar dat is contradictieus want een sequence is een set dus sequence oriented betekent automatisch set oriented', tja... zullen we dat soort discussies of dat nou wel of niet waar is maar bewaren voor de kroeg? Je kunt er nl. niets mee: Ik kan niet met het gegeven dat een sequence een set is, de set algebra pakken en alle Linq operations daarmee formuleren, ik heb dan meer gegevens nodig, een subset (pun intended) van alle mogelijke sets, nl. sequenced sets, oftewel sets met tuples met een semantische volgorde. WAS het maar zo dat het set oriented was, dan was het allemaal niet zo subtiel lastig voor veel mensen.

Maar goed, je hebt je deadline dus laten lopen voor deze non-discussie? Lijkt me toch een gevalletje verkeerde prioriteiten ;)

Nog een voor de meelezers: niet spieken:
Is dit hetzelfde:
var q = customers.Take(10).Skip(3);
vs.
var q = customers.Skip(3).Take(10);

IMHO een van de kleinste voorbeelden waar mensen de mist in gaan met dit sequence vs. set verhaal: Joe Mort gaat denken aan SQL, en ziet 1 set en 2 operations die gelijktijdig (niet echt, maar voor Joe wel, op het abstractieniveau van SQL) plaatsvinden. Echter het is 1 sequence, en 2 operations die achter elkaar plaatsvinden.

[ Voor 35% gewijzigd door EfBe op 14-01-2008 16:30 ]

Creator of: LLBLGen Pro | Camera mods for games
Photography portfolio: https://fransbouma.com


Acties:
  • 0 Henk 'm!

  • prototype
  • Registratie: Juni 2001
  • Niet online

prototype

Cheer Bear

EfBe schreef op maandag 14 januari 2008 @ 16:14:
Wat was dan je punt toen je zei: "LINQ is in essentie gewoon setnotation." ? Enig idee wat het betekent voor de mensen die niet zo onderlegt zijn met de achterliggende wiskunde maar wel jouw posts lezen? Die zich afvragen of Linq niet gewoon SQL is in C# en hoe het toch kan dat het niet hetzelfde werkt? Ga jij die uitleggen dat jouw set verhaal ook gewoon betekent dat het sequence oriented is, of laat je dat aan anderen over?
Als er een goed ding is dat voortgekomen is uit deze discussie behalve dan dat het mij heeft vermaakt (desondanks de gemiste deadline ;)), is dat het geleid heeft tot leuk leesvoer :) Het feit dat we 't in feite allebei over hetzelfde hebben, en door miscommunicatie te lang doorgaan is dan meerwaarde dacht ik zo ;).
Dat jij je set-verhaal dan puur houdt over het feit dat de sets die jij gebruikt in je verhaal sequences zijn geeft dus aan dat je niets toevoegde en er dus geen discussie was toen ik zei dat Linq sequence oriented was en niet set oriented. Dat jij dan aankomt met 'Ja maar dat is contradictieus want een sequence is een set dus sequence oriented betekent automatisch set oriented', tja... zullen we dat soort discussies of dat nou wel of niet waar is maar bewaren voor de kroeg? Je kunt er nl. niets mee: Ik kan niet met het gegeven dat een sequence een set is, de set algebra pakken en alle Linq operations daarmee formuleren, ik heb dan meer gegevens nodig, een subset (pun intended) van alle mogelijke sets, nl. sequenced sets, oftewel sets met tuples met een semantische volgorde. WAS het maar zo dat het set oriented was, dan was het allemaal niet zo subtiel lastig voor veel mensen.
Uhm, beste EfBe :D Voor mij was de discussie eigenlijk al klaar nadat ik de toevoeging had gemaakt in mijn tweede post, waarin ik beweerde dus dat een sequence te herschrijven is naar een set van paren. :D Toen je beweerde dat dat niet kon voelde ik me geroepen om hierover uit te wijden, en het resultaat is deze discussie waarbij we allebei waarheden vertellen, maar langs elkaar heen praten. :D
Als je onze posts eens bekijkt, dan zie je dat we heletijd hameren op dezelfde beredeneringen/argumenten, terwijl het gewoon samen hetzelfde is.

Imho is vanaf dat moment strict gezien voor de lezer niks meerwaarde geweest tenzij je uitwijdingen om reeds gezegde dingen te verduidelijken daaronder vindt vallen. Ik vind van wel iig :) Die mensen waar je het over hebt die misschien meelezen en niet onderbouwd zijn in de achterliggende wiskunde hebben er misschien wat van opgestoken (A)
Maar goed, je hebt je deadline dus laten lopen voor deze non-discussie? Lijkt me toch een gevalletje verkeerde prioriteiten ;)
Achja, houdt je van de straat :+

[ Voor 8% gewijzigd door prototype op 14-01-2008 17:05 ]


Acties:
  • 0 Henk 'm!

  • EfBe
  • Registratie: Januari 2000
  • Niet online
Als je onze posts eens bekijkt, dan zie je dat we heletijd hameren op dezelfde beredeneringen/argumenten, terwijl het gewoon samen hetzelfde is.
Mja, dat is veelal bij dit soort dingen het geval. ;)

Creator of: LLBLGen Pro | Camera mods for games
Photography portfolio: https://fransbouma.com

Pagina: 1