Stream: fhirpath
Topic: Creating a Coding in FHIRPath
RP (May 12 2021 at 22:09):
Moving https://chat.fhir.org/#narrow/stream/179166-implementers/topic/Creating.20a.20Coding.20in.20FHIRPath.3F to this thread which seems more appropriate.
I have an expression I want to write that has the following behavior iif(somecondition, return new Coding(system, value), return other Coding(system, value))
The issue I'm running into is I don't see a native way within FHIRPath to create Codings. You can extract a Coding from an object but I need to dynamically create one. We noticed that CQL does support this but I need this natively supported in FP.
Paul Lynch (May 12 2021 at 23:18):
FHIR-29324, still in state "Triaged".
RP (May 12 2021 at 23:50):
Thanks, much appreciated @Paul Lynch :+1:
Grahame Grieve (May 13 2021 at 00:22):
the FHIR Tools do support a Factory class that can create Codings, but this is not part of the standard
RP (May 13 2021 at 20:12):
Thanks, we went with %factory.coding for our implementation
Paul Lynch (Jun 04 2021 at 19:15):
@Bryn Rhodes What do you think the time frame is for discussing FHIR-29324 at an ITS meeting?
Ephraim Kigamba (Jun 07 2021 at 14:35):
Hey guys, is there anyway to easily generate a UUID string using FHIR expressions?
Grahame Grieve (Jun 07 2021 at 15:08):
not at the moment.
Ephraim Kigamba (Jun 08 2021 at 13:22):
Cool thanks
Bryn Rhodes (Jun 08 2021 at 18:57):
@Paul Lynch , the description of J#29324 suggests this would be a FHIRPath extension, which is actually a FHIR-I concern, not an ITS concern. If we wanted to update the language to include syntax for object construction, that would be a FHIRPath change (and then an ITS concern).
Bryn Rhodes (Jun 08 2021 at 18:58):
Happy to go whatever direction makes the most sense, I would like to see constructor syntax, but the factory approach does not need language modification.
Paul Lynch (Jun 08 2021 at 21:02):
I would not have a preference, but @Ralph already implemented %factory.coding, so I think we should stick with that. @Bryn Rhodes if that means the workgroup should be changed, could you change it? (I don't seem to be able to do that.)
Bryn Rhodes (Jun 08 2021 at 22:05):
Moved and provided a proposed disposition
Ephraim Kigamba (Jun 17 2021 at 07:08):
Grahame Grieve said:
not at the moment.
@Grahame Grieve Is this something that can be added as an official spec. I see that we have something similar for FHIR mapping language?
Grahame Grieve (Jun 17 2021 at 07:10):
sure. Create a Jira task proposing the change
Ephraim Kigamba (Jun 17 2021 at 15:32):
Thanks
Ephraim Kigamba (Jun 24 2021 at 08:46):
@Grahame Grieve I created an issue for my account creation last week and I'm yet to get a reply. I assume I need to have an account so that I can propose the change on Jira. Could you help out? The issue is NEWID-3417
Grahame Grieve (Jun 24 2021 at 08:47):
@Lloyd McKenzie
Lloyd McKenzie (Jun 24 2021 at 17:48):
Looks like this was addressed by HQ already sometime today. It can take 1-2 business days for someone to review and ensure you do indeed appear to be a real human.
Ewout Kramer (Jun 28 2021 at 19:48):
After discussing https://jira.hl7.org/browse/FHIR-29324 tonight in FHIR-I, I do think I disagree with the %factory solution. We need a more general way to create instances of types, we need this to work with System.Quantity too for example, and if we start out with %factory.Quantity
, we introduce functionality that is useful outside of the FHIR datamodel, but cannot be used by other models without creating ambiguity. We did this with is(Quantity), which we changed to is(FHIR.Quantity), we might need to do the same here. Also, this is really about constructing instances, so it would make sense to have a kind of constructor syntax for it (new FHIR.Quantity(x,y,z)
) ?
Grahame Grieve (Jun 28 2021 at 19:49):
the proiblem with this is the parameters. Somewhere. something needs to specify what parameters
Ewout Kramer (Jun 28 2021 at 20:13):
Right. So these need to specified per specification. It could be a specific section, or a new set of functions that are identified as constructors. I guess the FHIR path appendix of FHIR could specify what are the constructor overloads available for each FHIR primitive, and we need to do it for System types too.
Ewout Kramer (Jun 28 2021 at 20:14):
(if you need to choose between watching a beautiful sunrise now or constructor syntax, I'd choose the first option ;-) )
Grahame Grieve (Jun 28 2021 at 20:40):
I am about to hit the road, yes. I don't mind the syntax, but yes, we have to specify it somewhere. we could say that there's a syntax that lets you call methods on the objects that are static (defined on the class, not the object) and that have a stereotype constructor, or something, and let the specifications define those somewhere?
Bryn Rhodes (Jul 12 2021 at 19:41):
This would be a new syntax in FHIRPath, yes? A "new" keyword followed by a function invocation? I've added a tracker to support that in FHIRPath: https://jira.hl7.org/browse/FHIR-33044
Bryn Rhodes (Jul 12 2021 at 19:43):
Could potentially follow the approach taken by CQL that uses a tuple syntax so that constructors arguments are bound by name. That would avoid the need to document specific constructors anywhere.
Bryn Rhodes (Jul 12 2021 at 19:43):
instanceSelector
: namedTypeSpecifier '{' (':' | (instanceElementSelector (',' instanceElementSelector)*)) '}'
;
instanceElementSelector
: referentialIdentifier ':' expression
;
Ewout Kramer (Jul 14 2021 at 08:01):
I can see how this grammar works for FHIR.Patient { active : true }
, but it seems to allow FHIR.Patient { : }
too - what does that do?
Ewout Kramer (Jul 14 2021 at 08:15):
Maybe construct a new Patient without setting any of its properties which is more explicit than FHIR.Patient { }
?
Ewout Kramer (Jul 14 2021 at 08:16):
I do miss the "new" keyword, but that's my C/C#/Java bias I guess ;-)
Ewout Kramer (Jul 14 2021 at 08:19):
There's a bit of light between calling a constructor with a fixed # of predefined constructor arguments, or constructing an object, and then settings its properties (the CQL way). I can see the C# language designers struggling with this nowadays since C# now supports both notions. Makes sense since most constructors did nothing but assign (read-only) properties to the given constructor arguments. Since we're so data driven, maybe the constructor is less of a function, and the "property-based" approach of CQL is just fine.
Bryn Rhodes (Feb 07 2022 at 19:12):
Proposed updates to the FHIRPath grammar to enable this, plus worked examples here: https://github.com/HL7/FHIRPath/blob/fhir-33044-instance-selector/spec/instance-selector.md @Grahame Grieve @Ewout Kramer @Lloyd McKenzie @Paul Lynch @Ephraim Kigamba
Paul Lynch (Feb 07 2022 at 20:07):
I don't understand why:
type: CodeableConcept {
coding: {
Coding {
system: 'http://terminology.hl7.org/CodeSystem/v2-0203',
code: 'MR',
display: 'Medical Record Number'
}
},
text: 'Medical Record Number'
},
isn't:
type: CodeableConcept {
coding: Coding {
system: 'http://terminology.hl7.org/CodeSystem/v2-0203',
code: 'MR',
display: 'Medical Record Number'
},
text: 'Medical Record Number'
},
Bryn Rhodes (Feb 07 2022 at 20:55):
Because coding
is multi-cardinality, so it takes a List<Coding>
, not Coding
. Does that help?
Paul Lynch (Feb 07 2022 at 20:59):
So {...} is used for both lists and objects?
Paul Lynch (Feb 07 2022 at 21:08):
Okay, I guess we had {} (empty list) already. Another question: I see "listSelector" defined like '('List' ('<' typeSpecifier '>')?)? ...', but I don't see an example in which optional word 'List' appears. Should there be one?
Bryn Rhodes (Feb 07 2022 at 22:35):
Great feedback, thank you! Applied
Paul Lynch (Feb 07 2022 at 22:51):
Makes sense. I think the syntax will work well, though I am not quite sure yet what fhirpath.js should do with the type information. When it is better to write:
ValueSet.expansion.contains.select(Coding { system: system, version: version, code: code, display: display })
rather than:
ValueSet.expansion.contains.select({ system: system, version: version, code: code, display: display })
Bryn Rhodes (Feb 07 2022 at 23:03):
I'm thinking we'll want to define "assignment-compatible" as a tuple that has elements that are a subset (not necessarily proper) of the elements of the target, that is what CQL does so that you can use anonymous tuples or strongly-typed tuples. In FHIRPath where typing enforcement tends to be more run-time, the named instances won't be as important, though they would still be required to distinguish choices.
Bas van den Heuvel (Feb 08 2022 at 15:50):
Bryn, all the examples seem to be setting pre-defined data elements. Can I also create data elements with dynamic field values (values that are the result of expressions)?
Bryn Rhodes (Feb 08 2022 at 17:06):
Yes, the grammar allows for the value of each element to be an arbitrary expression.
Bas van den Heuvel (Feb 09 2022 at 07:45):
If I understand the grammar correctly, when you use a constant for system and an expression for value and an it will look like:
Quantity{ value: (%someObs.value as Quantity.value), unit: 'g/dl', code: 'g/dL', system: %ucum }
If this is the case, why use a difference expression for constants and expressions? Wouldn't it be less confusing if we use the same syntax for both?
Ewout Kramer (Feb 10 2022 at 11:38):
If a function expects a Coding as a parameter, and I'd pass one of these as arguments:
{ system: system, version: version, code: code, display: display }
Coding { system: system, version: version, code: code, display: display }
If I did type()
on each of those, would the first return TupleTypeInfo
and the second ClassInfo
? Or both ClassInfo
?
Bryn Rhodes (Feb 10 2022 at 15:07):
The first would return TupleTypeInfo
, the second a ClassInfo
Ewout Kramer (Feb 10 2022 at 15:15):
Can lists of anonymous tuples be used where List
is expected? And List<Any>
?
Ewout Kramer (Feb 10 2022 at 15:16):
Is it expected that, if a function takes a Coding as parameter and you supply it with such an anonymous tuple, there is an implicit conversion to Coding?
Ewout Kramer (Feb 10 2022 at 15:22):
Coming from a Java/C#/C background, my view of typing in FhirPath was based on a nominal type system, but I can see we're sort of introducing structural typing with this feature. I am not sure we're not stepping on thin ice, although I enjoy the challenge.
Ewout Kramer (Feb 15 2022 at 08:11):
When/where will we continue this discussion? I'd be interested to join if this is handled on a call.
Paul Lynch (Feb 28 2022 at 18:57):
@Bryn Rhodes Would this new syntax allow you to construct something more complex, like a Condition?
Paul Lynch (Feb 28 2022 at 18:59):
Never mind -- I see you have an example of a Patient being constructed. This seems really useful.
Bryn Rhodes (Mar 01 2022 at 21:36):
Yes, it will support construction of any type of instance (including anonymous tuples)
Bryn Rhodes (Mar 01 2022 at 21:48):
Apologies @Ewout Kramer , I missed these questions. In CQL, implicit conversion from a class type to an equivalent tuple type is allowed, but the other direction is not. So if you had a function that took a Coding, and you passed it a compatible tuple type, you'd have to do an explicit conversion to get it to be a Coding, but if you had a function that took a compatible tuple type with Coding, you could pass it a Coding. So it is shades of "duck typing", yes.
Last updated: Apr 12 2022 at 19:14 UTC