diff --git a/query-languages/m/m-spec-consolidated-grammar.md b/query-languages/m/m-spec-consolidated-grammar.md index d8237bea..6ce7eb19 100644 --- a/query-languages/m/m-spec-consolidated-grammar.md +++ b/query-languages/m/m-spec-consolidated-grammar.md @@ -260,15 +260,13 @@ logical-and-expression:
_is-expression:
      as-expression
-      is-expression_ `is` _nullable-primitive-type
-nullable-primitive-type:_
-      `nullable`_opt primitive-type_ +      is-expression_ `is` _primitive-or-nullable-primitive-type_ #### As expression _as-expression:
      equality-expression
-      as-expression_ `as` _nullable-primitive-type_ +      as-expression_ `as` _primitive-or-nullable-primitive-type_ #### Equality expression @@ -448,15 +446,15 @@ fixed-parameter-list:
      parameter
      parameter_ `,` _fixed-parameter-list
parameter:
-      parameter-name primitive-parameter-typeopt
+      parameter-name parameter-typeopt
parameter-name:
      identifier
-primitive-parameter-type:
-      primitive-assertion
+parameter-type:
+      primitive-or-nullable-primitive-type-assertion
return-type:
-      primitive-assertion
-primitive-assertion:_
-      `as` _nullable-primitive-type
+      primitive-or-nullable-primitive-type-assertion
+primitive-or-nullable-primitive-type-assertion:_
+      `as` _primitive-or-nullable-primitive-type
optional-parameter-list:
      optional-parameter
      optional-parameter_ `,` _optional-parameter-list
@@ -510,7 +508,9 @@ primary-type:
      nullable-type
primitive-type:_ one of
      `any anynonnull binary date datetime datetimezone duration function`
-      `list logical none null number record table text time type`
+      `list logical none null number record table text time type`
+_primitive-or-nullable-primitive-type:_
+      `nullable`_opt primitive-type_
_record-type:_
      `[` _open-record-marker_ `]`
      `[` _field-specification-listopt_ `]`
@@ -548,7 +548,7 @@ optional-parameter-specification-list:
optional-parameter-specification:_
      `optional` _parameter-specification
parameter-specification:
-      parameter-name parameter-type
+      parameter-name parameter-type
parameter-type:
      assertion
assertion:_
diff --git a/query-languages/m/m-spec-functions.md b/query-languages/m/m-spec-functions.md index 6fe331ff..e368b12a 100644 --- a/query-languages/m/m-spec-functions.md +++ b/query-languages/m/m-spec-functions.md @@ -17,7 +17,7 @@ A _function_ is a value that represents a mapping from a set of argument values Functions are written using a _function-expression_: _function-expression:_
-      `(` _parameter-listopt_ `)` _function-return-typeopt_ `=>` _function-body
+      `(` _parameter-listopt_ `)` _return-typeopt_ `=>` _function-body
function-body:
      expression
parameter-list:
@@ -26,24 +26,24 @@ parameter-list:
      optional-parameter-list
fixed-parameter-list:
      parameter
-      parameter_ `,` _fixed-parameter-list
+      parameter_ `,` _fixed-parameter-list
parameter:
      parameter-name parameter-typeopt
parameter-name:
      identifier
parameter-type:
-      assertion
-function-return-type:
-      assertion
-assertion:_
-      `as` _nullable-primiitve-type
+      primitive-or-nullable-primitive-type-assertion
+return-type:
+      primitive-or-nullable-primitive-type-assertion
+primitive-or-nullable-primitive-type-assertion:_
+      `as` _primitive-or-nullable-primitive-type
optional-parameter-list:
      optional-parameter
      optional-parameter_ `,` _optional-parameter-list
