Skip to content

Extra Reference Type Checks (prettierMonkeyC.extraReferenceTypeChecks)

markw65 edited this page Nov 24, 2024 · 1 revision

In MonkeyC, Arrays and Dictionaries are passed by reference, meaning that the callee can modify their values. Garmin's type checker treats tuples as inferred types - modification to the elements of a tuple will update its type. So Garmin's type checker allows code like:

function unsafe(t as [Number]) as [String, Boolean] {
  // allowed, and changes t's type from [Number] to [String]
  t[0] = t[0].toString();
  // allowed, and changes t's type from [String] to [String, Boolean]
  t.add(false);
  // ok
  return t;
}

But that's not safe because you could have:

var myTuple as [Number] = [42];

function useMyTuple() as Number {
  unsafe(myTuple);
  return myTuple[0];
}

This code passes Garmin's type checker at the strictest level, but ends up returning a String from a function that's supposed to return a Number.

Similarly, Garmin's type checker will allow a tuple to be passed to a function expecting an Array (provided the array is typed such that it can hold all the elements of the tuple), or an Array of a narrower type to be passed to an Array of a wider type. Again, this isn't safe:

function unsafeArray(arr as Array<String or Number or Boolean>) as Void {
  arr[0] = false;
  arr.add("Hello");
}

Passing a tuple to this is always unsafe, because its length will be changed. Passing a tuple of Strings would be unsafe, even without the add, because it would end up with a Boolean element. Passing an Array<Number> is unsafe because it will end up holding both a Boolean and a String; but Garmin's type checker allows all these.

The prettierMonkeyC.extraReferenceTypeChecks option, which is true by default, will cause the pmc type checker to warn about such cases. These warnings are generally worth paying attention to, but if you don't want them, set extraReferenceTypeChecks to false.

Clone this wiki locally