FHIR Chat · Creating a Coding in FHIRPath · fhirpath

Stream: fhirpath

Topic: Creating a Coding in FHIRPath


view this post on Zulip 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.

view this post on Zulip Paul Lynch (May 12 2021 at 23:18):

FHIR-29324, still in state "Triaged".

view this post on Zulip RP (May 12 2021 at 23:50):

Thanks, much appreciated @Paul Lynch :+1:

view this post on Zulip 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

view this post on Zulip RP (May 13 2021 at 20:12):

Thanks, we went with %factory.coding for our implementation

view this post on Zulip 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?

view this post on Zulip Ephraim Kigamba (Jun 07 2021 at 14:35):

Hey guys, is there anyway to easily generate a UUID string using FHIR expressions?

view this post on Zulip Grahame Grieve (Jun 07 2021 at 15:08):

not at the moment.

view this post on Zulip Ephraim Kigamba (Jun 08 2021 at 13:22):

Cool thanks

view this post on Zulip 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).

view this post on Zulip 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.

view this post on Zulip 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.)

view this post on Zulip Bryn Rhodes (Jun 08 2021 at 22:05):

Moved and provided a proposed disposition

view this post on Zulip 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?

view this post on Zulip Grahame Grieve (Jun 17 2021 at 07:10):

sure. Create a Jira task proposing the change

view this post on Zulip Ephraim Kigamba (Jun 17 2021 at 15:32):

Thanks

view this post on Zulip 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

view this post on Zulip Grahame Grieve (Jun 24 2021 at 08:47):

@Lloyd McKenzie

view this post on Zulip 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.

view this post on Zulip 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)) ?

view this post on Zulip Grahame Grieve (Jun 28 2021 at 19:49):

the proiblem with this is the parameters. Somewhere. something needs to specify what parameters

view this post on Zulip 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.

view this post on Zulip 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 ;-) )

view this post on Zulip 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?

view this post on Zulip 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

view this post on Zulip 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.

view this post on Zulip Bryn Rhodes (Jul 12 2021 at 19:43):

instanceSelector
    : namedTypeSpecifier '{' (':' | (instanceElementSelector (',' instanceElementSelector)*)) '}'
    ;

instanceElementSelector
    : referentialIdentifier ':' expression
    ;

view this post on Zulip 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?

view this post on Zulip 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 { } ?

view this post on Zulip Ewout Kramer (Jul 14 2021 at 08:16):

I do miss the "new" keyword, but that's my C/C#/Java bias I guess ;-)

view this post on Zulip 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.

view this post on Zulip 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

view this post on Zulip 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'
  },

view this post on Zulip Bryn Rhodes (Feb 07 2022 at 20:55):

Because coding is multi-cardinality, so it takes a List<Coding>, not Coding. Does that help?

view this post on Zulip Paul Lynch (Feb 07 2022 at 20:59):

So {...} is used for both lists and objects?

view this post on Zulip 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?

view this post on Zulip Bryn Rhodes (Feb 07 2022 at 22:35):

Great feedback, thank you! Applied

view this post on Zulip 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 })

view this post on Zulip 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.

view this post on Zulip 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)?

view this post on Zulip Bryn Rhodes (Feb 08 2022 at 17:06):

Yes, the grammar allows for the value of each element to be an arbitrary expression.

view this post on Zulip 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?

view this post on Zulip 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?

view this post on Zulip Bryn Rhodes (Feb 10 2022 at 15:07):

The first would return TupleTypeInfo, the second a ClassInfo

view this post on Zulip Ewout Kramer (Feb 10 2022 at 15:15):

Can lists of anonymous tuples be used where List is expected? And List<Any>?

view this post on Zulip 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?

view this post on Zulip 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.

view this post on Zulip 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.

view this post on Zulip Paul Lynch (Feb 28 2022 at 18:57):

@Bryn Rhodes Would this new syntax allow you to construct something more complex, like a Condition?

view this post on Zulip 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.

view this post on Zulip Bryn Rhodes (Mar 01 2022 at 21:36):

Yes, it will support construction of any type of instance (including anonymous tuples)

view this post on Zulip 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