Enum default value oddity

Greetings, ran across this nugget and thought I’d ask for clarity.

When defining an attribute use typed as an enum, it is possible to assign it a default value of a String. This surprised me, I assumed that the default values would be constrained to values of the enum.

So I dug into KerML, and found in Clause 8.4.4 a description of what is ‘essentially’ happening under the hood of an enum using a variation attribute def. THAT form refuses to allow a String as a default value, as expected.

The full package is below. SysIDE throws an error for the second form, but not the first.

Anyone with a deeper understanding than I have an explanation for this? Exactly how much work is that modifier ‘essentially’ doing in the KerML text? :face_with_monocle:

package EnumDefaultStringTest {
    doc
    /* KerML 1.0, Clause 8.4.4, pgs 404-405:
     *
     *  Therefore, anEnumerationDefinition of the form
     *      enum def E {
     *          enum e1;
     *          enum e2;
     *      }
     *  is essentially equivalent to
     *      variation attribute def E specializes Base::DataValue {
     *          variant attribute e1 : E subsets Base::dataValues;
     *          variant attribute e2 : E subsets Base::dataValues;
     *      }
     *
     */

    enum def ActualEnum {
        enum enum1;
    }
    attribute ae : ActualEnum default "Not an error... very surprising";

    variation attribute def EnumEquivalent specializes Base::DataValue {
        variant attribute eEnum1 : EnumEquivalent subsets Base::dataValues;
    }
    attribute ee : EnumEquivalent default "This is the expected error: ScalarValues::String does not conform to EnumDefaultStringTest::EnumEquivalent";

}

Your reading of the spec is correct, and the discrepancy you spotted is real. Note that the “essentially” in the spec is doing no work: it’s an abstract-syntax acknowledgement, not a semantic loophole.

Nice catch. Edges between sugar and desugaring are exactly where mismatches like this hide, so it’s a good instinct to push on them. I’ve raised this internally.

Thanks for the report, fixed for the next release.

There is a special case for enum value assignment that allows base type values from their enum defs to match other languages, e.g. C++. Allowing patterns such as

enum def E :> ScalarValues::String {
  enum a = "string";
}

even if a is technically typed by E. This was applied too broadly so constrained this special case to only work inside enum definitions.

Much appreciated, thanks.