
Nim Programming Language Tutorial - j-b
http://nim-lang.org/tut1.html
======
beagle3
I've just read through the Nim manual. On the surface, it looks as simple as
Python - but it is ridiculously deep when you look at all the template, macro,
term rewriters, etc.

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?

~~~
Araq
You cannot do these things easily currently since the assignment operator
cannot be overloaded. There are ways around it, you can "fix" the broken
builtin assignment with a TR macro, but since TR macros MUST not change
semantics (you can disable them on a global level and code shall continue to
work!) this is a bad idea.

~~~
beagle3
How about doing something like:

    
    
        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.

~~~
def-
I think that should be

    
    
        type refCounted[T] = object
          val: T
          refs: int
    

You could try a destructor for the object: [http://nim-
lang.org/manual.html#destructors](http://nim-lang.org/manual.html#destructors)

------
fiatjaf
For those wanting a quick grasp of the language, here's Nim in action:

\- against Python:
[http://rosetta.alhur.es/compare/Python/Nimrod/#](http://rosetta.alhur.es/compare/Python/Nimrod/#)

\- against Ruby:
[http://rosetta.alhur.es/compare/ruby/Nimrod/#](http://rosetta.alhur.es/compare/ruby/Nimrod/#)

~~~
def-
Wow, that's really cool! Never seen that before. (I implemented many of the
Rosetta Code tasks in Nim)

------
kartikkumar
I'm intrigued by Nim after browsing through some of the basic tutorials. Looks
quite straightforward to get started. As with other languages I look at, for
my use-cases it's important for me to understand0 if scientific packages are
available and if there's a "scientific computing ecosystem".

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...](https://github.com/nim-
lang/packages/blob/master/packages.json)

[2] [https://github.com/nimrod-code/nimble](https://github.com/nimrod-
code/nimble)

[3]
[http://eigen.tuxfamily.org/index.php?title=Main_Page](http://eigen.tuxfamily.org/index.php?title=Main_Page)

[4] [http://ab-initio.mit.edu/wiki/index.php/NLopt](http://ab-
initio.mit.edu/wiki/index.php/NLopt)

EDIT: Fixed typos

~~~
ldlework
While I'm not super familiar with the scientific computing field, I can say
that Nim needs everyone's help in building the library ecology. Right now, Nim
seems to be in the wrap-all-the-things! mode. You can see that most of the
available packages are bindings to existing libraries. I'm not sure this is a
bad thing. And I don't think it has anything to do with anything other than
Nim's currently small community.

~~~
thalesmello
I don't see a problem with that. Since Nim compiles to C, it's only natural
for people to take advantage of existing C libraries.

~~~
kartikkumar
I haven't dived deep enough to figure out if integration with existing
C/C++/Fortran libraries works out-of-the-box, or whether you have to setup
bindings a la Python. If it works out-of-the-box, my question is moot,
especially if two-way interoperability with Nim code is seamless.

~~~
ilaksh
You have to set up bindings but it is as simple as it could possibly be to do
by hand, and there is a c2nim program to help.

------
barosl
I'm quite surprised that Nim's strings are null-terminated, _and_ have a
length field. According to a forum article[1], it is mainly due to the C
interoperability.

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)

[1] [http://forum.nimrod-lang.org/t/125](http://forum.nimrod-lang.org/t/125)

~~~
gecko
This is actually really common in C++ libraries. I even worked in one (which I
know was on Windows, but I don't think was MFC; maybe OWL?) where the pointers
to the String object were actually pointing directly to the null-terminated C
string, and then each function in the class would start by fixing up the
pointer. E.g., something like

    
    
        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.

~~~
SamReidHughes
One example is std::string as implemented in the GNU libstdc++ or whatever
it's called.

------
Tloewald
Nice tutorial pitched just right for me. Looks a lot like Iron Python iirc. I
like that you can start writing old school interactive command line apps so
easily -- great for starting out and in the absence of solid gui tools.

------
wildmXranat
I just spent an hour going through Nim related webpages by users who write in
it. This is a good find, thanks.

~~~
Cyther606
This is another excellent Nim resource:
[http://goran.krampe.se](http://goran.krampe.se)

~~~
wbhart
Here is a slightly longer list of external articles I made.

[https://news.ycombinator.com/item?id=8811132](https://news.ycombinator.com/item?id=8811132)

------
jzelinskie
Is that german quote from something other than Rammstein lyrics?

------
davexunit
I don't see anything particulary special here. The metaprogramming features
are quite weak. The macro system is very primitive. The number types seem to
be lacking, too. I don't see anything about bignums, rationals, or complex
numbers.

~~~
def-
Metaprogramming:
[http://rosettacode.org/wiki/Metaprogramming#Nimrod](http://rosettacode.org/wiki/Metaprogramming#Nimrod)

My bignum library for Nim (not well tested yet):
[https://github.com/def-/bigints](https://github.com/def-/bigints)

Complex numbers: [http://nim-lang.org/complex.html](http://nim-
lang.org/complex.html)

How is the macro system primitive?

~~~
davexunit
>My bignum library for Nim (not well tested yet):
[https://github.com/def-/bigints](https://github.com/def-/bigints)

>Complex numbers: [http://nim-lang.org/complex.html](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. :(

~~~
klibertp
You're really very wrong on Nim's macros. It follows Lisp's defmacro tradition
instead of Scheme syntax-rules/syntax-case, but that doesn't make it any less
powerful (many would argue it's demonstrably _more_ powerful). You are also
dead wrong on syntax-rules/syntax-case capabilities, or maybe on what the
syntax/AST is, if you think that there's anything they can do that Nim can't.
Both systems deal with AST which means they both are unable to introduce new
ways of parsing the code, only transform already parsed one. In (some) Scheme
and Common Lisp you get access to readtable, which _is_ the parser, but that's
really a different thing. And even in Lisps it's not that popular: Clojure and
Emacs Lisp disallow this for example.

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.

