Stream: implementers
Topic: Questions about fhirpath spec on collections
Justin Pombrio (Dec 20 2019 at 18:24):
I have some questions about how some methods are supposed to behave on empty collections in fhirpath, where the spec isn't clear.
The Fhirpath spec (NormBallot2) says in section 4.3:
Finally, FHIRPath supports the notion of functions, which all take a collection of values as input and produce another collection as output and may take parameters. For example:
(name.given | name.family).substring(0,4)
This suggests to me that this example is valid, and that if name.given is "Jane" and name.family is "Smith", then this expression would produce the colleciton {'Jane', 'Smit'}.
However, substring
is defined in section 5.6, which says
The functions in this section [e.g. substring] operate on collections with a single item. If there is more than one item, or an item that is not a String, the evaluation of the expression will end and signal an error to the calling environment.
If that's correct, then this example should produce an error. What's the intended behavior of .substring? Should it produce a collection in this case, or an error because it was passed a collection of more than a single item?
More interestingly, how about this example?
{}.substring(0, 4)
Should it raise an error, or produce an empty collection? The note at the beginning of section 5.6 doesn't say what is supposed to happen with empty collections.
Relatedly, what should this expression produce? Should it raise an error, or produce 'T'?
{1, 2}.iif($this.exists(), 'T', 'F')
And likewise?
{}.iif($this.empty(), 'T', 'F')
I ask because iif
is defined in section 5.5 ("Conversion"), which has the same note about raising an error on collections that have more than a single item.
Lloyd McKenzie (Dec 20 2019 at 19:55):
@Bryn Rhodes
Bryn Rhodes (Dec 21 2019 at 01:22):
The example in section 4.3 is incorrect, that would produce an error. Substring expects a singleton, so to invoke it on a collection you would use .select()
. If you invoke .substring()
on an empty collection, the result is an empty collection. And yes .iff()
is a singleton function as well, so the example { 1, 2 }.iif(...
would throw an error, and the invocation on the empty collection would result in an empty collection. I've submitted a tracker (J#25403) to address the example.
Justin Pombrio (Dec 30 2019 at 20:34):
Thanks Bryn. That fully answers my question (together with the bit in spec that I had missed before that says "If a single-input function operates on an empty collection, the result is an empty collection").
It does make it hard to produce an expression that evaluates to 'A'
if a collection is empty, or 'B'
otherwise, which was the motivation behind this question. But I suppose you can say collection.empty().iff($this, 'A', 'B')
.
Last updated: Apr 12 2022 at 19:14 UTC