FHIR Chat · Slicing non-repeating elements to define a choice · implementers

Stream: implementers

Topic: Slicing non-repeating elements to define a choice


view this post on Zulip Marten Smits (Feb 02 2017 at 14:55):

I know you can't slice non-repeating elements. But I would love to slice observation.code (1..1), and then have a choice of three slices (all 0..1) to define a choice. I know I could create a ValueSet binding to a new ValueSet with the three options to do the same thing, but I prefer the slicing option (never thougt I would say that).

view this post on Zulip Marten Smits (Feb 02 2017 at 14:57):

Also, it's odd that FHIR allows me to slice a repeating element, constrain it to 1..1 and have all my slices 0..1
Which is exactly the same thing.

view this post on Zulip Eric Haas (Feb 02 2017 at 22:03):

I can't believe you are saying that as well. Why not a choice of three profiles one for code a , b and c and what wrong with using a valueset?

view this post on Zulip Brian Postlethwaite (Feb 02 2017 at 23:32):

You would then need an invariant to ensure that 1 of the 3 was selected (as this is a required field)

view this post on Zulip Brian Postlethwaite (Feb 02 2017 at 23:32):

Seems like a lot of work instead of just providing a restricted binding to the 3 values you want.

view this post on Zulip Marten Smits (Feb 16 2017 at 09:09):

Why would I need an invariant? If I define a closed slice on a required element, with all slices 0..1. The slice intro will already tell me that you have to select 1 off the options. For me, this is far less work than creating a new valueset.

view this post on Zulip Ewout Kramer (Feb 16 2017 at 09:21):

By having a slice on an element that is 0..1, in which each slice itself has cardinality 0..1, you could create constraints that are alternatives: e.g. the string length is between 1--5 (one slice) OR 10--20 (the other slice). Or maybe even more realistic: with this binding these invariants hold (slice A), with this other binding another set of invariants hold (slice B).

view this post on Zulip Ewout Kramer (Feb 16 2017 at 09:22):

I wonder: if you are allowed to constrain an already sliced element to cardinality 0..1 in a derived profile, why not allow it in the first place? I think most of our tooling would naturally do the "right" thing, unless we explicitly forbid it (as e.g. Forge does now). Does anyone see unexpected consequences?

view this post on Zulip Grahame Grieve (Feb 16 2017 at 20:06):

I'm about to process a task that changes the way slicing works for 0..1 elements

view this post on Zulip Alexander Henket (May 17 2019 at 10:48):

Where are we at currently? We would use slicing to define a choice of bindings for example. I believe that was what we thought of when we discussed multiple bindings.

view this post on Zulip Alexander Henket (May 17 2019 at 10:56):

