Can the compiler warn about real errors that cause runtime exception?

I have an app with minApiLevel="1.2.0". It's used by a few hundred users only, so it's more than likely that none of them uses epix (gen1). I just did that, I "accidentally" ran it in the simulator, and got a runtime exception because use Array.slice that is only since CIQ 1.3.0. So of course this is my bug, but I wonder if it would be possible for the compiler to be a little bit smarter (that me and it's current version) and warn me about this? After all I use strict type check, it warns me about even things I can't fix (and that are not a bug at all), i.e: 

WARNING: epix: MyDF/source/Config.mc:25,8: '$.Toybox.Application.AppBase.setProperty' is deprecated.

So instead of (or at least besides) these useless and annoying warnings, it could do some good and warn me when I compile for a device with lower CIQ level, that I use an api that will probably cause runtime exception. It's really possible in this case, as I just have:

function foo() as Array<Number> {
    // ....
    return arr.slice(0, n);
}

strict type check, no annotation to disable any check, and most importantly no has check, like: if (Array has :slice) ...

I realize it's a bit more complicated, as it'll have to fix existing bugs (like the above about setProperty, which is in the else block of: if(Application has :Properties ) but is this a realistic feature to ask for?

  • I think in both cases, you are asking for the compiler to emit device-specific warnings/errors. This isn't necessarily unreasonable, since there is already a device-specific warning for the launcher icon.

    WARNING: epix: MyDF/source/Config.mc:25,8: '$.Toybox.Application.AppBase.setProperty' is deprecated.

    i.e. in this case, the compiler only cares that setProperty is deprecated in general, and ignores the fact that it's not deprecated for epix.

        return arr.slice(0, n);

    i.e. in the is case, the compiler only cares that slice exists on Array in general, and ignores the fact that it doesn't exist for epix.

    I don't think what you're asking for is impossible, but it's probably not how the compiler and corresponding API info are currently designed. It seems that for the purpose of type checking and deprecation checks, the compiler just uses a single description of the API which is device-agnostic. [Ofc at runtime, the simulator absolutely uses device-specific API information to actually resolve symbols.]

  • After all I use strict type check, it warns me about even things I can't fix (and that are not a bug at all), i.e: 

    WARNING: epix: MyDF/source/Config.mc:25,8: '$.Toybox.Application.AppBase.setProperty' is deprecated.

    How smart do you want it to be here though? Sure, the compiler could get rid of the warning for devices that actually need setProperty. [I've complained about this, too].

    But consider the following code:

    Should the compiler be smart enough to suppress the normal deprecation warning for this code on a newer device like fr965?

    What about this:

    I could write similar examples for Array.slice(). In principle, it doesn't seem 100% possible for the compiler to know whether you're "using the API properly" when it comes to device-specific differences which may be handled at runtime, unless it actually runs your code. [Which is where the simulator comes in.]

  • The Epix1 never worked that great in the sim or on the real device, and not long after it was announced, Garmin had kind of a fire sale on it.  I've not even thought about supporting it in 8-9 years and haven't heard from users asking me to support it.  That's why it's still CIQ 1.2.  Considering things were in bad shape even pre-type checking, I wouldn't hold any hope for it now. You may just want to drop it as a target for your apps, unless you have one you can test with.

  • You totally missed the topic. Maybe it's my fault, as epix is not needed to be in this thread at all. It's not about epix in particular, nor is it about Array.slice in particular. It's a general question, it could be about any method or class that was added at any point (not in CIQ 1.0.0) and actually it's not only about api level and CIQ version, because some methods are there for certain devices but not for others.

  • Yeah, these cases could be maybe possible to be enabled/disabled.

    setProperty is a good example, it already has a warning that annoys some devs. It was added in CIQ 2.4.0, so for a device that has a partNumber that has a max that is less than 2.4.0 I would not want to see this warning at all.

    For a device that has at least 2.4.0 for all partNumbers, but has partNumbers with CIQ < 4.0.0 * I would want to get a warning, so I am reminded that there's a better option, but still I'm not forced to refactor my old projects if so I decide (this is more or less the warning we get now, in case it's a device with 2.4.0+)

    *) I guess Garmin gave up on deprecating setProperty at least for now, as the docs say it might be removed after 4.0 which did not happen even in 5.1.0. My guess is that there are so many old apps still in use that are no longer developed that would become useless and would make users of the old apps on new devices angry (way more than Connect+) that they decided to keep it.

    As for your thought about what the compiler would need to do/know. Yes, it's not simple. There might be some edge cases that are harder to support, but even supporting the most obvious cases would help. Some of the decisions of the compiler are made today at compile time though. has checks are like that, and this could be done as well. Garmin got better at fixing bugs in the device files lately, so this could be done probably.

    For your last example I would say: this is a "hack". There's a better way to check for this (has check) that is documented and better supported. If this was my code and the compiler wouldn't know how to treat it I would be fine with it.

  • Wouldn't you see the runtime error when you actually tested it in the sim? Nothing will replace actual testing...

  • yes, but this one was missed

  • I guess Garmin gave up on deprecating setProperty at least for now, as the docs say it might be removed after 4.0 which did not happen even in 5.1.0. My guess is that there are so many old apps still in use that are no longer developed that would become useless and would make users of the old apps on new devices angry (way more than Connect+) that they decided to keep it.

    Yes even a member of the Connect IQ team posted a comment along the lines of "please stop using these functions because we're trying to deprecate them!", in a bug report about the warning.

    Garmin even reversed the drawAngledText/drawRadialText removal on FR165[M] which caused a minor uproar.

    [These incidents actually do prove that Garmin "cares" about Connect IQ, to a certain extent.]

  • For your last example I would say: this is a "hack". There's a better way to check for this (has check) that is documented and better supported. If this was my code and the compiler wouldn't know how to treat it I would be fine with it.

    Of course this was not meant to be a real example, only a way to show that it's not always straightforward to the compiler to tell whether some code will execute at runtime or not. However do we really want the compiler to behave significantly differently based on how "nice" your code is [disregarding things like declaring types, ofc]? Many people have asked in the forums how to gate functionality by checking the CIQ version at runtime, and I can't say it's *always* wrong, even if I wouldn't do it that way.

    A more realistic example would be a has check for X which is used to gate X and Y. [Here X and Y could be getProperty and setProperty, for example.] Suppose a dev sees a warning about Y and not X - they may feel it's a bug and that they either expected to:

    - see a warning about neither X or Y

    - see a warning about both X or Y

    In other words, if the compiler gains a *little* bit of smarts about catching certain errors that are normally only detected at runtime, will devs insist it should be a *lot* smarter? Sometimes it's better to do nothing than to half-ass certain things.

    Anyway. that's just my hot take. I would be curious to hear how the CIQ team sees it. Would they think what you're asking is reasonable (but currently not supported) or would they think that what you're asking is not possible/feasible/desirable in practice?

  • - see a warning about neither X or Y

    - see a warning about both X or Y

    I think your native language is English, isn't it? Isn't this what you wanted to write:

    - see a warning about neither X nor Y

    - see a warning about both X and Y