Nim Programming Language Tutorial
nim-lang.org
nim-lang.org
Whether or not you can make use of it without being aware of all those things remains to be seen. I suspect the answer is mostly yes, i.e. that one can use the nim ecosystem effectively without knowing all of that. (my answer for C++ would be "mostly no" - you need to really know everything about all the dark corners of the language to use the ecosystem effectively).
I'm trying to think of a good way to implement automatic reference counting with copy-on-write, e.g. for big arrays, but haven't come up with one yet. Could a Nim veteran kindly point me in the idiomatic direction?
They are just functions that take an AST tree, modify that AST or produce a new AST and return it. Its just normal Nim code working on an AST object. That's it! I wrote a small blog article about them when I first learned about them: http://blog.ldlework.com/a-cursory-look-at-meta-programming-...
I encourage you to conquer your fears!
I was just comparing to C++ - where you have to understand how everything about templates and the STL works if you intend to understand the error messages produced by the compiler if you use STL. Or any library that interacts with STL containers. I heard things on this front have improved - I myself have left C++ for C a while ago.
C++ is a monstrosity. A common advice is "just pick the parts you like and stick to them". But it never works that way - as soon as you interact with 3rd party code, you have to deal with the parts THEY liked.
In comparison, my intuition says that despite all the dark corners (and if you read the entire manual, there are quite a few of them), that's not the case with Nim; Instead, if you treat it like a dialect of Python, you'll get simplicity close to Python; You'd only need to understand those dark corners if you plan to make use of them.
But I will need actual experience in Nim to find support for or against this intuition.
type refCounted[T] =
val: T
refs: int
proc `v=`(var x:refCounted[T], var y:refCounted[T]) =
inc(y.refs)
dec(x.refs)
if x.refs <= 0: destroy(x.val)
x.val = y.val
# use let so x and y cannot be assigned
let x, y = refCounted[string]
# instead use x.v to assign and manage refs properly.
x.v = y
using "let" would make sure all assignments happen through a blessed method (such as the ".v" assignment I defined above).But to actually make it work, I would need to decrease reference on going-out-of-scope (as there a way to do that? maybe a python "with" style enter exit macro?).
And to make it easy to work with, there would need to be a way to pre- "incref" an argument before it is passed as an argument, and "decref" it after the function call return. I can probably write a macro that rewrites every function call with a refCounted arg so that it increfs() on the way in, decrefs() on the way out; or maybe have that macro on the callees instead.
Guess I'll have to try the different approaches and see what works and how efficiently.
type refCounted[T] = object
val: T
refs: int
You could try a destructor for the object: http://nim-lang.org/manual.html#destructors- against Python: http://rosetta.alhur.es/compare/Python/Nimrod/#
- against Ruby: http://rosetta.alhur.es/compare/ruby/Nimrod/#
I had a look through the `packages.json` [1] listing for Nimble [2] and couldn't really spot the maths packages that I'd need, e.g., numerical integration, optimization, linear algebra. Given that I can't find any of those, I'm guessing there aren't any physics packages either e.g., Newtonian mechanics, physical constants etc. Maybe maths libraries are available as ports to e.g., Eigen, NLOPT etc.?
Can anyone that is more familiar with the community comment on the potential of Nim as a language for scientific computing, in contrast to e.g., Julia?
[1] https://github.com/nim-lang/packages/blob/master/packages.js...
[2] https://github.com/nimrod-code/nimble
[3] http://eigen.tuxfamily.org/index.php?title=Main_Page
[4] http://ab-initio.mit.edu/wiki/index.php/NLopt
EDIT: Fixed typos
I understand that FFI is kinda important for system languages, but isn't it giving up too much to disallow null characters in the middle of a string? Null-terminated strings generally work well, but there have been some corner cases that made me annoyed. (Such as PHP's preg_* functions)
class StringClass {
...all members, and then...
char *str;
};
StringClass *StringClass::new() {
StringClass st = new StringClass;
...
return (StringClass *)st->str;
}
void StringClass::someFunc() {
StringClass *realThis = this - sizeof(StringClass) + sizeof(char *);
...
}
Evil, eh?The good news is that, no, this does not have to prevent you having nulls in your string. The way this usually works is that all of the language's native string handling routines just use the length, so that's fine, and you're at least protected if you want to call C string handling routines instead. This can result in some unexpected behavior on the C side, but it beats the alternative.
You can have null characters in the middle of strings:
var s = "foo"
s[1] = '\0'
echo len(s)
echo s[2]
Nim will always append a null character to a string for when it gets passed to a C function, but Nim's string functions work just fine with the string proper containing null characters also.My bignum library for Nim (not well tested yet): https://github.com/def-/bigints
Complex numbers: http://nim-lang.org/complex.html
How is the macro system primitive?
>Complex numbers: http://nim-lang.org/complex.html
Ah, good! Glad to be wrong about that! It would be nice if Nim's reader could handle these numeric types transparently.
>How is the macro system primitive?
Well, I like to use macros to create new syntax, which AFAICT you can't do that with Nim. I'm used to using 'define-syntax' in Scheme, and Nim's macro system seems to be far less robust than that. I guess that's the price paid for non-homoiconic syntax.
I just don't see anything new and exiciting in Nim. :(
Personally I favour pattern-based macros, like the ones implemented in Dylan, Elixir or Sweet.js (to show some non-sexp-based languages with such macros); but there is nothing "wrong" with procedural macros and they are not, in any way, less robust.
You don't have to be excited by Nim, but you should try to avoid spreading lies just because you aren't. Maybe a "lie" is too strong a word, but this statement: "Nim's macro system seems to be far less robust than that" is really very wrong and I wanted to stress this fact.