I'm new to Nim, so sorry if I re-ask any common questions; I have already searched quite a bit while translating a familiar short program into Nim to try to find out what is idiomatic.
I have written a short command line program using argparse (which is pretty nice!).
To start with, I just wrote:
var p = newParser("foo")
let opts = p.parse()
But I understand that parse() can throw an exception, so it's not surprising that I get a warning: observable stores to 'opts'
And of course, I want to catch the exception and print a nice error message.
So I wrote:
try:
let opts = p.parse()
# rest of my program
except: die(getCurrentExceptionMsg())
and this works nicely. However, there are two problems:
try:
opts = p.parse()
except: die(getCurrentExceptionMsg())
The problem here is the interaction of let and try. I cannot use a try expression, because the except and try branches do not have the same type. I suppose I could use a var (but what would I initialize it to?), but the point here is very much that opts is immutable!
I feel I'm missing something obvious about Nim idiom, and would be grateful if someone could tell me what it is?
(I suppose it would also be possible to simply put the rest of the program in another proc, so that the code above becomes:
try:
let opts = p.parse()
main(opts)
except: die(getCurrentExceptionMsg())
but that again seems more like a workaround than a good idiom.)
If something like a quit/die procedure is called inside an expression, then that expression is still considered an expression. Nim's quit proc has the property of the pragma noreturn, which implies that a proc never , which allows for this behavior. So this compiles:
let a = 3
let b = if a < 5: quit() else: 10
echo b
Which means you can do:
let opts = try: p.parse() except: die(getCurrentExceptionMsg())
# rest of my program