Re: Missing LET (Assignment) in SPARQL 1.1

> This example actually is a good example of one thing that concerns  
> me about assignment (and remember that my implementation is one that  
> does support LET expressions): I'm concerned whenever a new SPARQL  
> construct has an order-dependence. SPARQL is already order-dependent  
> in cases involving OPTIONAL, but I prefer to keep as much of SPARQL  
> order-independent as is possible. The above collection of  
> assignments reads OK because of the order they're presented in, but  
> if you switch the order around it's not at all clear to me what the  
> proper algebraic expectations would be.

Yes, LET assignments will (have to) be order dependent. And yes, this  
is a good thing. Sure, it may not be perfect from some theoretical  
point of view, but without ordering the whole approach would not work,  
and we would throw out the baby with the bath water. Even the solution  
with nested sub-selects is order dependent. Giving users the ability  
to specify the order in a reliable way has not been a problem with any  
other mainstream computer language, so why should SPARQL be different?

Same with FILTERs - often the query designer knows very well where he  
wants the FILTERing to take place. Why should an engine be required to  
do the re-ordering automatically and possibly mess up any performance  
expectations? But that's a separate topic :)

>
> You can project multiple expressions from a single subquery, so I'm  
> not sure that's a concern?

The problem is readability. Imagine a couple of expressions in the  
same SELECT row...

>
> Again, why not put both calculations in a single subquery? I don't  
> know what "*?this*" is, but I'd expect this query to be much easier  
> to read as:
>
> CONSTRUCT {
>    ?diamond spinbox:replaceWith spinbox:Space .
>    ?world boulders:diamondsCollected ?newDiamondsCount .
> }
> WHERE {
>  SELECT ?world (?oldDiamondCount + 1 AS ?newDiamongCount)  
> (spinbox:getNeighbor(?this, ?direction) AS ?diamond) {
>    ?world spinbox:field ?this .
>    ?world spinbox:keyDirection ?direction .
>    ?diamond a boulders:Diamond .
>    ?world spinbox:field ?this .
>    ?world boulders:diamondsCollected ?oldDiamondsCount .
>  }
> }

Because I am using the variable ?diamond in the WHERE clause, and not  
just in the CONSTRUCT. ?diamond will have to be bound in the ?diamond  
a boulders:Diamond match, otherwise the whole query does not make  
sense. Compare the original version below

# Rule1: Collect and replace diamond if possible
CONSTRUCT {
     ?diamond spinbox:replaceWith spinbox:Space .
     ?world boulders:diamondsCollected ?newDiamondsCount .
}
WHERE {
     ?world spinbox:field ?this .
     ?world spinbox:keyDirection ?direction .
     LET (?diamond := spinbox:getNeighbor(?this, ?direction)) .
     ?diamond a boulders:Diamond .
     ?world spinbox:field ?this .
     ?world boulders:diamondsCollected ?oldDiamondsCount .
     LET (?newDiamondsCount := (?oldDiamondsCount + 1)) .
}

Regards,
Holger

Received on Tuesday, 27 October 2009 03:36:10 UTC