• Nim

Filed under:

Nim is a statically typed compiled systems programming language. It combines successful concepts from mature languages like Python, Ada and Modula.

Troubleshooting

readLine

Using an iterator with an openFile will mutate the file; That is, to run for l in inputFile.lines and read 3 lines, then process something else, then read another 6 lines, the iterator will pick up where it left off.

handleFrontMatter(inputF) # reads everything between two sets of `---` lines.

for line in inputF.lines:
  let t = determineLineType(line.string)

  case t:
    of "empty":
      outputF.writeLine(line)
    of "heading":
      outputF.writeLine(line)
    else:
      outputF.writeLine(wrapWords(line, maxLineWidth=80, splitLongWords=true))

expression is of type 'N' and has to be discarded

From what I can tell... if you are declaring a proc without actually storing it's results you may get an error noting that return values have to be discarded.

proc determineLineType(line: string): string =
  if line.len == 0:
    "empty"
  elif line[0] == '#':
    "heading"
  else:
    "unknown"

# without this line , we run into the discard error. let t =
# determineLineType(line)

From the docs:

To call a procedure that returns a value just for its side effects and ignoring its return value, a discard statement must be used. Nim does not allow silently throwing away a return value:

discard yes("May I ask a pointless question?")

The return value can be ignored implicitly if the called proc/iterator has been declared with the discardable pragma:

proc p(x, y: int): int {.discardable.} = return x + y
 
p(3, 4) # now valid

Variable parameters

I started running into this issue while trying to sort a list:

func sort[T](a: var openArray[T]; cmp: proc (x, y: T): int {.closure.}; order = SortOrder.Ascending)

What's happening? Turns out sort mutates a list in place. So it requires that the parameter is set to be a variable.

proc exA(i: int) =
  i = 0                 # Doesn't compile

proc exB(i: var int) =
  i = 0                 # Compiles

proc exC(i: ref MyRefObject) =
  i.myProp = 0          # Compiles
  i = new MyRefObject() # Doesn't compile

proc exD(i: var ref MyRefObject) =
  i.myProp = 0          # Compiles
  i = new MyRefObject() # compiles

Edit: this cleared it up for me - sort modifies a list in place. sorted does not and thus does not need to be passed as a var.

Miscellaneous notes