Why Assignment Error not caught at Compile Time in Nim?

Viewed 79

The code below produces ObjectAssignmentError, as far as I understand it's because the sequence defined as seq[Doc] and not as seq[TextDoc].

But aren't such errors supposed to be caught at compile time, by compiler and not leak into runtime?

type
  Doc = object of RootObj

  TextDoc* = object of Doc
    title*: string
    text*:  string

  TodoDoc* = object of Doc
    todo*:     string

var all_docs*: seq[Doc] = @[]

all_docs.add TextDoc(title: "", text: "")
1 Answers

The reason this isn't caught at compile time is because it's possible in general to add a TextDoc to an array of Doc, as long as they've been declared sensibly, i.e. heterogenous arrays have to be ref objects or Variants (otherwise they can't all fit in the same space)

to put it another way: inheritance means any procedure that accepts a Doc will also accept a TextDoc, including the procedure proc add(s:var seq[Doc],d:Doc)

Nim supports value semantics, which are important for cache-friendliness, but that freedom can be unsettling to those used to e.g. Java where everything is passed by reference.

with reference semantics the above code runs with no errors:

type
  Doc = ref object of RootObj

  TextDoc* = ref object of Doc
    title*: string
    text*:  string

  TodoDoc* = ref object of Doc
    todo*:     string

var all_docs*: seq[Doc] = @[]

all_docs.add TextDoc(title: "", text: "blah")
assert TextDoc(all_docs[0]).text == "blah"
Related