diff --git a/SPEC.md b/SPEC.md index 2a89f3bc..7582ff1b 100644 --- a/SPEC.md +++ b/SPEC.md @@ -1491,15 +1491,16 @@ Note that the ability to assign values to `Struct` declarations other than struc ##### Enumeration Types (Enums) -An enumeration (or "enum") is a closed set of alternatives that are considered semantically valid in a specific context. An enum is [defined]() at the top-level of the WDL document and can be used as a declaration type anywhere in the document. +An enumeration (or "enum") is a closed set of enumerated values (known as "variants") that are considered semantically valid in a specific context. An enum is defined at the top-level of the WDL document and can be used as a declaration type anywhere in the document. -An enum is defined using the `enum` keyword, followed by a globally unique name, followed by a comma-delimited list of identifiers in braces. The value for an enum cannot be created; rather, it must be selected from the list of available values using the `.` syntax. +An enum is defined using the `enum` keyword, followed by a globally unique name, followed by a comma-delimited list of identifiers—optional tagged with values—in braces. When referring to a variant within an enum, for example, when assigning to an enum declaration, the `.` syntax should be used. ```wdl enum FileKind { FASTQ, BAM } + task process_file { input { File infile @@ -1516,6 +1517,7 @@ workflow process_files { Array[File] files FileKind kind } + scatter (file in files) { call process_file { input: @@ -1526,7 +1528,49 @@ workflow process_files { } ``` -As an example, consider a workflow that processes different types of NGS files and has a `file_kind` input parameter that is expected to be either "fastq" or "bam". Using `String` as the type of `file_kind` is not ideal - if the user specifies an invalid value, the error will not be caught until runtime, perhaps after the workflow has already run for several hours. Alternatively, using an `enum` type for `file_kind` restricts the allowed values such that the execution engine can validate the input prior to executing the workflow. +As an example, consider a workflow that processes different types of NGS files and has a `file_kind` input parameter that is expected to be either "FASTQ" or "BAM". Using `String` as the type of `file_kind` is not ideal - if the user specifies an invalid value, the error will not be caught until runtime, perhaps after the workflow has already run for several hours. Alternatively, using an `enum` type for `file_kind` restricts the allowed values such that the execution engine can validate the input prior to executing the workflow. + +Enums are valued, meaning that each variant within an enum has an associated value. To assign a type to the values therein, enums can either be _explicitly_ or _implicitly_ typed. + +* Explicitly typed enums take an explicit type assigment within square brackets after the enum's identifier that declares the type of the value. Where possible, explicitly typed enums should resolve ambiguities via coercion. +* Implicitly typed enums are enums where the values can be unambiguously mapped to a single [primitive type](#primitive-types). Enums that are implicitly typed and for which no values are assigned are assumed to be `String` valued with values matching the variant names. All values within an enum must have the same type or an error is thrown. + +```wdl +# An explicitly typed enum that is `String`-valued. +enum FruitColors[String] { + Banana = "yellow", + Orange = "orange", + Apple = "red", +} + +# An explicitly typed enum that is `Float`-valued. Because the enum is +# explicitly typed, the `ThreePointOh` variant can be coerced to a `Float`, +# which is a valid enumeration definition. +enum FavoriteFloat[Float] { + ThreePointOh = 3, + FourPointOh = 4.0 +} + +# ERROR: because the enum is implicitly typed, the type cannot be unambiguously +# resolved, which results in an error. +enum FavoriteNumber { + ThreePointOh = 3, + FourPointOh = 4.0 +} + +# An implicitly typed enum that is `String`-valued. +enum Whitespace { + Tab = "\t", + Space = " " +} + +# An implicitly typed enum that is implied to be `String`-valued with the +# values "FASTQ" and "BAM" respectively. +enum FileKind { + FASTQ, + BAM +} +``` #### Hidden and Scoped Types