people[name=="Andrew"].friends ~= peter

antonio antonio at abrevia.net
Sun May 7 16:21:56 PDT 2006


Daniel Keep escribió:
> 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.  
Of course... D specification is very clean in this point: structures, 
clases or static/dynamic arrays:

    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
    /


> 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.
>   
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 :-) :

    *compiler way*:

    * AgregateExpression![condition] is "equivalent to" foreach( ) with(
      )  if ( ) structure.  This structure must act as a single
      stament.  The problem is how "sub ![] expressions must be expanded".
          o Example:  people![ children![isAGirl].length!=0 ].doSomething

        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]{ 
                   obj_scoped_staments;
                }

            2: (risky): foreach must include some agregate "properties"
        (closed to  "array" properties):
                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( );
            }

                    observe the new derived syntax implications:  the 
right side of the aggregate![ condition] is an Stament, not a property:

                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.

>> *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]
>
>   
¿Standard D offers some way to build a dynamic array on the fly? (like 
c#, java)

    Person someone = new Person();
    Person anotherone = new Person();

    int count = new Person[]{ someone, anotherone };  // Hoy do you do
    this on D?


Anyway, with my last proposal, (pure native stament) you can express it 
using a with( ) if ( ):

    people![ childs.length!=0 ] with(mother)if(age<36) .... //




>   
>> *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, ![ ] is an standard D stament... it's necessary to 
include it.

>   
>> 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."
>   
In my last proposal...  you have to write people![ married] 
doSomething(); because doSomething() is an stament, like 
people![married]{ doSometing(); doSomethingElse(); }
>   
>> **
>>
>>     * 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 :)
>   
With the last propossal:
    people![married] name="Peter";
    people![married] childs~= new Person();
    people![birthday == today] age++;
>   
>> *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.
>
>   
this limitation is deprecated with my new proposal. 
>> **
>> *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]
>
>   
Yes.
inorder is implicit in my last propossal... because each ![] is a 
separate stament (without dot)
    A![] B![] C![]

>> 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
>
>   
I will look for... not now... my bed is waiting for me.
Good night
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.puremagic.com/pipermail/digitalmars-d/attachments/20060508/eb7eb5b7/attachment.html>


More information about the Digitalmars-d mailing list