I'm checking out Nimrod, and I like what I see alot.
One thing I thought was brilliant in D was the scope(exit) statement for simple and readable resource management (cleaner than RAII). Is there a way to do the same thing in Nimrod?
If not built in, perhaps with a macro? Scope statements make it much easier to write exception safe code. It is simply syntactic sugar, but that sugar is very sweet.
{
statements1
scope(exit) statement2
statements3
}
is transformed or lowered into:
{
statements1
try {
statements3
} finally {
statement2
}
}
The real benefit comes when you have to use many scope statements in a function to manage several resources, because it converts very nested code into straight line code. See The D Programming Language, pages 84-87 for discussion (the above transformation should be credited to those pages, which I am quoting from directly). I see that Nimrod has several macro features, would it be easy to use them to implement such a feature?
Thank you.
Best regards,
Jason
statements1
finally: statement2
statements3
At the moment except: can't be used with a specific exception, it has to be a catch all.
Sweet. In case future readers have this same question, I will demonstrate the lovely behavior of nimrod with respect to multiple finally statements. This is elegant. Thank you @gradha.
#!/usr/bin/env nimrod c -r
proc testFinally(): void =
echo("-- test 1")
echo("a")
finally: echo("e")
echo("b")
finally: echo("d")
echo("c")
testFinally();
# expect: "abcde"
proc testFinally2(): void =
echo("-- test 2")
echo("a")
finally: echo("b")
if true: raise newException(EArithmetic, "some exception")
echo("c")
finally: echo("e")
echo("d")
proc call2() =
try: testFinally2();
except: nil
call2()
# expect: "ab"
proc testFinally3(): void =
echo("-- test 3")
echo("a")
finally: echo("d")
echo("b")
finally: echo("c")
if true: raise newException(EArithmetic, "some exception")
echo("e")
proc call3() =
try: testFinally3();
call3()
# expect: "abcd"
beatifully produces:
-- test 1
a
b
c
d
e
-- test 2
a
b
-- test 3
a
b
c
d
Some suggestions in case you're not aware:
You can safely omit the : void from proc definitions, and Nimrod doesn't require you to end your lines with a semicolon ;)
Note that if you use except/finally as a statement your code will do unexpected things if you try to concatenate it into a single line with a semicolon (see https://github.com/Araq/Nimrod/issues/412).
this bug has been fixed https://github.com/nim-lang/Nim/issues/412
Presumably working nimrod code matching your example would be: ...
IIRC now we use defer: instead of finally: for that although both seem to work. see also: https://github.com/timotheecour/D_vs_nim/pull/20#issuecomment-377364528
EDIT: standalone finally is deprecated: Warning: use 'defer'; standalone 'finally' is deprecated [Deprecated]
It's a post from 2013 ;).
Anyway the idiomatic way to do scope guard is with a template that does try: body finally: as it's done by Udiknedormin here.
There is an example in the guards and lock section of the manual too.