The Data Services team has starting thinking about adding Any/All support to Data Services and we noticed a couple of things that I think warrant minor changes to the proposal. So as always I wanted to share and get your thoughts.
New separator
The original any/all proposal suggested using a ',' to separate the range variable from the predicate, e.g:
~/Movies/?$filter=any(Actors a, a/Name eq 'John Belushi')
I think this has a problem. Usually ',' is used to separate similar things, like the parameters to a function, but in this case it separates a Lambda Parameter from a Predicate. Clearly these things are not the same, moreover using ',' would confuse things in the future if we ever allowed calling custom functions with multiple parameters in the filter.
I think this means we need something more lambda-ish, perhaps something like this:
~/Movies/?$filter=any(Actors a: a/Name eq 'John Belushi')
This uses ':' instead of ','. There is even a precedent for using ':' in lambdas, python uses ':' like this:
lambda a: a+1
More importantly this makes sense in OData because:
- ':' is explicitly allowed in querystrings, in fact it is in a list of suggested scheme specific separators called out in RFC 3986.
- Using a single character (as opposed to something like => or ->) makes more sense in a URL that needs to be concise.
Shorthand Syntax
While thinking through scenarios for any/all, I noticed that I was often writing queries like this:
~/Movies/?$filter=any(Awards a: true)
Or this:
~/Movies/?$filter=any(Actors a: any(a/Awards aw: true))
In both cases the predicate really doesn't matter, so requiring 'true' seems a little bit like a quiz.
The proposal then is to add a shorter (and easier to understand) 'overload':
~/Movies/?$filter=any(Awards)
~/Movies/?$filter=any(Actors a: any(a/Awards))
I think you'll agree this is a lot easier to understand.
Conclusion
Hopefully these proposals are not too controversial, either way though I'm very keen to hear your thoughts. Do you think they make sense?