optional-parameter:_
-      `optional` _parameter
-nullable-primitve-type
-      `nullable`_opt _primitive-type_ +      `optional` _parameter_
+_primitive-or-nullable-primitive-type:_
+      `nullable`_opt primitive-type_ The following is an example of a function that requires exactly two values `x` and `y`, and produces the result of applying the `+` operator to those values. The `x` and `y` are _parameters_ that are part of the _parameter-list_ of the function, and the `x + y` is the _function-body_: diff --git a/query-languages/m/m-spec-operators.md b/query-languages/m/m-spec-operators.md index 520c42b8..402a2ae2 100644 --- a/query-languages/m/m-spec-operators.md +++ b/query-languages/m/m-spec-operators.md @@ -2,7 +2,7 @@ title: M Language Operators description: Describes using operators in the Power Query M formula language ms.topic: conceptual -ms.date: 12/12/2024 +ms.date: 1/7/2025 ms.custom: "nonautomated-date" ms.subservice: m-specification --- @@ -133,12 +133,12 @@ The following table summarizes the M operators, listing the operator categories Type assertion x as y - Is compatible nullable-primitive type or error + Is compatible with primitive or nullable primitive type or error Type conformance x is y - Test if compatible nullable-primitive type + Test if compatible with primitive or nullable primitive type Logical AND @@ -1253,21 +1253,21 @@ The type compatibility operator `x is y` is defined for the following types of | X | Y | Result | | --- | --- | --- | -| `type any` | _nullable-primitive-type_ | `type logical` | +| `type any` | _primitive-or-nullable-primitive-type_ | `type logical` | -The expression `x is y` returns `true` if the ascribed type of `x` is compatible with `y`, and returns `false` if the ascribed type of `x` is incompatible with `y`. `y` must be a _nullable-primitivetype_. +The expression `x is y` returns `true` if the ascribed type of `x` is compatible with `y`, and returns `false` if it is not compatible. `y` must be a _primitive-or-nullable-primitive-type_. _is-expression:
      as-expression
-      is-expression_ `is` _nullable-primitive-type
-nullable-primitive-type:_
-      `nullable`_opt primitive-type_ +      is-expression_ `is` _primitive-or-nullable-primitive-type
+primitive-or-nullable-primitive-type:_
+      `nullable`_opt primitive-type_
Type compatibility, as supported by the `is` operator, is a subset of [general type compatibility](m-spec-types.md) and is defined using the following rules: * If `x` is null then it is compatible if `y` is the type `any`, the type `null`, or a nullable type. -* If `x` is non-null then if it is a compatible if the the primitive type of `x` is the same as `y`. +* If `x` is non-null then it is a compatible if the primitive type of `x` is the same as `y`. The following holds when evaluating the expression `x is y`: @@ -1279,13 +1279,15 @@ The type assertion operator `x as y` is defined for the following types of value | X | Y | Result | | --- | --- | --- | -| `type any` | _nullable-primitive-type_ | `type any` | +| `type any` | _primitive-or-nullable-primitive-type_ | `type any` | -The expression `x as y` asserts that the value `x` is compatible with `y` as per the `is` operator. If it is not compatible, an error is raised. `y` must be a _nullable-primitive-type_. +The expression `x as y` asserts that the value `x` is compatible with `y` as per the `is` operator. If it is not compatible, an error is raised. `y` must be a primitive type or a nullable primitive type. _as-expression:
      equality-expression
-      as-expression_ `as` _nullable-primitive-type_ +      as-expression_ `as` _primitive-or-nullable-primitive-type
+primitive-or-nullable-primitive-type:_
+      `nullable`_opt primitive-type_ The expression `x as y` is evaluated as follows: diff --git a/query-languages/m/m-spec-types.md b/query-languages/m/m-spec-types.md index e44eea8a..97ada8aa 100644 --- a/query-languages/m/m-spec-types.md +++ b/query-languages/m/m-spec-types.md @@ -2,7 +2,7 @@ title: M Language types description: Describes using types in the Power Query M formula language ms.topic: conceptual -ms.date: 1/31/2024 +ms.date: 1/3/2025 ms.custom: "nonautomated-date" ms.subservice: m-specification --- @@ -29,22 +29,24 @@ The set of _primitive types_ includes the types of primitive values, and a numbe All types that are not members of the closed set of primitive types plus their nullable counterparts are collectively referred to as _custom types_. Custom types can be written using a `type-expression`: +_primitive-type:_ one of
+      `any anynonnull binary date datetime datetimezone duration function list logical`
+      `none null number record table text time type`
+_primitive-or-nullable-primitive-type:_
+      `nullable`_opt primitive-type_
+ +All other types are collectively referred to as _custom types_. Custom types can be written using a `type-expression`: + _type-expression:
      primary-expression_
      `type` _primary-type
