Search code examples
compiler-errorsforward-declarationnim-lang

Declare procedures prototypes in nim


I am trying understand how I can declare, in a nim source, different procedures that call each other, as it sounds like the compiler expects all calls to come after the declaration, but the procedures can't be all at the top, so whichever is lower in the source code will be unknown to the compiler and an error is thrown.

I don't want to write object oriented code, at this stage, as I have very little experience in programming.

The following is an example:

proc mydouble(num: int): int =
  echo "Warning, someone is trying to double a number, which is forbidden by law!"
  echo "I will allow it for now, but I filed it under the capital crimes register."
  return mymultiply(num, 2)

proc mysum(firstnum, secondnum: int): int =
  if firstnum==secondnum:
    return mydouble(firstnum)
  else:
    return firstnum + secondnum

proc mymultiply(firstnum, secondnum: int): int =
  if firstnum == 2:
    return mydouble(secondnum)
  elif secondnum == 2:
    return mydouble(firstnum)
  else:
    var res=0
    for x in 1..secondnum:
      res=mysum(res,firstnum)
    return res

var a,b,c: int
a = 3
b = 2
c = -1

c=mydouble(a)
echo c # expecting 6, with a warning about crime.
c=mysum(a,b)
echo c # expecting 5
c=mysum(a-1,b)
echo c # expecting 4, with a warning about crime.
c=mymultiply(a,a)
echo c # expecting 9
c=mymultiply(a,b)
echo c # expecting 6, with a warning about crime.

The result is:

./test.nim(5, 10) Error: undeclared identifier: 'mymultiply' candidates (edit distance, scope distance); see '--spellSuggest': (7, 1): 'result' (7, 2): 'mydouble' (7, 4): 'countup'

If I put mymultiply above mydouble, I get:

./test.nim(4, 12) Error: undeclared identifier: 'mydouble' candidates (edit distance, scope distance); see '--spellSuggest': (2, 5): 'cdouble'

Is there a way to warn the compiler that the missing code is a few rows below (for example, with prototype declarations or forward declarations)? I can't find anywhere a way to do that in nim. How do I do it?

All my searches resulted in the same few websites that only bring some reference material (no real life explanations) or forum questions with many specific details that make it irrelevant and too complicated (I am not a programmer, I got only very basic experience using simpler languages for a couple of programs and this is my first code in nim). For example, there is a post about assigning a function pointer in a Window Procedure and it didn't help, in my case.


Solution

  • You can forward-declare procedures for this!

    Here a minimal example to demonstrate:

    proc procOne(x: string)
    
    proc procTwo(y: string) =
      echo "Defined before one!"
      procOne(y)
      
    proc procOne(x: string) =
      echo "Defined after two!"
      echo x
    
    procTwo("Last!")
    

    There is also a section on nim's official tutorial about this.