I'm just getting started with Nim, and really loving it. (My background is
mostly C++ and Objective-C, but I've spent time in Java, Swift, Python, Ruby,
Smalltalk-80, and I'm currently also learning Rust.)
I'd like to use a more Rust/Swift/etc. style where `nil` is not allowed. It
looks like the `not nil` annotation and the `options` module will let me do
that. But I'm running into problems (with Nim 1.2 on macOS). Yes, I realize
that not-nil is experimental, but it's documented in the language manual so I'm
assuming it's useable.
First, the compiler's nil-checker seems too limited. In the example below, it
doesn't seem to realize that the `raise` never returns. Workaround is to put
the return statement in an `else:` block.
{.experimental: "notnil".}
type
Foo = ref object
x: int
Container = object
foo: Foo not nil
proc newFoo(x: int): Foo =
if x < 0: nil else: Foo(x: x)
proc makeContainer(x: int): Container =
let f = newFoo(x)
if f == nil:
raise new CatchableError
return Container(foo: f) # Error: cannot prove 'f' is not nil
Run
Mixing not-nil with `Option` produces warnings too:
import options
{.experimental: "notnil".}
type
FooObj = object
x: int
Foo = ref object not nil
proc makeFoo(f: Foo): Option[Foo] =
if f != nil:
return some(f)
else:
return none(Foo)
Run
This produces:
notnil.nim(14, 20) template/generic instantiation of `some` from here
..../nim/1.2.0/nim/lib/pure/options.nim(119, 5) Warning: Cannot prove that
'result' is initialized. This will become a compile time error in the future.
[ProveInit]
notnil.nim(16, 20) template/generic instantiation of `none` from here
..../nim/1.2.0/nim/lib/pure/options.nim(125, 3) Warning: Cannot prove that
'result' is initialized. This will become a compile time error in the future.
[ProveInit]
Run
Known issues? Are there workarounds?
\--Jens|
---|---