Is SDK 7.1.0 an April's fool joke?

I saw that SDK 7.1.0 was released (typical to Garmin it's called 7.1.0-RC2-2024-02-14 inside..., though probably it should be called 7.1.0-RC3-2024-04-01)

So I tried it again. This of course means changing all my apps one by one with changes that make them incompatible with SDK 6.4.2. This could be "OK", but nothing works in 7.1.0! I see that none of the things reported by multiple people about 7.x were fixed... 

  • Yeah, but that's not backward compatibility, that's forward compatibility :) 

    If you create a new project with 7 then it's OK that it needs sdk7. The problem is that people have hundreds of old projects that work for years. I would say that even that is not very bad if I have to change them a little bit to make them compatible with both 6 and 7 (though I guess others would say even that's not acceptable). The problem is that it's impossible it's XOR. Either works in 6 or in 7 but can't work in both. And to make it even worse it's not that there's some change in some niche part of the sdk that is used by 3% of the apps. 2 things are used in 100% of the apps: getInitialView() and resources.

  • The simulator is still broken on MacOS in terms of retrieving a GNSS location, as per my bug report: forums.garmin.com/.../simulator-bug-no-gnss-gps-position-returned-on-activity-app-type-when-using-macos

  • **************************************
    WITH SDK 7.1.0:

        
    // from SDK 7
        //! Return the initial view of your application here
        function getInitialView() as [Views] or [Views, InputDelegates] {
            view = new EdgeAllinOne1View(_sensor);                    
            return [ view, new InputDelegate(view) ];    
        }
    This code works fine with 7.1.0.

    But built with SDK 6.4.2 - following error is thrown:
    ERROR: edge1040: C:\Garmin_IQ_Projekte\Edge1_Ebike_Beta\source\EdgeAllinOne1App.mc:54,30: no viable alternative at input 'as['

    *************************************

    Concerning backwards compatibility I did the following test - and it's really shocking:

    With actual SDK 7.1.0:
    create a new project via VSCode and Ctr+P:
    A complex datafield.
    Did nothing more!
    Build with 7.1.0 - no problem.

    Then changed to SDK 6.4.2 and tried to build this "official" datafield -> shocking!
    ERROR: edge1040: C:\Garmin_IQ_Projekte\TEST\source\TESTApp.mc:20,30: no viable alternative at input 'as['
    Even with Type Check completely disabled!

    Not to state the obvious but:

    - those are two examples of the exact same thing

    - As flocsy pointed out, being able to build an SDK 7 project with SDK 6 would be an example of forwards compatibility, not backwards compatibility

    - as [array element type] is obviously completely new syntax for 7.x, so it's not surprising that it would fail to compile in 6.x or earlier. If you're interested in the details, "no viable input at..." is an error message that comes from the ANTLR syntax parser. Syntax parsing is the first step that has to happen before anything else, in order to convert the source text to an AST (abstract syntax tree) that the type checker/compiler can actually use, so it's not shocking that it would fail build regardless of whether type checking is enabled or not

    So the reason SDK 7 projects won't build with SDK 6 (in your example) is because of new syntax.

    The reason SDK 6 projects won't build with SDK 7 (in your example) is because the return type of getInitialView() has changed - it's no longer valid to return null, and therefore the ? in the return type in the SDK 6 project is invalid.

    I get that it's annoying, but it's understandable.

  • Ok, thanks for your input!

  • Yeah, I know it wasn't very helpful :/. But it seems that the change to return type of getInitialView() is a bug fix that was made in v7.0.0.beta1:

    • Update API typing to prevent null being returned from getInitialView().

    Unfortunately this is the kind of bug fix that would break older code in newer SDKs and newer code in older SDKs, regardless of the new syntax (I think).

    It would be nice if type checking could be disabled just for one line/symbol to get around this problem, but it seems that it's only possible to disable type checking for the glance or background view. (Somebody correct me if I'm mistaken.)

    [https://developer.garmin.com/connect-iq/monkey-c/monkey-types/#applicationscopetypechecking]

    Maybe the ability to disable type checking altogether for a single annotated symbol would be a good feature request. That way if there's a need for code to compile with old and new SDKs, problem code like you mentioned could use this annotation.

  • (:typecheck(false))
    but I don't think the null is the big problem here. Removing the Null is a good step and I don't think any app ever really returned null anyway. The problem is that this doesn't work:
        (:sdk6)
        function getInitialView() as Array<Views or InputDelegates>? {
            return [ view, delegate ] as Array<Views or InputDelegates>;
        }
        (:sdk7)
        function getInitialView() as [Views] or [Views, InputDelegates] {
            return [ view, delegate ] as [Views, InputDelegates];
        }
    
    Because sdk6 so much has no idea about this new format that it even fails the syntax checker.
  • I'm already using it, and it's ok

  • is your name jim_3480363? Slight smile

  • Because sdk6 so much has no idea about this new format that it even fails the syntax checker.

    Yeah I mentioned that except it's more than a syntax checker, it's a syntax parser (mostly likely ANTLR), meaning that SDKs earlier than SDK 7 can't even *understand* the new syntax. (And how would they, it's new)

    (:typecheck(false))

    Haha I figured it might be something like that in the back of my mind but I wasn't sure. I wanted to find official guidance on developer.garmin.com but all it said was the :typecheck annotation exists and it had examples of disabling type checking for background and glance views.

    Like seriously, what kind of documentation is this:

    https://developer.garmin.com/connect-iq/monkey-c/annotations/

    We're supposed to guess, ask/search the forums, or scour the release notes?

    but I don't think the null is the big problem here.

    It's a problem though, if you're going to attempt to work around it by providing two versions of your code. To be fair, it doesn't seem possible to express the new type ([Views] or [Views, InputDelegates]) in terms of the old syntax (Array<...>).

    It's a moot point since the types are different anyway (meaning that even if you express the new type in terms of the old syntax, it wouldn't help).

    But that doesn't mean you can't use the old syntax with SDK 7 and disable the type check (see below).

    The problem is that this doesn't work

    Sorry, as usual I wasn't explicit enough with my suggested solution. The idea is you use the function signature for getInitialView() that works with *old* SDKs (so it has both the old type syntax and the old type signature), and you disable type checking for that symbol so the new SDK doesn't throw an error even if you have strict type checking enabled.

        // this builds in 7.1.0 and 6.4.2 with typecheck = 3 / strict
        (:typecheck(false))
        function getInitialView() as Array<Views or InputDelegates>? {
            // ...
        }

    Yeah I know it's kind of a cop out to say "just disable typechecking!!!" but personally I would be ok with it for 1 or 2 standard functions where we're pretty sure it's going to be harmless.

  • NAHHHH!

    I thought I'll give it another try. But I get 30 errors from code that is generated by the compiler itself...

    ERROR: fr955: MyApp/bin/gen/006-B4024-00/source/Rez.mcgen:16,16: Invalid '$.Toybox.Lang.Dictionary{:title as $.Toybox.Lang.Symbol}' passed as parameter 1 of type 'PolyType<Null or $.Toybox.Lang.Dictionary{:icon as $.Toybox.Graphics.BitmapType or $.Toybox.Lang.ResourceId or $.Toybox.WatchUi.Drawable, :title as $.Toybox.Lang.ResourceId or $.Toybox.Lang.String or $.Toybox.WatchUi.Drawable, :theme as Null or $.Toybox.WatchUi.MenuTheme, :focus as $.Toybox.Lang.Number}>'.

    This is the generated code:
    Menu2.initialize({:title=>$.Rez.Strings.settings_title});