1

I am porting some Java code to Xojo which doesn't have the same language constructs as Java does.

I have a bug in the port and I think I've narrowed it down to this bit of Java code:

int maxIndex = 0;
int n = vertices.length; // vertices is an array
double max = dot(vertices[0]), candidateMax; // I'm assuming `candidateMax` is being initialised to 0 here.

if (max < (candidateMax = vector.dot(vertices[1]))) {
  // Search to the right
  do {
    max = candidateMax;
      maxIndex++;
  } while ((maxIndex + 1) < n && max < (candidateMax = vector.dot(vertices[maxIndex + 1])));

} else if ( max < (candidateMax = vector.dot(vertices[n - 1])) ) {
  maxIndex = n;
  // Search to the left
  do {
    max = candidateMax;
     maxIndex--;
  } while (maxIndex > 0 && max <= (candidateMax = vector.dot(vertices[maxIndex - 1])));
}
return maxIndex;

I've ported it to this code (Xojo - more verbose than the code above):

Var maxIndex As Integer = 0
Var n As Integer = Vertices.Count
Var max As Double = vector.Dot(Vertices(0))
Var candidateMax As Double

candidateMax = vector.Dot(Vertices(1))
If max < candidateMax Then
  // Search to the right.
  Do
    max = candidateMax
    maxIndex = maxIndex + 1

    // Exit?
    If maxIndex + 1 >= n Then
      Exit
    Else
      candidateMax = vector.Dot(Vertices(maxIndex + 1))
      If max > candidateMax Then Exit
    End If
  Loop
Else
  candidateMax = vector.Dot(Vertices(n - 1))
  If max < candidateMax Then
    maxIndex = n

    // Search to the left.
    Do
      max = candidateMax
      maxIndex = maxIndex - 1

      // Exit?
      If maxIndex <= 0 Then
        Exit
      Else
        candidateMax = vector.Dot(Vertices(maxIndex - 1))
        If max > candidateMax Then Exit
      End If
    Loop
  End If
End If

Return maxIndex

I'm assuming the while loop conditional:

if (max < (candidateMax = vector.dot(this.vertices[1]))) {
  // Search to the right
  do {
    max = candidateMax;
      maxIndex++;
  } while ((maxIndex + 1) < n && max < (candidateMax = vector.dot(vertices[maxIndex + 1])));

translates as: "Do the contents of the loop at least once. After each iteration of the loop, check to see if maxIndex + 1 is less than n. If it's not then exit the loop. If maxIndex + 1 is greater than n then assign the result of the vector.dot method to candidateMax and check to see if max is less than candidateMax. If it is then keep iterating".

Is this correct? I think I'm misinterpreting the order that the while conditional is being evaluated.

Garry Pettet
  • 8,096
  • 22
  • 65
  • 103
  • *"I'm assuming `candidateMax` is being initialised to 0 here."* You're assuming wrong. `candidateMax` is unassigned. It will however be definitely-assigned in the next line of code. – Andreas Feb 02 '20 at 19:05
  • 1
    *"Is this correct?"* Yes, except the opposite of `max < candidateMax` is `max >= candidateMax` in the first loop. Looks like a copy/paste error, or you simply missing that first loop uses `max <`, while second loop uses `max <= `. – Andreas Feb 02 '20 at 19:11
  • Thank you so much Andreas! You're right, I overlooked the difference between `max <` in the first loop and `max <=` in the second loop. Tired eyes :) – Garry Pettet Feb 02 '20 at 19:17
  • A while loop is only executed if the condition is true. If the condition is false, it will never execute. – NomadMaker Feb 02 '20 at 19:22
  • 1
    @NomadMaker True for a `while (...) { ... }` loop, but not true for a `do { ... } while (...)` loop, which executes the body once before checking the condition. – Andreas Feb 03 '20 at 02:25
  • Correct. I didn't read it closely enough. – NomadMaker Feb 03 '20 at 02:43

1 Answers1

2

I believe you got the loop exit condition wrong.

Original:

while (maxIndex > 0 && max <= (candidateMax = vector.dot(vertices[maxIndex - 1])))

would mean in Xojo, roughly:

  ...
  if maxIndex > 0 then candidateMax = vector.Dot(Vertices(maxIndex - 1))
while (maxIndex > 0) and (max <= candidateMax)

In general, you can translate Java/C's do ... while (b) into Xojo's do ... loop until not (b).

This would mean, in your case:

  ...
  if maxIndex > 0 then candidateMax = vector.Dot(Vertices(maxIndex - 1))
loop until not ( (maxIndex > 0) and (max <= candidateMax) )
Thomas Tempelmann
  • 11,045
  • 8
  • 74
  • 149
  • Thanks for the tip about translating to `do...lop until not`. Very helpful. The only slight issue with this particular loop condition is that a variable (`candidateMax`) is being assigned to within the condition, something that isn't (at least I don't think it is) possible in Xojo. – Garry Pettet Feb 02 '20 at 20:26
  • 1
    I want to up-vote for the `do ... loop until not (...)`, but at the same time I want to down-vote for the rest of it. The Java code is `do { ... } while (maxIndex > 0 && max <= candidateMax)`, which is the same as `while (true) { ...; if (maxIndex <= 0 || max > candidateMax) { break; } }`, and that is exactly what the code in the question has for the Xojo version. Before that you say *"But you turned it into"*, as-if that is wrong, but it is the correct code. Your *"would mean in Xojo"* code is wrong, and your `loop until not ( (maxIndex > 0) or (max <= candidateMax) )` is wrong. – Andreas Feb 03 '20 at 02:36