Acknowledged

The new ResourceId type for resources in sdk-7 is a breaking change

For example, if you have an Array of string ids, prior to sdk-7 you would have to declare and use it like this:

var strings as Array<Symbol> =
    [Rez.Strings.S1, Rez.Strings.S2] as Array<Symbol>;

var string as String = WatchUi.loadResource(strings[0]) as String;

In other words, the type checker thinks that Rez.Strings.S1 is a Symbol (I've previously submitted a bug showing that it's actually a Number at runtime - but that rarely matters in practice), and loadResource expects to be passed a Symbol.

But in sdk-7.x, Rez.Strings.S1 etc are typed as Lang.ResourceId. This is a new type introduced in sdk-7.x, but the documentation for it incorrectly says it's Api Level 1.0.0. (You can find the docs at  .../Sdks/connectiq-sdk-mac-7.0.2.beta-2024-01-10-acc16aead/doc/Toybox/Lang/ResourceId.html).

So this is another breaking change in sdk-7.x. There's no way to rewrite that Array that works both with sdk-6.x and sdk-7.x.

I'm not sure what can be done about that - except to not introduce a new type. If you want to give it a name, why not just "typedef ResourceId as Symbol;"? And then if it really needs to be a new type (why?) do so at a later date (say sdk-8.x). At least at that point, code could be fixed to work with both 7.x and 8.x. It seems like it should be a goal for Garmin that users can write code that works both with the current sdk, and at least one older one.

Regardless the documentation needs updating to say that it's a ciq-5 feature.

  • But from what I can see, they're still Numbers

    Ok, if I use the new epix2pro47mmsystem7preview, they are in fact ResourceIds. But since they were never Symbols, and nothing ever broke, I don't really see why they needed to be retyped...
  • Once typing is updated, it should be backwards compatible because the compiler transforms any Toybox.Lang.ResourceId to a Toybox.Lang.Symbol when generating code for non-7.0 devices

    But only with a completely different definition of "backward compatibility" that the one I'm using. I mean yes, I assumed that once you moved to the 7.x sdk it would still work with older devices. It didn't occur to me that it might not...

    My point is that once you rewrite your code to be compatible with 7.x, it no longer compiles with 6.x. That's terrible when all you want to do is try out a beta. I literally can't try it without breaking my code for 6.x.

    Once 7.x goes live it's not *so* much of a problem - but I still don't like the idea that I can't (easily) go back to 6.x. And this isn't the only such issue with 7.x.

    I don't expect to always be able to move to the next compiler version without making changes to my code; but I do expect to be able to make those changes in such a way that it doesn't break the old version of the compiler (if I'm careful enough). And that's been the case so far with every previous update. I would have thought there needed to be a really strong reason to do this - but I'm really struggling with what the point is here. In older sdk's Rez.Strings.* are typed as Symbol, but are in fact Number (I've previously filed a bug about that) but it turns out that loadResource is quite happy to be given a Number anyway, so everything works.

    So now you're changing the type checker to think that they're ResourceIds? But from what I can see, they're still Numbers (at least, in the simulator instanceof Number returns true, while instanceof Symbol and instanceof ResourceId returns false for all the devices I tried).

    So why was the change so important that it was worth breaking backwards compatibility?

  • As I'm sure you understand, Toybox.Lang.ResourceId doesn't exist in pre-7.0 SDKs. If you typed resources (Toybox.Lang.Symbol) for pre-7.0 SDKs, the typing will need to be updated. Once typing is updated, it should be backwards compatible because the compiler transforms any Toybox.Lang.ResourceId to a Toybox.Lang.Symbol when generating code for non-7.0 devices