Skip to content

Add a Conditional Access Operator (Null Conditional Operator) #146

Open
@kindlich

Description

@kindlich

In order to make working with optional types easier without losing the information that we are using optionals, we want to introduce a Conditional Access Operator.

Null conditional operator: (x?.field or x?.method(...))

  • Used to call a method or load a field on an optional value
  • Can be used only on optional values (T?), usage on other types is an error
  • Always returns an optional - null if the value if null, the result of the method call / field otherwise
  • If the resulting value is optional, it is flattened - there are no doubly optionals
  • Not supported for operators, including [ ] and ( )
  • No short-circuit, if the operand before the ?. is null, any chained calls are stil evaluated.
    • a?.getB().c would error unless B? had a member c
  • Uses the members from the base-type (T if invoked on T?)

Acceptance Criteria:

  • Decide: Should this be usable on member-get and member-set operator => Requires: Member getter / setter in zc #144 ; If that issue has been completed by then, implement if we decide we want this, otherwise create new issue to track that implementation.
  • Test Cases:
    • Simple test case with null- and non-null-value

    • ?. flattens optional return type

    • "Collision:" Member exists on both Nullable-type and on base-type, which one does the null-safe operator use?

      public expand string? { public const get internalized as string => this == null ? "NULL" : this.toUpperCase(); }
      public expand string  { public const get internalized as string => this; }
      
      var x as string? = null;
      println(x?.internalized); // null
      println(x.internalized); // "NULL"
      
      var y as string? = "Hello";
      println(y?.internalized); // "Hello"
      println(y.internalized); // "HELLO"
      
    • Properly converts back and forth between null and -1 for null as usize

    • If decision on member-get and member-set operator: Tests for that

    • Fails for non-optional type

    • Operator cannot be overridden in a custom type

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions