none
Type Equality RRS feed

  • Question

  • Hello,

    I was wondering if someone from the language team could help me with a clarification question. :-)

    In the language specification, under “Equality operators” (section 6.6), the last bullet starts with:

    A type value is equal to itself, but may or may not be equal to another type value. ...

    However, in practice, it seems like the claim that a type value will equal itself is only guaranteed to hold true for what the specification calls nullable primitive types but not (necessarily?) for custom types. Based on this, it seems like the rule really is:

    A nullable primitive type value is equal to itself, but may or may not be equal to another type value. A custom type may or may not be equal to itself or another type value. ...

    Is this correct or am I missing something here? (Trying to make sure I am accurately understanding the details here.)


    Details

    Nullable Primitive Types: any, anynonnull, binary, date, datetime, datetimezone, duration, function, list, logical, none, null, number, record, table, text, type
    (any of the preceding can also be marked as nullable by proceeding it with “nullable”)

    Examples of comparisons between nullable primitive types:

    • type number = type number // true
    • type table = type table // true
    • type any = type nullable anynonnull // true, as both evaluate to same type

    Examples of comparisons between custom types:

    • type {number} = type {number} // false
    • type table [A = text] = type table [A = text] // false

     

    Thank you,
    Ben

     




    Monday, January 20, 2020 8:46 PM

Answers

  • Both primitive types and nullable primitive types are always equal to themselves. This includes the primitive types "type record", "type table" and "type list".
    • Marked as answer by Ben Programmer Tuesday, January 28, 2020 1:41 PM
    Monday, January 27, 2020 8:26 PM

All replies

  • It's actually subtly different than that.

    Every time you create a non-primitive type, you get back a new instance of a type which may be structurally identical to another type but is not the same instance as it.

    Note that a record type is equal to itself:

    M> let t = type [A=any] in t = t
    true

    Tuesday, January 21, 2020 11:03 PM
  • Ah! Very helpful! Subtly but significantly different. :-) Thank you for the clarification.

    A type value is equal to itself, but may or may not be equal to another type value. If two type values are considered equal, then they will behave identically when queried for conformance.
    (from the specification's section 6.6)

    When the specification says the above, is it in essence implying the following?

    When a type value is requested, it is an internal implementation detail as to whether an existing instance of that value will be returned or a new instance will be created.

    If two type values are the same instance, they will equal (=) because they are one and the same. If two type values are not the same instance, they will not equal—even though they may both describe the exact same type (structurally speaking)—because type equivalence is not defined in M (section 5.9).

    Since there’s no guarantee that the two conceptually identical type values will be the same instance, there’s no guarantee that applying the equality operator between the two will return true.

    Exception: Any request for a given nullable primitive type will always return the same instance each time, so equality comparisons between nullable primitive types work.

    If the above is correct, then it seems like:

    • A generalized version of your example is guaranteed to always work for any type because it compares the same instance to itself:
      l
      et t = type {any type} in t = t
    • While the following is only guaranteed to work for nullable primitive types (it may or may not work for other types):
      let GetType = () => type {any types} in   GetType() = GetType()

    Is this right or are there other subtle but significant differences? :-)

    Thanks,
    Ben

    Thursday, January 23, 2020 2:57 PM
  • Both primitive types and nullable primitive types are always equal to themselves. This includes the primitive types "type record", "type table" and "type list".
    • Marked as answer by Ben Programmer Tuesday, January 28, 2020 1:41 PM
    Monday, January 27, 2020 8:26 PM
  • Thank you, Curt!
    Tuesday, January 28, 2020 1:41 PM