FHIR Chat · FHIRPath Specification Questions · implementers

Stream: implementers

Topic: FHIRPath Specification Questions


view this post on Zulip Michael Calderero (Jun 14 2017 at 12:31):

Hi,

I have some questions regarding the FHIRPath specification, but don't know whether the version I'm looking at is the most recent one or there's something newer.

I am looking at these:
https://github.com/FHIR/fluentpath/blob/master/spec/index.adoc
http://hl7.org/fhirpath/

Are these the latest versions?

view this post on Zulip Grahame Grieve (Jun 14 2017 at 12:37):

the current formal version is here:

view this post on Zulip Grahame Grieve (Jun 14 2017 at 12:37):

http://hl7.org/fhirpath

view this post on Zulip Michael Calderero (Jun 14 2017 at 15:12):

Thanks for that. I have the following questions:

1. In section 6.5 Boolean logic (i.e. http://hl7.org/fhirpath/#boolean-logic), it says:
"For all boolean operators, the collections passed as operands are first evaluated as booleans (as described in Boolean Evaluation of Collections). The operators..."
It seems to refer to a section named "Boolean Evaluation of Collections". However, I don't see such a named section in the specification. The closest I could find was http://hl7.org/fhirpath/#singleton-evaluation-of-collections. Is this the correct reference?

2. In http://hl7.org/fhir/STU3/definitions.xml.zip, in search-parameters.xml, some of the search parameters use the is() or as() functions. An example is http://hl7.org/fhir/SearchParameter/Condition-abatement-boolean.
I cannot find any definition of these functions in the FHIRPath spec. I do find the equivalent 'is' or 'as' keywords under http://hl7.org/fhirpath/#types. Are the functions equal to their keyword counterparts?

view this post on Zulip Bryn Rhodes (Jun 14 2017 at 15:15):

1. Yes, that's been corrected in the next version, but isn't published yet.

view this post on Zulip Bryn Rhodes (Jun 14 2017 at 15:16):

2. Yes, that's also been corrected, and yes, they are equivalent. They're done as part of the syntax so we can distinguish that the identifier is a "type" identifier, rather than a "variable" identifier.

view this post on Zulip Michael Calderero (Jun 14 2017 at 15:20):

Thanks. Is the unpublished version viewable? Like in GForge or something?

view this post on Zulip Bryn Rhodes (Jun 14 2017 at 15:21):

The source is in Github, and now that I'm looking at it I see that that issue is still outstanding, I thought it had been corrected.

view this post on Zulip Bryn Rhodes (Jun 14 2017 at 15:21):

https://github.com/FHIR/fluentpath/blob/master/spec/index.adoc

view this post on Zulip Bryn Rhodes (Jun 14 2017 at 15:21):

I'll fix it.

view this post on Zulip Bryn Rhodes (Jun 14 2017 at 15:27):

There's actually a tracker on it too: http://gforge.hl7.org/gf/project/fhir/tracker/?action=TrackerItemEdit&tracker_item_id=12583&start=0

view this post on Zulip Michael Calderero (Jun 14 2017 at 15:34):

I had forgotten about that issue I posted on GForge. My bad.
But for my question #2, it seems that https://github.com/FHIR/fluentpath/blob/master/spec/index.adoc is not yet updated. Do you want me to put in a GForge ticket for this?

view this post on Zulip Bryn Rhodes (Jun 14 2017 at 15:35):

No, in looking at that ticket, it was auto-deferred, so we can just put it back to open and apply the change.

view this post on Zulip Bryn Rhodes (Jun 14 2017 at 15:39):

For question #2, the github is correct, is and as are keywords.

view this post on Zulip Bryn Rhodes (Jun 14 2017 at 15:41):

But yes, I see that they are used as functions in the FHIRPath for the search parameters in the spec.

view this post on Zulip Bryn Rhodes (Jun 14 2017 at 15:42):

So yes, log a ticket for that so we can sort it.

view this post on Zulip Bryn Rhodes (Jun 14 2017 at 15:43):

Actually, looks like Ewout just did.

view this post on Zulip Ivan Dubrov (Feb 22 2018 at 20:04):

So, what is the correct semantics for the "Boolean Evaluation of Collections" (I wasn't able to find it anywhere).
Is it that single boolean value evaluates to that value, empty collection evaluates to empty and anything else is "true"?

view this post on Zulip Bryn Rhodes (Feb 22 2018 at 20:42):

Singleton evaluation of collections

view this post on Zulip Bryn Rhodes (Feb 22 2018 at 20:44):

Boolean evaluation of collections is a special case of singleton evaluation. In general, it's an error to attempt to evaluate a collection with more than one thing in it as a singleton.

view this post on Zulip Ivan Dubrov (Feb 22 2018 at 20:56):

Would non-boolean produce an error or evaluate to 'true'?
Reason I'm asking is that I see the following FHIRPath in standard definitions: "(code or value.empty()) and (system.empty() or system = 'urn:iso:std:iso:4217')", which implies that non-empty code should evaluate to true.

view this post on Zulip Ivan Dubrov (Feb 22 2018 at 20:58):

(it's in Money definition)

view this post on Zulip Lloyd McKenzie (Feb 22 2018 at 21:04):

@Bryn Rhodes

view this post on Zulip Bryn Rhodes (Feb 22 2018 at 22:17):

Hmmm.... seems like it shouldn't evaluate to me, should be (code.exists() or value.empty()) and (system.empty() or system = 'urn:iso:std:iso:4217')

view this post on Zulip Grahame Grieve (Feb 22 2018 at 22:26):

indeed that should be corrected

view this post on Zulip Bryn Rhodes (Feb 22 2018 at 22:50):

GF#15611

view this post on Zulip Lloyd McKenzie (Feb 22 2018 at 23:19):

Marked as an auto-approved typo

view this post on Zulip Ivan Dubrov (Feb 26 2018 at 19:12):

Here is one more inconsistency between the spec and its application.
For example, spec doesn't define ".in()" function (), but rather an "in" operator. However, both spec and real definitions use "in" as a function.
Same for the "as" operator.
So, in those two cases, should those be both supported as a "function" and as an "operator" or only as an operator?

view this post on Zulip Ivan Dubrov (Feb 26 2018 at 19:19):

There is also a lot of other things, like missing .exists(), as in example above, comparing single item versus a collection (like in value.empty() or code!=component.code for Observation), assuming short-cutting "or" operator (like in min.empty() or max.empty() or (max = '*') or (min <= max.toInteger()), toInteger will fail if max = '*').
(plus some of the data in examples doesn't pass validation, like bmi-questionnaire.json missing "linkId" elements here and there).

Should I report all these cases one by one or maybe I can just list all of them as a bulk item?

view this post on Zulip Bryn Rhodes (Feb 26 2018 at 19:21):

I don't see a reference to .in() in the spec, in is defined as an operator in the spec and the grammar.

view this post on Zulip Bryn Rhodes (Feb 26 2018 at 19:22):

For is and as, they are defined in the spec and the grammar as operators, but I do see examples that use them as functions. I'd suggest a tracker for that on FHIRPath.

view this post on Zulip Bryn Rhodes (Feb 26 2018 at 19:22):

For the use of .in() in the spec, I'd say that would be a tracker against FHIR, citing the invariant that uses it.

view this post on Zulip Bryn Rhodes (Feb 26 2018 at 19:22):

Separate trackers for the items in FHIRPath are preferable, it's easier to track the specific resolutions for the issues.

view this post on Zulip Ivan Dubrov (Feb 26 2018 at 19:29):

You are right about ".in()", it was just one of the constraints.

I'll open separate tickets.

view this post on Zulip Bryn Rhodes (Feb 26 2018 at 20:09):

Thank you!

view this post on Zulip Ivan Dubrov (Feb 26 2018 at 21:42):

Created few:

https://gforge.hl7.org/gf/project/fhir/tracker/?action=TrackerItemEdit&tracker_item_id=15648
https://gforge.hl7.org/gf/project/fhir/tracker/?action=TrackerItemEdit&tracker_item_id=15649
https://gforge.hl7.org/gf/project/fhir/tracker/?action=TrackerItemEdit&tracker_item_id=15650
https://gforge.hl7.org/gf/project/fhir/tracker/?action=TrackerItemEdit&tracker_item_id=15651
https://gforge.hl7.org/gf/project/fhir/tracker/?action=TrackerItemEdit&tracker_item_id=15652
https://gforge.hl7.org/gf/project/fhir/tracker/?action=TrackerItemEdit&tracker_item_id=15653
https://gforge.hl7.org/gf/project/fhir/tracker/?action=TrackerItemEdit&tracker_item_id=15654

view this post on Zulip Ewout Kramer (Feb 27 2018 at 09:44):

There is also a lot of other things, like missing .exists(), as in example above, comparing single item versus a collection (like in `value.empty() or (...)

Should I report all these cases one by one or maybe I can just list all of them as a bulk item?

Hi Ivan, these inconsistencies are because of a change of the boolean interpretation of empty arrays & introduction of three-valued logic in STU3. We tried to manually hunt these mistakes down & fix them, but obviously we've missed a few. Thanks for pointing them out!

view this post on Zulip Ewout Kramer (Feb 27 2018 at 09:45):

@Bryn Rhodes @Grahame Grieve: I think we need to continue our discussion around sum() or aggregate/fold (and possible lambda notation) for the FhirPath normative?

view this post on Zulip Grahame Grieve (Feb 27 2018 at 10:00):

we do. though I don't know about the lambda bit?

view this post on Zulip Ewout Kramer (Feb 27 2018 at 10:08):

The major question is:

  • Option A: We add just sum(), which works on a collection of numbers and sums the numbers
  • Option B: We generalize and introduce explicit lambda notation like so: Patient.name.first.aggregate(\total arg -> $total & $arg) (just borrowing from Haskell here) - which would allow you to sum/aggregate anything in any way, since you're not bound to just sums
  • Option C: Another magic variable $total (much like $this), which only appears in aggregate: Patient.name.first.aggregate($total & $this)

view this post on Zulip Ewout Kramer (Feb 27 2018 at 10:22):

I think the third option is closest to our current design - where() etc introduce a magic $this, aggregate() could introduce $total.

Interestingly, repeat() could then be rewritten using aggregate():

Questionnaire.repeat(group | question).question becomes

Questionnaire.aggregate($total | (group | question)).question

view this post on Zulip Bryn Rhodes (Feb 27 2018 at 17:08):

Option A is the most well understood, but least flexible. It's the least likely to be considered a substantive change.

view this post on Zulip Bryn Rhodes (Feb 27 2018 at 17:09):

Option B is, I think, the least understood, but most flexible, and I think would be considered substantive, it's a pretty big change in terms of functionality, even if not in terms of the actual grammar and specification.

view this post on Zulip Bryn Rhodes (Feb 27 2018 at 17:11):

Option C is my favorite, it's not as flexible as lambdas, but it's also a very focused change so much less likely to be considered substantive. I actually really like it, it supports everything we need and more, nice proposal @Ewout Kramer

view this post on Zulip Grahame Grieve (Feb 27 2018 at 18:05):

I understand this: Patient.name.first.aggregate($total & $this) - but I find it not useful because of the need for a separator in most cases - an 'all but the first' action.

view this post on Zulip Grahame Grieve (Feb 27 2018 at 18:05):

but I don't understand this: Questionnaire.aggregate($total | (group | question)).question - what is aggregate aggregating on? Is this a mistake, or something I don't understand?

view this post on Zulip Bryn Rhodes (Feb 27 2018 at 19:38):

Patient.name.first().aggregate($total & $total.iif(exists(), ', ') & $this)

view this post on Zulip Bryn Rhodes (Feb 27 2018 at 19:38):

For the second one, it's aggregating the list, so union is the aggregate function.

view this post on Zulip Grahame Grieve (Feb 27 2018 at 20:04):

how is it different to (Questionnaire.group | Questionnaire.question) ? Surely you have to have a list as focus in order to actually aggregate something?

view this post on Zulip nicola (RIO/SS) (Feb 27 2018 at 20:17):

Are you going create Turing complete language with perl syntax?

view this post on Zulip Grahame Grieve (Feb 27 2018 at 20:18):

no but that sounds like fun. It'll only take you a few minutes to do that...

view this post on Zulip Ewout Kramer (Feb 28 2018 at 16:16):

but I don't understand this: Questionnaire.aggregate($total | (group | question)).question - what is aggregate aggregating on? Is this a mistake, or something I don't understand?

No, I was a bit too enthousiastic ;-) We can't get rid of the repeat() unfortunately.

view this post on Zulip Ewout Kramer (Feb 28 2018 at 16:17):

Are you going create Turing complete language with perl syntax?

Thinking about addinc let rec....

view this post on Zulip Brian Postlethwaite (Feb 28 2018 at 22:37):

With the aggregate functions, need to be very careful that they don't operate on a list that has had duplicates removed, will skew values and make sums incorrect.


Last updated: Apr 12 2022 at 19:14 UTC