
Nim Programming Language v0.16.0 released - dom96
http://nim-lang.org/news/e029_version_0_16_0.html
======
ENTP
Nim is a language I really want to like. Having looked for a language that's
1) Cross-platform, 2) Script-like syntax and 3) C Speeds, Nim should be my
ideal language. What I find though is a sense of frustration that grows over
time when using it. Sometimes this stems from the quality of the documentation
and other times from obscure problems that's hard to Google and get an answer
for.

I do appreciate Nim, and bought Dom's book, but I feel it's missing a trick in
its current state. No doubt I'll try it again as I'm ever the optimist :-)

~~~
lmm
When you say C speeds do you mean absolutely C-like or just a lot faster than
Perl/Python/Ruby? Would e.g. OCaml work?

~~~
nameless912
In my (admittedly very poor) testing, Nim can get to within 5% or so of C
speeds for simple benchmarks-it compiles to pretty decently optimized C, and
then can use LLVM/Clang as a backend to take advantage of all the amazing
optimization work being done there, so in the end you have code that is very
similarly performant to C.

------
arc776
Some articles on Nim for those that haven't encountered it:

Nim by example: [https://nim-by-example.github.io/](https://nim-by-
example.github.io/)

Getting started with Nim: [https://akehrer.github.io/posts/getting-started-
with-nim/](https://akehrer.github.io/posts/getting-started-with-nim/)

What is special about Nim: [https://hookrace.net/blog/what-is-special-about-
nim/](https://hookrace.net/blog/what-is-special-about-nim/)

What makes Nim practical: [https://hookrace.net/blog/what-makes-nim-
practical/](https://hookrace.net/blog/what-makes-nim-practical/)

Introduction to metaprogramming: [https://hookrace.net/blog/introduction-to-
metaprogramming-in...](https://hookrace.net/blog/introduction-to-
metaprogramming-in-nim/)

Writing a 2D platformer with SDL2:
[https://hookrace.net/blog/writing-a-2d-platform-game-in-
nim-...](https://hookrace.net/blog/writing-a-2d-platform-game-in-nim-with-
sdl2/)

------
jxy
I have love-hate relationship with Nim. It's the best C alternative I can find
for our high performance supercomputing needs, yet it breaks my code [0] (yes,
it's broken with 0.16.0 now) every single new release for the past year.

[0] [https://github.com/jxy/tpl](https://github.com/jxy/tpl)

~~~
dom96
Sorry about that. Have the changes which break your code been documented in
the changelog? If not please report them[0], if this is a regression then it
should be fixed quickly.

0 - [https://github.com/nim-lang/Nim/issues/new](https://github.com/nim-
lang/Nim/issues/new)

~~~
jxy
It's a problem with macro heavy code in Nim currently. Macros on typed NimNode
still touch too many undocumented/unspecified Nim internals, that it always
takes me some time to actually figure out what is the culprit.

On the other hand, code without much typed macro transformations is really
solid now, c.f. [0], the repo you are watching.

[0] [https://github.com/jcosborn/qex](https://github.com/jcosborn/qex)

~~~
dom96
I see. I would guess that macros on typed NimNodes are indeed unstable and
underused :\

Please don't give up on us. I see that you've already created a couple of
issues, if we forget about them then please keep pinging us on GitHub or IRC.

------
crux
I've been doing as much Nim as I can recently and really enjoying it. I just
took a week to put together a proof of concept Python module wrapper around
Nim code and I'm really looking forward to implementing some optimized inner
loops for our main Python application at work.

------
desireco42
I really like Nim, it is fantastic creation. That said, I didn't use it nearly
as much as I would like and people complaining about bugs are probably right.
Thank you contributors for your work.

If it could carve a small use case for itself, it would help it's momentum.
Something to be recognized for.

------
komerdoor
Nim comes very close to be the perfect language for me (game development,
machine learning etc.). Some things I experimented with including some links
to show what I tried as follows:

\- Fully controllable and plugable GC: I can decide for myself when the GC
runs and for how long. Very important for games. If I do not like the GC I can
even write my own or choose one of the many existing ones. See:
[http://forum.nim-lang.org/t/2646](http://forum.nim-lang.org/t/2646)

\- Meta-programming, templates, concepts etc.: To be able to write a machine
learning library I needed something that can replace simple code (DSL) with
more complex code using scalar math, SIMD, SPIR-V, OpenCL or Cuda. I also
wanted to be able to automatically generate bindings for scripting. See:
[http://forum.nim-lang.org/t/2654](http://forum.nim-lang.org/t/2654) and
[http://forum.nim-lang.org/t/2635](http://forum.nim-lang.org/t/2635) . As I
understood by reading the forums they will soon merge in many concept
improvements. See: [http://forum.nim-lang.org/t/2396](http://forum.nim-
lang.org/t/2396)

\- Nim itself can be used as an embedded scripting language: Nim as a
scripting language is used by the compiler to run Nim while compiling to
generate new code. Nim as a scripting language can also be used as a more
advanced configuration language (like Lua in the beginning). It can be used as
an embedded or standalone scripting language as well. See: [http://forum.nim-
lang.org/t/2647](http://forum.nim-lang.org/t/2647) and
[https://github.com/komerdoor/nim-embedded-
nimscript](https://github.com/komerdoor/nim-embedded-nimscript)

\- Compiling to C89 code (useful for creating libraries and cross-platform
support etc.): I want my games to compile on platforms not supported by GCC or
Clang/LLVM (actually I am sure they can support them all after some patching)
but with their own C89 compiler. After compiling to C it is easier for me to
see what the code will actually do. Still if I really want to I can choose to
compile to Javascript, C++, Objective-C and LLVM (not officially included yet)
as well. See:
[https://github.com/arnetheduck/nlvm](https://github.com/arnetheduck/nlvm)

\- Pretty good functional programming support (as far as compiled code allows
for): For this I created a library that use the zero-overhead iterators. There
are many alternatives as well and I like to be able to choose between multiple
implementations of higher level functionality. See:
[https://gist.github.com/komerdoor/70d9c25820952624cf797890a1...](https://gist.github.com/komerdoor/70d9c25820952624cf797890a18f9cd5)
. Of course a better implementation is possible by combining this with
concepts, generic dynamic method binding and all other of Nim's features. See
the following again: [http://forum.nim-lang.org/t/2654](http://forum.nim-
lang.org/t/2654)

\- Easy integration of existing C code: I wrote part of my code in C (low-
level) and another part in Nim (mid-level).

Some things which may get new Nim users in shock but I learned to love:

\- Use of indentation using spaces for grouping like Python: I never really
liked this but I cannot ignore that this made my code easier to read and
discourages my preference for one-liners (yes I know bad habit and does not
work well inside editors and with source-control).

\- Multiple ways to write the same identifier (case/underscore insensitive):
Liked this from the beginning. I am really consistent to choose a single style
but all my C code is written using underscore (ex.: typens_do_something(x))
while in Nim in prefer to use camel case (ex.: typensDoSomething(x)) or fully
drop the namespace entirely (ex.: doSomething(x) or x.doSomething()).

\- Multiple ways to call methods: Both "abc".toUpper() and toUpper("abc") are
the same. There are no namespace conflicts because Nim uses the best match for
toUpper like: func toUpper(c: char): char or toUpper(s: string): string. It
also makes it easier to add new methods for existing types while still being
able to call the methods like if OOP is being used.

\- Minimal support for OOP but encouraging composition over inheritance

~~~
komerdoor
Sorry people for the missing punctuation marks and paragraphs. It looks like
there is a bug in Hackers News that does not allow me to edit my post. Tried
different browsers even. Update: It seems I am able to edit this one

~~~
steveklabnik
You can only edit a post for up to an hour after you've posted it.

~~~
komerdoor
It was within the hour and the edit button was still there. I already reported
this to the HN team and someone updated the post for me.

------
gravypod
I don't want to be that guy but I don't see this language as usable. Not
because of technical reasons but because... I mean... look at it. I can't
understand what's going on. It's way too complicated.

    
    
       type Vector* {.importcpp: "std::vector", header: "<vector>".}[T] = object
    
       template `[]=`*[T](v: var Vector[T], key: int, val: T) =
         {.emit: [v, "[", key, "] = ", val, ";"].}
    

What the hell does that mean?How the hell do I check this is correct at a
glance?

I know "it's easy", "you'll get used to it", "after you learn the syntax it'll
be great" but I mean... no one is going to buy that.

I get that it's supposed to be condenced but I don't necassarily buy that as
being the end-all-be-all of language construction. I think that's actually
quite harmful to programmers. If a single character means the same as 10 lines
of a simpler language then you're more likely to hide a mistake in your code.

I'm not saying it's wrong either, I'm just saying a majority of programmers
will be afraid of it. I rather like what swift is trying to do with condensing
well-known operations but I don't think Nim and many other ML-inspired
languages do it in an approchable way.

~~~
mrkgnao
Macros implemented with ... string interpolation? This looks like a suboptimal
idea.

Edit: I spoke too soon. This looks like code generation, and I guess that you
ultimately have to do stringy things at some point. But couldn't there be some
kind of type-safe mechanism for this?

~~~
Tarean
There are basically three ways to do meta programming in nim. Simple
replacement of tokens:

    
    
        const debug = true
        template log(msg: string) =
          if debug: stdout.writeLine(msg)
    
    

You could also use other concrete types, generics and type checked or
unchecked expressions instead of string.

Macros are syntax tree transformations, similar to rust compiler plugins:

    
    
        import macros, strutils
    
        macro readCfgAndBuildSource(cfgFilename: string): typed =
          let inputString = slurp(cfgFilename.strVal)
          result = newStmtList()
    
          for line in inputString.splitLines:
            # Ignore empty lines
            if line.len < 1: continue
            var chunks = line.split(',')
            if chunks.len != 2:
              error("Input needs comma split values, got: " & line)
            let entry = quote do:
              const cfg`chunks[0]` = "`chunks[1]`"
            result.add(entry)
      
          if result.len < 1: error("Input file empty!")
    
        readCfgAndBuildSource("data.cfg")
    
    

This reads a file and creates constants from it at compile time.

Emit is a tad more complex. Nim is compiled to another language like c, c++ or
llvm. Emit lets you emit code in the host language, mostly to wrap libraries.
Don't think there is any way to make that typesafe.

