Clarification of variable scoping

First, thanks again for the great work on SPARQL!

I think a bit more clarification (and perhaps examples) of variable
scoping would be helpful in the SPARQL Query spec.

I tried the following query (in Parliament 2.7.1):

  # Example 1: no results
  SELECT *
  WHERE { 
    BIND( 10 as ?ten )
    GRAPH <http://example/bookStore> { 
      FILTER( ?ten >= ?ten )
    } 
  }

and it produced 0 results.  However, when I moved the BIND inside the
GRAPH clause, the following query worked, producing one result with 10
bound to ?ten:

  # Example 2: one result
  SELECT *
  WHERE { 
    GRAPH <http://example/bookStore> { 
      BIND( 10 as ?ten )
      FILTER( ?ten >= ?ten )
    } 
  }

Based on investigation, it looks like ?ten is unbound at the point of
the FILTER clause in example 1, whereas it *is* bound at the point of
the FILTER clause in example 2.   This behavior was non-intuitive (to
me), but it is not evident to me from the spec whether this is
considered correct behavior or not.  In looking at the variable scoping
rules in section 18.2.1
http://www.w3.org/TR/sparql11-query/#variableScope
the table says that "v is in-scope".  But "in-scope" *where*?  It is not
clear where the scopes are and which scope is meant.  The spec *does*
clearly say that "use of a variable in FILTER, or in MINUS does not
cause a variable to be in-scope outside of those forms".  But I would
have expected the BIND statement to *cause* the variable to be bound
within the FILTER clause.

This behavior seems counterintuitive to one who is accustomed to
variable scoping rules in programming languages, since AFAIK the purpose
of BIND is to set a variable that can be used in throughout the query.
But if the behavior above is correct, I do not yet see how to do that.
For example, I'd like to use the same variable ?limit bound to the
constant 10 in multiple GRAPH clauses like this:

  SELECT *
  WHERE { 
    GRAPH ... { 
      FILTER( ?n <= ?limit )
    } 
    GRAPH ... { 
      FILTER( ?n <= ?limit )
    } 
    GRAPH ... { 
      FILTER( ?n <= ?limit )
    } 

  }

But where should I put the BIND statement to achieve this?


Thanks

-- 
David Booth, Ph.D.
http://dbooth.org/

Opinions expressed herein are those of the author and do not necessarily
reflect those of his employer.

Received on Tuesday, 13 September 2011 17:20:46 UTC