compiler-errorsnim-lang

Why is nim expecting type Ordinal instead of Board


nim 1.6.8

To compile: nim c ./myfile.nim

I've tried adding var in front of Board in parameters(but I don't need to modify Board). I've tried adding [Board] after proc name to indicate proc is for Board. I've tried changing result name to something else and returning that. None of these changes, change the error.

Full Error:

Error: type mismatch: got 
<proc (x: openArray[Board]): int{.noSideEffect.}>
but expected one of:
proc inc[T: Ordinal](x: var T; y = 1)
  first type mismatch at position: 1
  required type for x: var T: Ordinal
  but expression 'res' is of type: proc (x: openArray[Board]): int{.noSideEffect.}

Relevant Code

import strutils
import sequtils

const
  Rows = 1000
  Cols = 1000

type
  Row = array[Cols, bool]
  Board = array[Rows, Row]

# another proc, that has no errors
proc toggle(b:var Board, start:tuple, last:tuple) =
  for c in start[0]..last[0]:
    for r in start[1]..last[1]:
      b[c][r] = not b[c][r]

proc onLights(b:Board):int{.noSideEffect.} =
  var result = 0
  for c in low[b] .. high[b]:
    result += low[c].count(true)

var lights:Board
echo lights.onLights() # expect 0

Solution

  • You seem to be confused on what low and high do, they are functions, so you should use () to call them, instead of [] which is used for array indexing. If you would like to loop through the array indices, you should change your code to something like this. Notice I use () when calling low and high to pass in the array that I'm calling them on, and then use [c] to use the index to access elements in the board later.

    proc onLights(b: Board): int {.noSideEffect.} =
      for c in low(b)..high(b):
        result += b[c].count(true)
    

    Alternatively, you can use the equivalent of foreach loops in other languages, to loop through the elements of the array instead:

    proc onLights(b: Board): int {.noSideEffect.} =
      for c in b:
        result += c.count(true)
    

    The reason you get this error is that low[b] uses the other usage of square brackets, which is to specify generic types. low[b] then is the low function, specified to the type Board, which you then make a range out of and try to loop through, which of course doesn't make sense.