FHIR Chat · Nested items in rulesets · shorthand

Stream: shorthand

Topic: Nested items in rulesets


view this post on Zulip Jose Costa Teixeira (Feb 02 2021 at 17:21):

Is it possible to have a ruleset populate nested items?

view this post on Zulip Jose Costa Teixeira (Feb 02 2021 at 17:23):

RuleSet: Question(linkId, text, type, repeats)
* item[+].linkId = "{linkId}"
* item[=].text = "{text}"
* item[=].type = #{type}
* item[=].repeats = {repeats}

This works OK for top level, but I need it to create

* item[=].item[=].item[=].item[+].linkId = "{linkId}"
* item[=].item[=].item[=].item[=].text = "{text}"
* item[=].item[=].item[=].item[=].type = #{type}
* item[=].item[=].item[=].item[=].repeats = {repeats}

And I don't want to have to create a ruleset for each level

view this post on Zulip Jose Costa Teixeira (Feb 02 2021 at 17:23):

in other words, when is the with coming? :)

view this post on Zulip Elliot Silver (Feb 02 2021 at 17:23):

Yup, I noted this a couple of days ago (https://chat.fhir.org/#narrow/stream/215610-shorthand/topic/Soft.20Indexing.20downside/near/224426782).

view this post on Zulip Elliot Silver (Feb 02 2021 at 17:27):

I was trying to think of a way to pass in the parent item, and then tack on the current context, but I haven't built a working example yet.

view this post on Zulip Elliot Silver (Feb 02 2021 at 17:32):

RuleSet: Question(context, linkId, text, type, repeats)
* {context}.item[+].linkId = "{linkId}"
* {context}.item[=].text = "{text}"
* {context}.item[=].type = #{type}
* {context}.item[=].repeats = {repeats}

Then you could do:

* insert(this, ...)
* insert(item[=], ...)

Not sure, just theorizing...

view this post on Zulip Chris Moesel (Feb 02 2021 at 17:33):

@Jose Costa Teixeira -- we're experimenting w/ contextual rule grammars right now. And I agree, this is a good advanced use case for it. But another possible approach I've considered for this type of use case (inserting a ruleset in the context of a path):

* item[=].item[=].item[=] insert Question(foo, Foo?, boolean, false)

That would match some of our other grammars that are {path} {command} {value}.

For the time being, it is ugly, but I think this would work w/ the current grammar:

RuleSet: Question(prefixPath, linkId, text, type, repeats)
* {prefixPath}item[+].linkId = "{linkId}"
* {prefixPath}item[=].text = "{text}"
* {prefixPath}item[=].type = #{type}
* {prefixPath}item[=].repeats = {repeats}

then

* insert Question(item[=].item[=].item[=]., foo, Foo?, boolean, false)

view this post on Zulip Jose Costa Teixeira (Feb 02 2021 at 17:34):

Right - this is ugly :) I'm trying it now

view this post on Zulip Chris Moesel (Feb 02 2021 at 17:35):

Ha. I see that @Elliot Silver beat me to the punch on that last one. But SUSHI doesn't understand this, so I think you'd need to do something more like my example that would work w/ and empty prefixPath to have no nested path (but requires trailing . when there is a nested path).

view this post on Zulip Jose Costa Teixeira (Feb 02 2021 at 17:38):

correct

view this post on Zulip Jose Costa Teixeira (Feb 02 2021 at 17:38):

still

view this post on Zulip Elliot Silver (Feb 02 2021 at 17:38):

Or maybe do:

RuleSet: Question(context, linkId, text, type, repeats)
* {context}[+].linkId = "{linkId}"
* {context}[=].text = "{text}"
* {context}[=].type = #{type}
* {context}[=].repeats = {repeats}

On first look the ruleset in context looks ugly, but it's somewhat growing on me.

view this post on Zulip Jose Costa Teixeira (Feb 02 2021 at 17:38):

  • insert Question(* item[=].,pastOrPresent,Active\, Inactive or Resolved allergy?,choice,false)
Sushi: Line: 22                                                                  (00:01.0634)
Sushi: error Errors parsing insert rule with parameterized RuleSet Question      (00:01.0642)
Sushi: - no viable alternative at input '* *'                                    (00:01.0690)

view this post on Zulip Jose Costa Teixeira (Feb 02 2021 at 17:39):

sorry

view this post on Zulip Elliot Silver (Feb 02 2021 at 17:39):

Don't include the *

view this post on Zulip Jose Costa Teixeira (Feb 02 2021 at 17:58):

indeed.

view this post on Zulip Jose Costa Teixeira (Feb 02 2021 at 17:59):

confirming - this works

view this post on Zulip David Pyke (Feb 02 2021 at 20:55):

Next on "Obfuscating FSH", we'll present the award winners, Elliot and Jose for their "Impenetrable Item Path"

view this post on Zulip Elliot Silver (Feb 02 2021 at 21:06):

@David Pyke you probably don't want me to ask the other thing I've been wondering about with rulesets: can they nest? Can one ruleset invoke another? All of this questionnaire stuff is great, except that the item type dictates the information that needs to be collected. So, can I do:

RuleSet: Question(context, linkId, text, type, repeats)
* {context}[+].linkId = "{linkId}"
* {context}[=].text = "{text}"
* {context}[=].type = #{type}
* {context}[=].repeats = {repeats}

RuleSet: QuestionValueSet(context, linkId, text, repeats, vs)
* insert Question({context}, {linkId}, {text}, choice, {repeats})
* {context}[=].choiceValueSet = {vs}

...
* insert Question(item, foo, bar, group, false)
* insert QuestionValueSet(item, baz, boom, false, myValueSet.)

view this post on Zulip David Pyke (Feb 02 2021 at 21:17):

Give it a shot and see how many layers of rulesets you can do before it screams

view this post on Zulip Elliot Silver (Feb 02 2021 at 21:21):

ooh, can we do
recursive fsh?

view this post on Zulip Chris Moesel (Feb 02 2021 at 21:58):

Yeah, you should be able to do recursive rule sets as long as they don't infinitely recurse. That said, I do wonder if maybe things would get gummed up w/ the escape sequences, because the escaping \ would get removed when it's applied the first time. I'll have to try it.

view this post on Zulip Chris Moesel (Feb 02 2021 at 22:04):

Ugh. Yeah, the recursive calls don't work with escapes. Dang. We're trying to avoid doing anything too clever, but... we might have to do something clever to support this. https://fshschool.org/FSHOnline/#/share/2YFQDdu

view this post on Zulip Elliot Silver (Feb 02 2021 at 22:06):

@Chris Moesel , just to be clear, I don't really see a need for recursive rulesets, particularly since there is no way to encode stop conditions. On the other hand, I do see a need for nested rulesets.

view this post on Zulip Chris Moesel (Feb 02 2021 at 22:40):

Well even nested ones would have an issue in the (hopefully rare) case that a substitution you pass in at the top-level needs to be passed into a nested rule set insert rule and needs to have an escaped character (( or ,). But we'll try to fix that. Aside from that one issue, nested rulesets should be fine.

view this post on Zulip Elliot Silver (Feb 02 2021 at 22:44):

Maybe add a marker to where a parameter is used indicating whether to leave the content escaped? Arbitrarily choosing exclamation as the marker, my nested example would become:

RuleSet: QuestionValueSet(context, linkId, text, repeats, vs)
* insert Question({!context}, {!linkId}, {!text}, choice, {!repeats})
* {context}[=].choiceValueSet = {vs}

view this post on Zulip Chris Moesel (Feb 04 2021 at 20:10):

That seems a reasonable approach. I was also thinking just to automatically keep the escape chars when we know we're expanding into an insert rule. That would be less for authors to remember and fewer opportunities to make a mistake and forget to do it. I also can't think of any other use cases where you would want to specifically keep \, and \)except when passing into another insert rule.

view this post on Zulip Chris Moesel (Feb 04 2021 at 20:11):

But if that proves too hard and we need to have a signal to leave it unescaped, I like the ! -- it's brief and to the point.

view this post on Zulip Elliot Silver (Feb 04 2021 at 20:20):

I wonder if there are use cases where you want to pass in escaped content that remains escaped in the expansion? For example passing in text that needs to remain escaped so the correct html/markdown is generated.

view this post on Zulip ryan moehrke (Feb 04 2021 at 21:50):

but then you should just escape your escape characters, no?

view this post on Zulip ryan moehrke (Feb 04 2021 at 21:52):

like, if I want my text to be explicitly "(\abc\)123" then I should pass in "(\\abc\\\)123" it doesn't matter in that case if I end up using that in the initial ruleset or passing it through to another one, that text is what I want to write under Chris's model right?

view this post on Zulip Elliot Silver (Feb 04 2021 at 21:59):

hmm, right. So if it is used in the ruleset, the use removes a level of escaping. If it is passed into another ruleset, the passed-in value does not escape. Yeah, you could probably get away without a "don't touch that" signal.

view this post on Zulip John Moehrke (Feb 04 2021 at 22:35):

you should listen to that Mr Moehrke dude

view this post on Zulip Chris Moesel (Feb 04 2021 at 23:44):

Right. And the only things we support escaping for are \, ,, and ) -- which is probably a little too narrow and specific to be useful anywhere else but in the context of insert rules.


Last updated: Apr 12 2022 at 19:14 UTC