-type:
-      primary-expression
-      primary-type
primary-type:
      primitive-type
      record-type
      list-type
      function-type
      table-type
-      nullable-type
-primitive-type:_ one of
-      `any anynonnull binary date datetime datetimezone duration function list logical`
-      `none null number record table text time type` +      nullable-type_ The _primitive-type_ names are _contextual keywords_ recognized only in a _type_ context. The use of parentheses in a _type_ context moves the grammar back to a regular expression context, requiring the use of the type keyword to move back into a type context. For example, to invoke a function in a _type_ context, parentheses can be used: @@ -95,7 +97,7 @@ Value.Type( 1 as number ) // type number {2} as text // error, type mismatch ``` -Note that the `is` and `as` operators only accept nullable primitive types as their right operand. M does not provide means to check values for conformance to custom types. +Note that the `is` and `as` operators only accept a _primitive or nullable primitive type_ (i.e. a _non-custom type_) as their right operand. M does not provide means to check values for conformance to custom types. A type `X` is _compatible_ with a type `Y` if and only if all values that conform to `X` also conform to `Y`. All types are compatible with type `any` and no types (but `none` itself) are compatible with type `none`. The following graph shows the compatibility relation. (Type compatibility is reflexive and transitive. It forms a lattice with type `any` as the top and type `none` as the bottom value.) The names of abstract types are set in _italics_. @@ -210,28 +212,28 @@ A conforming value may contain field names not listed in the field specification Any function value conforms to the primitive type `function`, which does not place any restrictions on the types of the function's formal parameters or the function's return value. A custom _function-type value_ is used to place type restrictions on the signatures of conformant function values. -_function-type:_
-      `function (` _parameter-specification-listopt_ `)` _function-return-type
+function-type:_
+      `function (` _parameter-specification-listopt_ `)` _return-type
parameter-specification-list:
      required-parameter-specification-list
      required-parameter-specification-list_ `,` _optional-parameter-specification-list
      optional-parameter-specification-list
required-parameter-specification-list:
      required-parameter-specification
-      required-parameter-specification_ `,` _required-parameter-specification-list
+      required-parameter-specification_ `,` _required-parameter-specification-list
required-parameter-specification:
      parameter-specification
optional-parameter-specification-list:
      optional-parameter-specification
-      optional-parameter-specification_ `,` _optional-parameter-specification-list
+      optional-parameter-specification_ `,` _optional-parameter-specification-list
optional-parameter-specification:_
-      `optional` _parameter-specification
+      `optional` _parameter-specification
parameter-specification:
-      parameter-name parameter-type
-function-return-type:
+      parameter-name parameter-type
+parameter-type:
      assertion
assertion:_
-      `as` _nullable-primitive-type_ +      `as` _type_ The result of evaluating a _function-type_ is a type value whose base type is `function`. @@ -364,7 +366,7 @@ Value.Type( Value.ReplaceType( {1}, type {number} ) Type equivalence is not defined in M. An M implementation may optionally choose to use its own rules to perform equality comparisons between type values. Comparing two type values for equality should evaluate to `true` if they are considered identical by the implementation, and `false` otherwise. In either case, the response returned must be consistent if the same two values are repeatedly compared. Note that within a given implementation, comparing some identical type values (such as `(type text) = (type text)`) may return `true`, while comparing others (such as `(type [a = text]) = (type [a = text])`) may not. -Compatibility between a given type and a nullable primitive type can be determined using the library function `Type.Is`, which accepts an arbitrary type value as its first and a nullable primitive type value as its second argument: +Compatibility between a given type and either a primitive type or a nullable primitive type can be determined using the library function `Type.Is`, which accepts an arbitrary type value as its first argument and a primitive or nullable primitive type value as its second argument: ```powerquery-m Type.Is(type text, type nullable text) // true