nim-lang/Nim

Make forward declaration unnecessary

simonkrauter opened this issue · 5 comments

I think the forward declaration for procs and methods should not be required in any case.
Working with Nim would be more convenient and less error-prone.

Example:

type T1 = ref object of RootObj
type T2 = ref object of T1
type T3 = ref object of T2

method m(self: T1) =
  echo "T1"

# method m(obj: T2) # forward declaration
  
method m(obj: T3) =
  procCall obj.T2.m()
  echo "T3"

method m(obj: T2) =
  procCall obj.T1.m()
  echo "T2"
  
var obj = T3()
obj.m()

In this example, a missing forward declaration leads to different/wrong program logic.
It still compiles fine, but the program result is not, what the programmer expect.
Would be nice, if this does the same with and without the forward declaration.

I think the problem is in procCall to allow the cast from T2 to T1. When the programmer already wrote an explicit conversion to T2 and procCall I doubt that implicit casting should be applied. But I can be wrong here, becaues I barely use procCall.

If this should be implemented, this should be concidered:

import macros

static:
  var str = "unmodified"

macro getStrValue(): string =
  result = newLit(str)

macro makeProcedure(): untyped =
  str = "modified"
  result = quote do:
    proc foo(): void =
      echo "Hello foo"
    
#foo()              # undeclared here, not possible yet

echo getStrValue()  # unmodified
makeProcedure()
echo getStrValue()  # modified

foo() # ok here

Now that I think about it, there is not really a conflict here, but I still don't like the idea, that the compiler does not work in order. It is a very nice attribute to know that a compiler works in order, especially when working with macros. And macros should have highest priority.

I would like to have this too, since i prefer to write code in top-bottom order (i.e. the main comes first). unfortunately, I don't know any language that combine both features - they either parse all definitions simultaneously (Haskell) or process file sequentially "executing" the definitions.

Although Template Haskell in GHC tries to get best from both worlds - it splits input file into sections divided by new macro definitions, and processes each section as a whole.

Araq commented

@Bulat-Ziganshin Try the new {.reorder: on.} directive as a top level statement.

(For the record, this feature seems now to be renamed to: {.experimental: "codeReordering".}, as documented in the manual.)