return Null for a Moment

With the new type checking feature.

if I get a function like this :

function parseISODate(date) as Moment {

 ....

}

previsously I was able to do a return Null, it nothing found

no I got a :

Object of type 'Null' does not match return type '$.Toybox.Time.Moment'.

how can i handle/modify that to be good !

thanks

  • TL;DR

    Change

    function parseISODate(date) as Moment {

    to

    function parseISODate(date) as Moment or Null {

    You don't want to "return null for a Moment", you want to tell the type checker that your function returns "Moment or Null", as opposed to (only) "Moment".

    ---

    Details:

    My understanding of your post is that parseISODate() is your function (you control the signature and the implementation), and you want to be able to return either a Moment or null from that function.

    To do so, change the function signature from

    function parseISODate(date) as Moment {

    to

    function parseISODate(date) as Moment or Null {

    The bolded parts above (as Moment / as Moment or Null) signify the declared return type of the function. When type checking is enabled, the declared return type (if specified) needs to match the actual return type. This allows the type checker to catch type errors relating to the usage of the function.

    The other alternative, which would be to cast a returned null value to Moment (e.g. "return null as Moment"), is *not* recommended, because it would defeat the purpose of type checking in the first place (by giving the type checker incorrect information about the return type of the function.)

    Consider the following incorrect code:

    // function is declared to return Moment
    function parseISODate(date) as Moment {

      // ...
      return null as Moment; // this is a bad cast! null is not a Moment
    }

    function foo() {
      var moment = parseISODate("blablabla");
      System.println(moment.value()); // this line may crash at runtime because moment can be null
    }

    In this case, the type checker assumes that the return value of parseISODate is a Moment (and not null), and no warning/error is emitted for System.println(moment.value());

    Now consider this code, which is arguably more correct:


    // function is declared to return Moment or Null
    function parseISODate(date) as Moment or Null {

      // ...
      return null; // no bad cast necessary since the function is declared to possibly return Null
    }

    function foo() {
      var moment = parseISODate("blablabla");
      System.println(moment.value()); // this line may crash at runtime because moment can be null
    }

    Here the return type of parseISODate() is correctly declared as Moment or Null. Now the compiler will emit a warning for the line containing System.println(moment.value());

    Cannot find symbol ':value' on type 'Null'.

    This warning can be handled (and more importantly, the runtime error will be avoided) by adding a null check:

    function foo() {
      var moment = parseISODate("blablabla");
      if (moment != null) {
     
      System.println(moment.value());
      }

    }

    In most cases, when the compiler is complaining about a type error for the return value of a function, the correct course of action is to fix the declared return type. In this case, change "function parseISODate(date) as Moment" to "function parseISODate(date) as Moment or Null"

    In general, a type cast should be the option of last resort. An example of a type cast is "return null as Moment". The reason type casts are bad/dangerous is because they essentially lie to the type checker and defeat the purpose of type checking in the first place. This is why I think it's a huge mistake for Monkey C to use the "as" keyword for both type declarations and type casts. (I don't know of any other language that does something similar. Usually there's different syntax for type declarations and type casts.)

    Unfortunately, there may still be some situations in Monkey C which require type casts (when type checking is enabled at a certain level), although this is not one of them.

  • great and details, thanks