firely-cql-sdk icon indicating copy to clipboard operation
firely-cql-sdk copied to clipboard

Implement implicit casts from List<X> to List<Y>, if X is convertible to Y

Open ewoutkramer opened this issue 1 year ago • 4 comments

Bryn's compiler supports conversions from List<X> to a List<Y>, where X is convertible to Y. Lacking a foreach construct, the actual conversion is carried out using a query.

The fact that this is possible, means it is also allowed to mix List<X> and List<Y>, as in the following List constructor:

define y: { {4}, {6.0} }

The ELM required to make this work looks like this:

 "expression": {
            "type": "List",
            "element": [
              {
                "type": "Query",
                "source": [
                  {
                    "type": "AliasedQuerySource",
                    "expression": {
                      "type": "List",
                      "element": [
                        {
                          "type": "Literal",
                          "locator": "11:14",
                          "resultTypeName": "{urn:hl7-org:elm-types:r1}Integer",
                          "valueType": "{urn:hl7-org:elm-types:r1}Integer",
                          "value": "4"
                        }
                      ],
                      "resultTypeSpecifier": {
                        "type": "ListTypeSpecifier",
                        "elementType": {
                          "type": "NamedTypeSpecifier",
                          "name": "{urn:hl7-org:elm-types:r1}Integer"
                        }
                      },
                      "locator": "11:13-11:15"
                    },
                    "alias": "X"
                  }
                ],
                "return": {
                  "type": "ReturnClause",
                  "expression": {
                    "type": "ToDecimal",
                    "operand": {
                      "type": "AliasRef",
                      "name": "X"
                    }
                  },
                  "distinct": false
                }
              },
              {
                "type": "List",
                "element": [
                  {
                    "type": "Literal",
                    "locator": "11:19-11:21",
                    "resultTypeName": "{urn:hl7-org:elm-types:r1}Decimal",
                    "valueType": "{urn:hl7-org:elm-types:r1}Decimal",
                    "value": "6.0"
                  }
                ],
                "resultTypeSpecifier": {
                  "type": "ListTypeSpecifier",
                  "elementType": {
                    "type": "NamedTypeSpecifier",
                    "name": "{urn:hl7-org:elm-types:r1}Decimal"
                  }
                },
                "locator": "11:18-11:22"
              }
            ],
            "resultTypeSpecifier": {
              "type": "ListTypeSpecifier",
              "elementType": {
                "type": "ListTypeSpecifier",
                "elementType": {
                  "type": "NamedTypeSpecifier",
                  "name": "{urn:hl7-org:elm-types:r1}Decimal"
                }
              }
            },
            "locator": "11:11-11:24"
          },
          "resultTypeSpecifier": {
            "type": "ListTypeSpecifier",
            "elementType": {
              "type": "ListTypeSpecifier",
              "elementType": {
                "type": "NamedTypeSpecifier",
                "name": "{urn:hl7-org:elm-types:r1}Decimal"
              }
            }
          },
          "locator": "11:1-11:24",
          "name": "y",
          "context": "Patient",
          "accessLevel": "Public"
        }
      ]
    },

Note how the type of the outer list is determined to be List<List<Decimal>>, and the elements of the List<Integer> are translated to a List<Decimal> using a query construct.

ewoutkramer avatar Oct 25 '23 22:10 ewoutkramer