Question re constants and enums

I have a couple of enums that I want to use in combination with typechecking because it saves me code for checking valid options. However, when I try to use enums which share some constants I'm running into dead ends:

  • You cannot have the same key in different enums: Redefinition of 'FOO' in '$'. Previous definition at ...
  • You cannot assign enums to consts (see code snippet below) with type checking on gradual (1): Attempting to initialize enum constant 'FooFOO' of enum 'EnumFoo' with an expression.


const FOO = 0;
const BAR = 1;
const BAZ = 2;

// This is not allowed: Duplicate declaration of symbol 'FOO' in module 'globals'.
enum EnumFoo {
  FOO, 
  BAR,
  BAZ,
}

// Working around it:
enum EnumFoo {
  FooFOO = FOO,
  FooBAR = BAR,
  FooBAZ = BAZ,
}

How do people solve this?

Top Replies

All Replies

  • I want to use a constant, because the values of the enum are also constants

  • The problem that I'm facing is that I have a collection of constants that are also individual members of enums. Enums in monkeyC don't seem to be able to intersect, allow expansion and mixing and matching. I can't use the typechecking because the typechecking is actually breaking the easy implementation. Unless I'm writing a helper script that generates the enums and makes sure I'm keeping them unique.

    Instead of enum x { FOO } i need to do enum x { xFOO = 1 }; enum y { yFOO = 1 }

    Which means my code gets more unreadable than helpful.

  • there's a difference between an enum and it's value or ordinal. I'm not sure how you do this in Monkey C, but for sure you understand this, because you wrote that you want a solution with type checking Slight smile So probably you need something like:
    enum Bar {
        BarFOO = Foo.value() or Foo.id()... whatever Monkey C makes possible.
    }

  • I really liked this idea, but the error remains the same. Since the constant is a symbol of some sort it has toNumber() and toString() methods btw.

    I'm going to abort the idea. I found out while testing that if you do this with typechecking that the constant isn't used and you need to cast it to the type, eg

    function foo(foo as enumFoo) {
      // code here
    }
    
    // elsewhere
    
    xxx.foo(FOO as enumFoo);
    
    // If I just use xFoo
    xxx.foo(xFOO);

    I didn't want to have several types that are essentially the same, but it seems it is not possible with MonkeyC.

  • Hi ,

    Are you using the new Beta SDK? If you are not, I think you are running into a type checking limitation that was unfortunately in place when type checking was first introduced to the Monkey C compiler. That limitation should have been removed from the Beta.

    Marianne

  • No, I'm not using the beta. I gave it a spin, now it fails because I use me.xxx inside a class function, and not self.xxxz

    ERROR: fenix6xpro: Could not validate optimized Monkey C IR.
    ERROR: fenix6xpro: xxxx:62,8: Optimization validation failure: Cannot find register value '%me'

    and that should work according to developer.garmin.com/.../

    But it does not complain about using a const in an enum anymore. I think, it now complains about a whole range of other things:

    Cannot perform operation 'instanceof' on type 'Any'.

    I can't use the 4.1.4 beta, because it just breaks everything I'm doing on gradual.

    I have t.is(needle, haystack, msg), which does needle instanceof Double which now breaks where it previously didn't.

     ^^

    You can get the code at gitlab.com/.../opn-monkeyc

  • Are you using the new Beta SDK? If you are not, I think you are running into a type checking limitation that was unfortunately in place when type checking was first introduced to the Monkey C compiler. That limitation should have been removed from the Beta.

    I saw that the beta no longer has the constant (and non-expression) type check for enums.

    But it also allows you assign anything at all to an enum, such as a float, string, or Time.Moment object. I guess it's not a big deal since this was always allowed, but technically (according to dev docs), enums are supposed to be integers. (Enum members which are abused like this do have the correct type -- which is to say the type of their value and not Number -- so I guess it's all good.)

    function now() {
       return Time.now();
    }

    class TestView extends WatchUi.SimpleDataField {

       enum EnumFoo {
          FooFOO = 42 * 1.55,
          FooBAR = "forty two",
          FooBAZ = now(),
       }
    //...

    }

    No, I'm not using the beta. I gave it a spin, now it fails because I use me.xxx inside a class function, and not self.xxxz

    Someone opened a bug for this. Here's the link if you want to vote on it.