Why would drawPoint(x,y) give "Invalid Value"?

drawPoint(x,y) in the code below is infrequently giving error "Error: Invalid Value
Details: 'Failed invoking <symbol>'".
Any thoughts as to why?
This isn't happening very often - in fact, only once so far, on a real device.
The only thought I've had so far is perhaps x or y was NaN or Inf somehow.  I supposed A or B could possibly by NaN or Inf (shouldn't be, but could) and if so, that would descend to x & y.
Any thoughts welcome!
CODE -------------------------------------------


//type = :low or :high; swidth & sheight are the screen width & height of myDc
// xc, yc are the center points of myDc
drawFuzzyEllipse (myDc, swidth, sheight, xc, yc, A, B, type) {


      if (A> swidth && B > sheight) { return; }

      var step =  A/2.0;  

      var start = 0;

      if (type == :low) {
step = (Math.rand()%150)/100.0 + 0.5;
start = (Math.rand()%314).toFloat();
}

      if (step<25 && A > 3  && type == :high) { step = 25; }

      for (var theta = start; theta < 2 * Math.PI;theta += Math.PI * 2.0 / step) {

         var adder = 0;
         if (type == :low) {adder = Math.rand()%1000/1000.0 * Math.PI * 2;

         var ran = Math.rand()%1000;
         var addme = 0.95f + ran/10000000.0f;

         var x = xc + (A*addme) * Math.cos(theta);
         var y = yc + (B*addme) * Math.sin(theta);

       

CODE -------------------------------------------
  • I'm not sure what you are saying here.

    You give two examples of testing flatOrb for null.

    - the first example is in your words a non-strict check ("if you don't check it strictly"). I would word this as an implicit conversion to boolean, as opposed to an explicit comparison with null. And you say "it only works if you don't check it strictly", implying that the first example works.

    - the second example is an explicit (inequality) comparison with null. You say that "it is happier" (which I assume also means that the second example works.)

    The only thing I can glean from this is that you either have a typo or both examples work.

    I think you meant to say "it doesn't work if you don't check it strictly"

    Indeed:

    My 2 cents:

    - actually the real problem here is that monkey types thinks it's wrong to try to implicitly convert a nullable variable to a boolean, as per the warning, even though this should work at runtime. It warns you about this implicit conversion and it refuses to do the conversion itself. This might be worth filing a bug report

    - previously you implied it was impossible to use null checks with strict type checking due to the above scenario: "The idea that a variable could be null breaks about everything in type checking." I assume this was before you discovered that an explicit comparison with null actually works

    I should note there are actually cases where trying to use null in place of a boolean will cause a runtime error as well.

    e.g.

    My point here is that it may be better in most cases to do explicit comparison with null.

  • If I use Gradual typing, both examples will compile and work. If I use Strict typing then the first will not compile but the second does.

    The problem with using a global public variable for classes is it is a catch-22. As a path means using the variable like:

    myClass.myfunction(myParam1); as opposed to the fully qualified name which just makes code use more bytes.

  • If I use Gradual typing, both examples will compile and work. If I use Strict typing then the first will not compile but the second does.

    Yeah I think it's a bug and should be reported (see above).

    The problem with using a global public variable for classes is it is a catch-22. As a path means using the variable like:

    myClass.myfunction(myParam1); as opposed to the fully qualified name which just makes code use more bytes.

    By fully qualified name do you mean "$.myClass.myFunction(myParam1)"?

    If this works when "myClass.myFunction(myParam1)" fails (due to the fact that myClass is nullable), that would only tell me that the type checker has another bug (it's not checking types for variables prefixed with "$.").

    it is a catch-22.

    Again it is only a catch-22 because you are asking for something which is not supported and is not a good idea: for variables in monkey c to be uninitialized and for the type checker to be totally cool with that (i.e. I guess it should just not check the type at all if it thinks the variable is uninitialized? not sure how that would even work, since it's a compile time type checker, and the variable is going to be initialized / first assigned at some indeterminate point at runtime.)

    Again, if myClass is defined as TestClass (and not null), and myClass is allowed to be uninitialized (with no implicit default value), what should the type (and value) of myClass be before it's initialized to an instance of TestClass?

    You have not answered that question.

  • If I use Gradual typing, both examples will compile and work. If I use Strict typing then the first will not compile but the second does.

    Yeah I think it's a bug and should be reported (see above).

    The problem with using a global public variable for classes is it is a catch-22. As a path means using the variable like:

    myClass.myfunction(myParam1); as opposed to the fully qualified name which just makes code use more bytes.

    By fully qualified name do you mean "$.myClass.myFunction(myParam1)"?

    If this works when "myClass.myFunction(myParam1)" fails (due to the fact that myClass is nullable), that would only tell me that the type checker has another bug (it's not checking types for variables prefixed with "$.").

    Look, you're the one who first started with a statement about global variables and suddenly switched to talking about member variables. It's not like I suggested using either of those things.

    You are constantly moving the goal posts in this discussion. First something doesn't work with global variables, but then all of a sudden we're talking about member variables.

    First something is implied to be impossible, then it turns out it doesn't work when you use certain syntax (implicit conversion to boolean) but it does work with different syntax (explicit comparison with null).

    it is a catch-22.

    Again it is only a catch-22 because you are asking for something which is not supported and is not a good idea: for variables in monkey c to be uninitialized and for the type checker to be totally cool with that (i.e. I guess it should just not check the type at all if it thinks the variable is uninitialized? not sure how that would even work, since it's a compile time type checker, and the variable is going to be initialized / first assigned at some indeterminate point at runtime.)

    Again, if myClass is defined as TestClass (and not null), and myClass is allowed to be uninitialized (with no implicit default value), what should the type (and value) of myClass be before it's initialized to an instance of TestClass?

    You have not answered that question.

  • I think we're getting into the weeds when we should be trying to help OP with their problem.

  • Thanks - I put in some checks for NaN & Inf that I found in the forums, but that didn't help.  (Tried to post about this earlier but the forum is malfunctioning or whatever, it never showed up.)

    Anyway I finally cracked it today - it was exactly that division: 2.0/step.  Every once in a blue moon step == 0 and you're dividing by zero.

    I should have thought to check for that the second I wrote the / sign, just overlooked it.  It is just funny that no error shows up until many lines later, when to my eye a bunch of those other things should throw an error if step =0 (and thus theta is Inf, how is the loop even working or incrementing, and so on down the line).

    Tl;dr: Don't divide by zero, just like they taught you in 3rd grade.

  • > forums.garmin.com/.../meta-forum-returning-lots-of-errors-today-e-g-parens-links-and-images-cause-problems

    Aha, thank you, I couldn't crack the code...

  • > [https://forums.garmin.com/developer/connect-iq/f/discussion/338071/testing-for-nan/1637853#1637853]

    Aha, I will try that.  I was using the code below, and obvs it was not catching the situation where x = y/0 - though you would think it should!

    const FLT_MAX = 3.4028235e38f;

    function isnan(x as Float) as Boolean {

        return x != x;

    }

    function isinf(x as Float) as Boolean {

        return (x < -FLT_MAX || FLT_MAX < x);

    }
  • x = y / 0;

    isinf(x);

    won't work because you'll get the division by zero error in the 1st line, you'll never get to the 2nd line.

    You'll have to check for the divisor not to be null or 0 before you try to divide by it.