Of course... D specification is very clean in this point: structures, clases or static/dynamic arrays:antonio wrote:
Yes... I think explicit yntax is really more clean:: *you convinced to me :-)*Huzzah :)Let's go with the new proposed syntax: *STEP 0*: drinking from oter sources... XPATH syntax... xmlNode.SelectNodes("tagNameA[conditionA]/tagNameB[conditionB]")... * "[condition]" signifies: evaluate this condition on left side tagNode contents. * When no condition is imposed XPath assumes "[true]"; then xmlNode.SelectNodes("*tagNameA/tagNameB[conditionB]*") is equivalent to xmlNode.SelectNodes("*tagNameA[true]/tagNameB[conditionB]*")... *STEP 1*: lets propose something: The syntax used by the XPath D expression must be "autodefined", becuse whe dont want to use the "xmlNode.SelectNodes( ... )" method :-p. One solution is using specific *![Condition]* that defines "this is an XPath condition"... .. *AggregateExpression*![*condition*] signifies: evaluate the condition on left side aggregated elements and build an aggregated result with elements that passed condition (the result could be a dynamic array)Just one point I'd like to make: AggregateExpression may not neccecarily be an array. It's possible that it is, say, a very *very* large iterable object.
if the aggregate is a struct or a class object, that struct or class must have an opApply function with the type:int opApply(int delegate(inout Type [, ...]) dg);where Type matches the Type used in the foreach declaration of Identifier
You makes me thing about: my conclusion is that I commited an error supposing than ![ ] must "return" an aggregate object... I't more clean to chante the point of view to a "compiler" stament: the result is, bassycally, a set of iterations over an stament... I explay this clearly in this new fools proposal :-) :The syntax so far is fine, but I think user defined classes should be given the option of changing what the result of this is, or even specifying that the result should be an iterable object.
compiler way:
observe the new derived syntax implications: the right side of the aggregate![ condition] is an Stament, not a property:children![isAGirl] must act as a single stament that returns something with the length property :-(.
In fact, I'm thinking in a most "closed" D programming languaje syntax like: foreach stament enrichment:
1: include the condition on foreach stament:
foreach(Type obj; Aggregate; obj_scoped_condition) {
}
Equivalent to:
foreach(Type obj; Aggretate) with(obj) if(obj_scoped_condition) {
obj_scoped_staments;
}
On "D XPath way" it could be expressed as:
aggregate![obj_scoped_condition]{2: (risky): foreach must include some agregate "properties" (closed to "array" properties):
obj_scoped_staments;
}
foreach(....) { }.length (Number of iterations executed )
I think other properties are not necessary.
With this new syntax, the example could be expressed in this alternaive way:
foreach(Person p; people; foreach(Person child; childs; isAGirl).length!=0 ) {
doSomething();
)
Of course, I prefer to write
people![ childs![isAGril].length!=0 ]{
doSomething( );
}
people![ childs![isAGril].length!=0 ] doSomething( ); // without the dot "."
and, of course, the "Subject" of this discussion must be changed to:
people![ name=="Andrew" ] friends ~= peter; // really nice :-)
of course... this introduce some "problems"... foreach does not returns data:
Person[] youngGrandmothers = new Person[]; // We have to separate the declaration
people![ childs.length != 0 ] mother![age<36] youngGrandMothers~= this; // and the "~=" assignation.
¿Standard D offers some way to build a dynamic array on the fly? (like c#, java)*STEP 2* : what to do with not aggregate expressions :-( * ex: *Person[] youngGrandmothers = people![childs.length!=0].*mother![age<36]* *NotAggregateExpression*![*condition*] signifies: evaluate the condition on left side Element and build a dynamic result array with 0 or 1 elements (depending on the condition evaluation result).What if you did this instead: people![childs.length!=0].mother![age<36] ==> ((people![childs.length!=0]).mother)![age<36]
Person someone = new Person();
Person anotherone = new Person();
int count = new Person[]{ someone, anotherone }; // Hoy do you do this on D?
In my last proposal, ![ ] is an standard D stament... it's necessary to include it.*STEP 3:* whe have to use ![] in all hierarchy node: ex: // whe can asume than *![] is equivalent to ![true]* countries![population>10000000].people![age<3].mother![].mainHome![].rooms![windows>2] **If you take the above suggestion of not using "real" arrays for the intermediates, then you don't need to specify ![] at each level.
In my last proposal... you have to write people![ married] doSomething(); because doSomething() is an stament, like people![married]{ doSometing(); doSomethingElse(); }some exceptions: the last hierarchy node doesn't need to be followed by the ![] in some cases: * When the node is a Method: ex: people![married].*doSomething();*Hmm... not sure if I'm comfortable with that. Selecting data is fine, but then performing an operation on that... The problem is that everywhere else in D, this would be a *single* function call. In this one particular case, it's multiple function calls. If you wanted to do this, I think it might be better to spell it out explicitly: foreach(person ; people![married]) person.doSomething() >From the Zen of Python: "Explicit is better than implicit."
With the last propossal:** * When the node is a property and it's on the left side of an assignment ex: people![married]*.name = "Peter";* people![married]*.childs ~= new Person();* people![birdtha=today]*.age++; *// This introduce an implicit right side assignment property evaluation... I suppouse this is an "exception" because compiler can solve this easily.Looks handy :)
this limitation is deprecated with my new proposal.*STEP 4: *right side must be a member. Expression![condition].*member*I think the "must be a member" is a bit strict. Currently, you can do things like this: char[] firstFive(char[] a) { return a[0..5]; } auto firstFiveLetters = "ABCDEFGHIJKLMNOPQRSTUVWXYZ".firstFive; I'd like to be able to still do that. Perhaps just saying "use whatever lookup policy D currently uses on arrays" would be sufficient.
Yes.** *STEP 5:* How compiler expands this expression. I suppouse Walter must decide between a preorder or inorder evaluation * preorder: first all parents, then their childs : A![].B![].C![] could be evaluated like this: foreach(a in A) tmpA~=a; foreach(a in tmpA) foreach(b in a.B) tmpB~=b; foreach(b in tmpB) foreach(c in b.C) tmpC~=c * inorder: first parent, then their chids... when childs evaluated next parent... and so on A![].B![].C![] could be evaluated like this foreach(a in A) foreach(b in a.B) foreach (c in b.C)I would say that in order would be best... provided it's implemented as chained iterators. In other words, each of the intermediate "aggregate results" should only generate elements as neccecary. The reason for this is that then you can perform very complex filters on large data sets. If you did it "preorder", then this would be ludicrously expensive: SomeHugeDataSet![size > 50*Megabytes] .largeInternalObject![size > 75*Megabytes]
I will look for... not now... my bed is waiting for me.Well... I'm not an expert, but how hierarchy is evaluated is a compiler work and programmer must be isolated about the compiler solution. We can assume than *result elements order can't be predicted* (like realtional model). Results needs to be postprocessed (distinct, sort, ...) if needed.At any rate, nice proposal, and I look forward to seeing something come of it :)I agree... this is, basically, my dream: People writes constantly FOR + IF structures that can be easily expressed with this propossal.Oh, one other thing that suddenly occured to me: what if "people" isn't an array? You use 'foreach' in your expansions, but what if "people" CAN be iterated over, but isn't an array in of itself? Then the syntax becomes downright misleading!D propose an standard implementation for "aggregate" classes... the main goal now is to propose something D compatible: * Is there a standard I_Iterable interface? * foreach( ) recognizes this I_Iterable interface? * Array acomplish with the I_Iterable interface? I_Iterable is not part of D programming Language.... and this is another discussion :-): * It could be perfect some standard Interfaces recognized by the compiler, like c# foreach or using staments (IIterable and IDisposable interfaces).I've always thought it would be nice to have a few "standard" interfaces attached to things like arrays. Only thing is that I imagine converting between, say, char[] and IIterable!(char) would be very expensive. Again, I like where this proposal is trying to go. One question, though: have you looked at Linq in C#? I think it's slated for version 3.0, but it looks quite similar to what you're proposing, and allows you to do selects and transforms. I'd give you an example, but I can't remember any :P -- Daniel