We also have a type slice defined on Dosage.dose 0..1 (https://simplifier.net/nictizstu3-zib2017/zib-instructionsforuse). This aims to say specific things for when Dosage.dose is a SimpleQuantity and for when it's a Range.

view this post on Zulip Grahame Grieve (May 17 2019 at 22:19):

you don't slice for different restrictions on different types

view this post on Zulip Grahame Grieve (May 17 2019 at 22:19):

I don't follow the multiple bindings thing

view this post on Zulip Alexander Henket (May 20 2019 at 04:29):

you don't slice for different restrictions on different types

So what do you do? Do you just start Dosage.doseQuantity versus Dosage.doseRange without slicing discriminator? They are both the same element, distinguishable by type, are they not?

view this post on Zulip Alexander Henket (May 20 2019 at 04:46):

I don't follow the multiple bindings thing

Suppose I want codes from ValueSet A or ValueSet B: I'd slice the element and add ValueSet A as binding to the one and ValueSet B to the other.

The alternative could be that I create a new third ValueSet C and include A & B but I do not want a new ad hoc ValueSet for every combination of ValueSets. I want multiple separate bindings.

Suppose I want to say use ValueSet A, or use NullFlavor UNK or use NullFlavor OTH , which is very very common in V3, in FHIR I'd say:

  • Slice element
  • Add binding to ValueSet A on first slice
  • Extend element to support NullFlavor extension 0..1
  • Slice NullFlavor.valueCode
  • Add fixedCode UNK to slice1
  • Add fixedCode OTH to slice2

In Templates ITS things could look like this:

<element name="hl7:value" strength="required" datatype="CD" conformance="R" minimumMultiplicity="1" maximumMultiplicity="1">
    <vocabulary valueSet="ValueSetA" flexibility="2019-01-01T12:34:56"/>
    <attribute name="xsi:type" isOptional="false"/>
    <attribute name="nullFlavor" isOptional="true">
        <desc language="en-US">Use NullFlavor when there's no relevant code</desc>
        <vocabulary code="UNK"/>
        <vocabulary code="OTH"/>
    </attribute>
</element>

view this post on Zulip Grahame Grieve (May 20 2019 at 04:52):

Do you just start Dosage.doseQuantity versus Dosage.doseRange without slicing discriminator?

yes

view this post on Zulip Grahame Grieve (May 20 2019 at 04:53):

create a new third ValueSet C and include A & B

yes. Much better than slicing. And inline the value set if you want

view this post on Zulip Alexander Henket (May 20 2019 at 04:54):

Why? there's slicing involved. Is it all implicit here? Would you do the same for effectiveTime as SXPR_TS versus IVL_TS? This is the V3 equivalent for type slicing

view this post on Zulip Grahame Grieve (May 20 2019 at 04:58):

yes. you would

view this post on Zulip Alexander Henket (May 20 2019 at 08:42):

create a new third ValueSet C and include A & B

yes. Much better than slicing. And inline the value set if you want

I've been chewing on that. If I inline an ad hoc valueset then how would a validator request validation on that? There's nowhere to ask for expansion.

view this post on Zulip Alexander Henket (May 20 2019 at 08:47):

Why? there's slicing involved. Is it all implicit here? Would you do the same for effectiveTime as SXPR_TS versus IVL_TS? This is the V3 equivalent for type slicing

yes, you would

But for V3 effectiveTime, contrary to FHIR doseRange vs dosePeriod, there would not be any difference in path name, so something like "Use SXPR_TS with a comp IVL_TS and a comp PIVL_TS, OR use IVL_TS with a low and a high" could look like:

element SubstanceAdministration.effectiveTime
.... type SXPR_TS
element SubstanceAdministration.effectiveTime.comp
.... type IVL_TS
element SubstanceAdministration.effectiveTime.comp
.... type PIVL_TS
element SubstanceAdministration.effectiveTime
.... type IVL_TS
element SubstanceAdministration.effectiveTime.low
.... type TS
element SubstanceAdministration.effectiveTime.high
.... type TS

view this post on Zulip Grahame Grieve (May 20 2019 at 09:13):

the validator does inline expansion on inline value sets

view this post on Zulip Grahame Grieve (May 20 2019 at 09:13):

hmm. that issue will require some thought

view this post on Zulip Alexander Henket (May 20 2019 at 10:54):

the validator does inline expansion on inline value sets

Only if it knows about the systems involved, or if it is an extensional set I'm assuming

view this post on Zulip Grahame Grieve (May 20 2019 at 10:55):

it can handle pretty much anything, I think. If it can't resolve the value set, it just passes it to the terminology server as a parameter

view this post on Zulip Alexander Henket (May 20 2019 at 15:51):

Did anyone ever think of a terminology server hint extension on a ValueSet so you don't have to wonder where to search for answers based on just the ValueSet?

view this post on Zulip Grahame Grieve (May 20 2019 at 21:37):

can you explain that a bit more please

view this post on Zulip Rob Hausam (Jun 12 2020 at 22:15):

I'm raising this issue again. Have we categorically decided to reject this possibility (now and forever), or is it still open for consideration? There is no clear answer that I see to that up to this point in the topic thread. In the spec under Slicing it says:

One common feature of constraining StructureDefinitions is to take an element that may occur more than once (e.g. in a list), and then split the list into a series of sub-lists, each with different restrictions on the elements in the sub-list with associated additional meaning.

But that statement doesn't even include slicing polymorphic elements on type, which clearly is allowed, so the statement is obviously incomplete. And the Rules about Slicing in ElementDefinition also don't address this. We've also had several Zulip topics which have brought up the issue, but I don't see any firm conclusions on it.

@Lloyd McKenzie said here in Sep 2018 that:

It's legitimate to slice non-repeating elements

@Grahame Grieve disagreed with that and said that is documented here, but that actually only says (at least currently in the CI build) that you can slice polymorphic elements. Lloyd added that:

I still thought we supported slicing non-repeating elements. E.g. allowing you to say that a non-repeating element needs to follow constraint set X or Y

And @Michel Rutten questioned:

I wasn't aware that slicing is apparently only allowed for repeating elements... why would cardinality be a limiting factor?

The remainder of that Zulip topic thread had some further discussion, but (to my reading) didn't resolve whether this is (or should be) allowed or not - just that the tools likely didn't support it, but there was no significant technical barrier to implementing it. The same issue has been picked up and discussed in several other topics (the ones that I've found are here, here and here) - with my summary of the overall conclusions being Grahame's thoughts that it's "semantically wrong" and "non-sensical", and also the observations that it's not currently supported (or at least not fully supported) by the tooling.

After looking again through all of this, it seems to me that @Marten Smits's original request at the beginning of this topic thread, also repeated by others (including myself), to be able to slice a non-repeating non-polymorphic element to allow a choice between multiple sets of constraints would be useful to have in a number of situations. And it also doesn't seem that it's been clearly explained (at least not yet) why this should be explicitly disallowed. I'm interested in hearing what the community thinks about it at this point. And if we come to the conclusion yet again that we don't allow this, then I would at least like to see that made explicit and explained to a reasonable degree in the specification, so that maybe we can lessen any confusion and ideally avoid the need to keep discussing this.

view this post on Zulip Grahame Grieve (Jun 12 2020 at 22:20):

Slicing can be used in any resource that has cardinality ..* on the base resource, or any resource with a choice of types.

view this post on Zulip Grahame Grieve (Jun 12 2020 at 22:20):

http://hl7.org/fhir/elementdefinition-definitions.html#ElementDefinition.slicing

view this post on Zulip Rob Hausam (Jun 12 2020 at 22:23):

Yes. I read it again but missed including that in the post. So it is stated there. But I still haven't seen a clear explanation of why it should be that way, as opposed to the alternative. What else have I missed?

view this post on Zulip Grahame Grieve (Jun 17 2020 at 16:52):

for me, it's about minimising complexity. Slicing is nasty and hard.

view this post on Zulip Rob Hausam (Jun 17 2020 at 19:41):

Yes. I agree that slicing is hard (I don't really want to call it nasty!) - but we decided to include it as a feature in FHIR from the very beginning, so we're kind of stuck with that at this point. :) And, (not presuming to discuss internal representations here) we've already built the code that handles this complexity. To restate the basic premise of slicing, it's that it allows multiple sets of constraints to be defined and then for one of those sets of constraints to be applied (based on the values of the discriminators) for a particular repeat of a repeating (max = *) element. But logically, a non-repeating (max = 1) element is simply the degenerate case of a repeating element - the single repeat in that case can have one of the defined constraint sets applied, just like any other repeat. And, beyond that, we're already slicing non-repeating elements in the polymorphic case - it's just that in that case we've pre-defined the slicing based on type rather than allowing other discriminators. So, at a simplistic level, if we stop explicitly excluding the non-repeating non-polymorphic case, then it should already be covered.

view this post on Zulip Alexander Zautke (Jul 03 2020 at 09:31):

Do we have a tracker item for this or any other formal vote on the issue?

view this post on Zulip Grahame Grieve (Jul 03 2020 at 09:36):

I'm not sure. It was a decision from a long time ago, that's for sure

view this post on Zulip Alexander Zautke (Jul 03 2020 at 09:45):

I just have the feeling that with some hindsight more people are in favor of allowing it and the .NET tooling supports it like @Ewout Kramer and @Marten Smits described it in 2017.

view this post on Zulip Alexander Zautke (Jul 03 2020 at 09:54):

Any proposals on how to move this forward?

view this post on Zulip Grahame Grieve (Jul 03 2020 at 10:25):

I guess to create a task and ask FHIR-I to consider it.

view this post on Zulip Grahame Grieve (Jul 03 2020 at 10:25):

I'm not in favour, as you can probably tell. I don't really see the use case

view this post on Zulip Alexander Zautke (Jul 03 2020 at 10:42):

@Rob Hausam Could you create this tracker item and highlight a few IPS use cases based on which we could discuss the issue?

view this post on Zulip Lloyd McKenzie (Jul 03 2020 at 13:39):

The use-case is to describe alternatives where it's clearer, cleaner - or in some cases, only possible - to use element-based constraints to define the alternatives (i.e. FHIRPath invariants don't meet the requirement)

view this post on Zulip Rob Hausam (Jul 03 2020 at 16:07):

Yes, I can create a tracker for this and include the cases that we have in IPS (and probably some others that I've heard about). I'll try to do that later today.

view this post on Zulip Grahame Grieve (Jul 03 2020 at 20:54):

it's hard for to imagine that slicing is better than some other alternative

view this post on Zulip Rob Hausam (Jul 04 2020 at 03:03):

It's not too hard for me to imagine - it seems like a good fit for what we want to do, and that's why we went that way. I think it seems preferable, at least in some cases, to having a single value set with everything included. Of course that can be discussed and debated, and either can work. Do you have some other alternatives in mind?

view this post on Zulip Lloyd McKenzie (Jul 04 2020 at 03:32):

The only other alternative I'm aware of is FHIRPath, and slicing is generally better than that - both for being more expressive than FHIRPath can be and for being easier for most folks to read and understand.

view this post on Zulip Alexander Zautke (Sep 14 2020 at 19:20):

@Rob Hausam Did you create the tracker item with the IPS use cases? Would this be a good topic for the WGM?

view this post on Zulip Rob Hausam (Sep 17 2020 at 13:41):

@Alexander Zautke Sorry for the slow reply. I had a tracker (with quite a bit of text) ready to submit but lost it due to a Confluence glitch. :( It's still on my plate to redo and submit it. We're tracking it on the IPS calls (including yesterday). I agree that it is a good topic for the WGM, so I will get it on the front burner again and have the tracker submitted and ready in advance of next week. I guess we need to figure out where best to discuss it?

view this post on Zulip Rob Hausam (Sep 17 2020 at 13:42):

Presumably a FHIR-I session, so I will look at that.

view this post on Zulip Rob Hausam (Sep 21 2020 at 20:33):

I'll still submit that tracker.

view this post on Zulip Yunwei Wang (Sep 23 2020 at 13:52):

@Alexander Zautke I added this to Monday's regular call agenda (Monday 3 PM ET). @Rob Hausam If you have tracker number, I can add to agenda.

view this post on Zulip Rob Hausam (Sep 23 2020 at 14:35):

Thanks, Yunwei. I'm still working on finding the time to collect the details again and get the tracker submitted (I should be able to do that today). I'll let you know the tracker number when I do.

view this post on Zulip Abel Enthoven (Feb 02 2021 at 12:56):

We talked about your issue in the FHIR-I call @Rob Hausam (didn't see whether or not you were there too). The request was denied on grounds of complexity and the fact that it would impact the implementations in toolings on different platforms. However, we as Firely maintain the .NET tooling (the SDK/API) and for us the impact of implementing this would be relatively small since we already make very little distinction between 'singular' and 'plural' element definitions. So for us the complexity would actually ga down, since we wouldn't have to make the distinction anymore. And logically it also makes sense to synchronize the two. I can imagine this can be (much) harder in other implementations though. @Grahame Grieve , for example, told us that it would be a lot of work in the Java tooling. Since it is potentially also quite an incompatible change, I would personally suggest to at least defer the change a little bit and put it on the road map for R5? Would that be an option?

view this post on Zulip Rob Hausam (Feb 02 2021 at 14:39):

Yes, I saw that (and chatted with @Lloyd McKenzie about it a bit afterward). I normally try to make it for the FHIR-I calls, but had to miss it yesterday. :( And I had no idea that this tracker was going to be on the agenda. I appreciate hearing your perspective on it from Firely, @Abel Enthoven, as what you said is what makes sense to me. I agree that ultimately this should actually help to reduce the overall complexity, rather than add to it - but rework is always hard, as @Grahame Grieve indicated. It doesn't seem to me that the change to support this would be incompatible, as it would be officially supporting an additional capability but would not be removing or changing anything that is already being supported. And I think in the spec itself it is only the text describing slicing and the rules for it that would need to be changed? That is why if it had been approved, this could potentially be used in R4 if the tooling was updated to support it. And at this point I'm fine with looking further at any possibilities for R5, as long as there is sufficient interest (probably beyond just the IPS team). @Giorgio Cangioli

But my interpretation of the vote and resolution yesterday and the subsequent discussion so far is that the intent of that was pretty much to close the door on this - unless "there are a number of convincing use-cases brought forward that can't reasonably be met by another technical solution". I think we've already made the case for including this, and I'm not sure that anyone will bring forward new use cases (or very many of them) that don't have, even if not as elegant, some available workaround. And actually I think you could probably make that same argument for slicing in general. Slicing is now a very prominent and useful feature in FHIR profiling. But I suspect it may be correct to say that if FHIR didn't already have slicing, that we could argue against adding it at all because it doesn't provide any capabilities that couldn't "reasonably be met by another technical solution". That's my take at the moment, and I'm happy to have further discussion.

view this post on Zulip Lloyd McKenzie (Feb 02 2021 at 14:51):

Changing cardinality breaks the json representation, so it's somewhat problematic, but technically allowed to do. The use-cases that we saw submitted so far were ones that could be handled easily enough with invariants. If you have convincing use-cases that can't be met with invariants, please bring them forward.

view this post on Zulip Abel Enthoven (Feb 02 2021 at 15:45):

Of course you are right @Lloyd McKenzie that there are no use cases demanding these changes as all of them could be covered by invariants. I do think there is one compelling argument for me to change it anyway though. As @Rob Hausam says all of the restrictions made using slicing on 'plural' element definitions could also be covered using invariants. But if you continue on that path, there is much more of the restrictions (minvalue, maxvalue, fixed, etc.) that could be covered using invariants. To me (but correct me if I'm wrong) one of the reasons for separating those restrictions out in their own fields was that a user interface would be able to use them to 'automagically' generate the appropriate components. For example: knowing the maximum length of a string you can generate an appropriately sized text field. At a certain point though, the elementDefinition cannot continue to grow more complex and invariants take over. And for many situations they suffice, for they can be executed against the model and generate warnings or errors bound to an element. So there is a balance between complexity of the ElementDefinition and the use of the model for automation. In the case of slicing of the 'singular' element definition, I think I could argue that it would be useful for an automated system to know which possibilities it needs to support for a singular element. Although it is theoretically possible to derive that from invariants I think it would be very beneficial to be able to read them directly from the sliced ElementDefinition.

view this post on Zulip Lloyd McKenzie (Feb 02 2021 at 15:49):

To be clear, I am in favor of allowing slicing on non-repeating elements. Conceptually, there are all sorts of reasons why it could be useful. The resolution was saying that we're not going to undertake the degree of effort required for conceptual benefits - we need concrete practical benefits. "Real-world" scenarios that obviously need to be supported, but where using invariants can't cut it - either because it's expressing things that invariants can't do, or because the invariants would get unreasonably complex/non-maintainable/non-comprehensible.

view this post on Zulip Rob Hausam (Feb 02 2021 at 17:12):

We'll continue to think about and see about compiling the "Real-world" scenarios. At least if the bar is "invariants can't cut it" because they "would get unreasonably complex/non-maintainable/non-comprehensible", that is somewhat easier to meet than "can't be met with invariants", which would be nearly or completely impossible.

view this post on Zulip Lloyd McKenzie (Feb 02 2021 at 17:14):

Invariants can't express mustSupport, can't provide documentation or usage notes.

view this post on Zulip Rob Hausam (Feb 02 2021 at 17:18):

Yes, that is true. Maybe we can further describe why those items are needed, or at least are very useful to have.

view this post on Zulip Rob Hausam (Feb 02 2021 at 17:19):

@Lloyd McKenzie I'm also not clear what you are thinking of in regard to "changing cardinality", as I don't think that allowing a non-repeating (0..1 or 1..1) element to be sliced has anything to do with making changes to cardinality or anything that would affect the json representation. Can you explain?

view this post on Zulip Lloyd McKenzie (Feb 02 2021 at 17:27):

Never mind. My head was thinking about something else that wasn't relevant. No cardinality change would be involved in loosening this restriction.

view this post on Zulip Rob Hausam (Feb 02 2021 at 17:29):

No problem - thanks for the clarification!

view this post on Zulip Grahame Grieve (Feb 02 2021 at 21:25):

any change to the snapshot generation / validation code is now scary - changes to test cases are starting to mean weeks of work to deal with the ramifications. Irrespective of the actual work in the code.

view this post on Zulip Grahame Grieve (Feb 02 2021 at 21:25):

I think that the real driver is bindings. I'm going to work on them independently

view this post on Zulip Rob Hausam (Feb 02 2021 at 21:42):

I'm happy that you are planning to work on bindings. But a binding is a type of constraint. And a slice is a set of constraints (which may include a binding) which is applied for an instance of an element or group of elements that matches the condition(s) in the discriminator (assuming that a discriminator has been defined, which is by far the most common and the preferred case). I'm not sure (yet) entirely what you have in mind for bindings going forward, but whatever it is it should be able to be and actually be applied consistently across the board - whether the element includes or is part of defined slices or not. And I assume that you already have that well in mind, but I'm just stating it to be clear.

view this post on Zulip Jean Duteau (Feb 02 2021 at 21:50):

i'm reading this with interest as I have had a number of cases in my guides where I wanted to slice a choice - if you send me a code, it has these constraint, if it is a reference, it has these constraints, if it is an integer, it has these constraints (to make up a purely arbitrary set of slices). I can obviously use constraints to provide the restrictions on each choice, but I feel that it is a presentation perspective. It seems to me that it is easier to portray and understand if it were presented as constraints on slices versus having to read the constraints.

view this post on Zulip Grahame Grieve (Feb 02 2021 at 21:58):

we're not proposing to remove type slicing

view this post on Zulip Rob Hausam (Feb 02 2021 at 21:59):

@Jean Duteau A choice type (i.e. a polymorphic element) uses the slicing mechanism internally. And I think the display in the spec (core or IG) is for the most part consistent with that. So I'm not quite sure what you are describing or looking for that is different from or goes beyond that. If there is something, maybe you can clarify that?

view this post on Zulip Jean Duteau (Feb 02 2021 at 22:00):

no, i misread Abel's statement as removing any slicing on non-repeating elements including type slicing. so my bad.

view this post on Zulip Rob Hausam (Feb 02 2021 at 22:03):

Oh, right, that makes sense. As Grahame said, there hasn't been a suggestion or a decision to change that.

view this post on Zulip Jean Duteau (Feb 02 2021 at 22:04):

going back to reading his statement it isn't as "omg, what are they doing!" as I first read. :)

view this post on Zulip Rob Hausam (Feb 02 2021 at 22:05):

We've just been arguing that non-repeating non-polymorphic elements should be given equal treatment. :)


Last updated: Apr 12 2022 at 19:14 UTC