Hacker Newsnew | past | comments | ask | show | jobs | submitlogin
Nim language v0.18.0 released (nim-lang.org)
102 points by mratsim on March 1, 2018 | hide | past | favorite | 45 comments


Seems like nim is still doing well and progressing.

I last looked into it about 2 years ago, when the library ecosystem was very bare-bones and the language quite buggy, but promising non the less.

Clean, Python-like syntax and generally a joy to code in.

Anyone here actively using Nim and can share some insight into it's current state?


I think it's hugely underrated. I agree that it really is a fun language to use and as someone who came to it from a web dev perspective with no prior system level experience I had no trouble at all being productive in it (I built four internal Windows GUI apps with it).

But there's also some things that make people nervous -- like case & style insensitive names (ie. `read_file` is equivalent to `readFile`) -- that are almost never an actual issue.

Having that be more widely understood would do a lot of favors for Nim, and once the language hits a stable 1.0 I could see it getting a lot more attention.


> But there's also some things that make people nervous -- like case & style insensitive names (ie. `read_file` is equivalent to `readFile`) -- that are almost never an actual issue.

Gahhh, why would you do this? It just seems like it'd be a nightmare to use grep to understand your codebase.


This is exactly my point when I say it needs to be better understood: you wouldn't do it within a single project, but if you've got a third party library that exposes a `read_file` method you can use it as `readFile` meaning your own code base is more consistent.

In other words, you're not limited by the design decisions of another developer (or language, as nimmer pointed out).


Thanks, that's interesting. I see the justification for it, at least.

I don't know if the whole world is magically living with much more orderly developers than I have had the pleasure to work with, but I guarantee you that if I were using such a project at work, we'd end up with the same variable being referenced different ways.

I really wouldn't be able to grep for variables with confidence.

(Cf. Carmack: Everything that compiles will ultimately end up in your code. In the context of exploring static analysis tools, which were finding lots of errors.)

I do like the idea for uniformity though, but it seems like maybe better to restrict it -- define project-based 'style-rules', and automatically translate when moving between domains.

So foo_bar inside package A must be accessed as FooBar inside package B.


These style issues are trivial to enforce at commit time (pre-commit hook) and build time with a linter. It’s easy to enforce the order you desire upon your developers.


does such a linter actually exist, or is this the mathematicians trivial, "it is not required to discover something new to do it"?


> I guarantee you that if I were using such a project at work, we'd end up with the same variable being referenced different ways.

Luckily this is trivial to resolve as the compiler reports ambiguous variables as errors and you can then prefix by module name if required.


Hmm, maybe I misunderstood the feature.

If I have a variable declared as fooBar, and somewhere else in the code someone refers to it as fooBAr, does that compile, or is it an error?


It compiles, but is definitely considered bad style.


What if an external C library defines readFile and read_file and you want to refer to read_file as readFile?

If you explicitly rename your functions as you import them, that should have more predictable behavior.

Still, it's a nice sentiment.


What sane C library would do such a crazy thing though? :)


Being case insensitive is a PITA for implementing any numerical algorithm you read from a paper. Most mathematical symbols are single-letter, and quite often both capital letter and its small letter counterpart are used in the same paper.


The first letter of a Nim identifier is case sensitive, it's just the rest that aren't.


You are right. I didn't notice that before.


I use Nim a lot and I've never seen libraries that mix different styles. I use grep without issues.

Style insensitivity is useful when wrapping C libraries.


specifically for this nim ships with its version of grep - nimgrep


I've written quite a few personal projects in Nim, and I love programming in it. Nim is garbage-collected and the GC is not a stop the world GC, so the language is well-suited for game-development.

Its standard library is improving with each release, and is already equivalent to what you expect from most modern programming languages. It contains flaws and inconsistencies, but it is being worked on and stabilized for a 1.0 release of the language. The ecosystem is small - but growing.

Some of the great things about Nim -

1) Ability to interface with C/C++/Obj-C/JS

2) Can compile to any of ^

3) Meta-programming

4) Python like syntax

5) Small binaries

6) Can compile to WASM via emscripten

I've built AWS lambda jobs with Nim by interfacing with Python, as prototypes for work, but I've never been able to leverage the language in production. I really only use it professionally to replace personal shell scripts or other tasks I've previously automated.

That said - Nim has a bright future - it needs to mature and hit 1.0 and it could really use some more interest as well as sponsorship.

Github - https://github.com/zacharycarter


5) Small binaries

That part is amazing. I personally do not have a real use case to exploit it [1], just find it neat from an engineering viewpoint...

I guess, it has an aggressive dead code removal process, compared to other - nowadays hot - compiled languages (Go, Haskell, Rust, D, Crystal). In those languages if you use a small part of their standard library, you usually get large chunks of it linked in statically (+ runtime if there is such)...

(Once I've tried LTO with one of my Rust project: it increased the build time tremendously but in the end it managed to shave off only 30KB from my several MB binary...)

[1] If I would try micro controller programming ever, I probably would give Nim a shot because of this...


I've just tried now some Rosetta code examples. Most of it had to be modified a bit to get compiled with this Nim version although. (adding types, change case of type names)

Used -d:release --opt:size, then strip, Ubuntu 16.04 64 bit. The binary sizes:

GTK2 example code: http://rosettacode.org/wiki/GUI_enabling/disabling_of_contro... - 35k

http client: http://rosettacode.org/wiki/Ordered_words#Nim - 72k

http server: http://rosettacode.org/wiki/Hello_world/Web_server#Nim - 121k

The binaries are dynamically linked only to the common standard C prog. dependencies on Linux: linux-vdso.so.1, libc.so.6, ld-linux-x86-64.so.2 (Except for the gtk2 example of course, which uses libdl to to pull in a large bunch of additional gtk dependencies too...)


how does it compile to wasm if it has a GC?


Probably it builds the GC into the WebAssembly output.


Every time I see news about Nim I just wish Cobra[0] would get the same love...

[0] http://cobra-language.com/


    Recent News
    2013-12-23  Cobra 0.9.6 has been released.
Maybe because this is Hacker "News" and Cobra hasn't had a release in 4-5 years is why it's not mentioned much.


Nim transpiles to C, C++, or JavaScript so it can run on nearly anything (Windows, Linux, MacOS, embedded to some degree, web browser...etc). Cobra appears to be .NET, so a little more restricted I guess.


Compiles... compiles.

Edit -

Sorry - that was rude. I should have elaborated.

Transpiling is a specific type of compilation that involves two languages with a similar level of abstraction.

Compilation involves languages with different levels of abstraction.

Nim offers a much higher-level abstraction than C, thus you could consider the process of converting Nim to C, a compilation process rather than a transpilation process.


This comes up everytime i post about this and most people agree with me that transpile means convert to a different source language. It is definitely a common use, but I realize it is a gray area.

Edit: Compiling def isn't wrong, but Transpiling is more descriptive to me as it indicates you're not going to assembly or machine language or something like that.


Compiling is the correct terminology here. Nim transpiles to JavaScript, but it compiles to C and C++. You don't say that Rust transpiles to LLVM IR, do you?


Mad respect for you Dom, but why would going from Nim -> JS be Transpiling and Nim-> C++ be compiling? Both go from a high level Lang to another high level Lang.


I don't consider C/C++ high-level.


I would normally agree with you, but that seems subjective.


It is indeed a little subjective and changes with time. This Wikipedia article explains it fairly well I think: https://en.wikipedia.org/wiki/High-level_programming_languag...


I would say compiles is a more general form of transpiles. Transpiling meaning it compiles into a higher level form i.e. c, C++, JavaScript, and compile meaning it compiles into a more lower level form i.e assembly, bytecode, etc?

That's just how I look at it anyway.


Why?


Not the parent but my personal pet-peeve is case-insensitive variable names - a deal breaker for me.


> "That means only the first letters are compared in a case sensitive manner. Other letters are compared case insensitively within the ASCII range and underscores are ignored." [1]

Wow, this is strange. I understand the reasoning but strongly disagree with it. Not sure if it's a deal-breaker for me though, just... strange.

[1]: https://nim-lang.org/docs/manual.html#lexical-analysis-ident...


It definitely doesn't exist in any other language, so from that perspective it is strange. But please give Nim a try before closing the web page because of this feature.


Yeah like I said before, it's not necessarily a show-stopper, it just threw me off.


> First class support for unit tests and contracts this maybe ?


I don't know about Cobra, but I would say Nim has first class support for unit tests. If you check out the "Testable documentaion examples" section of the article, it shows they've even added support for testing sample code in inline function documentation. This is a really interesting approach. I don't use Nim myself (not a "systems" programmer - what a silly term that is, we all make "systems" but I guess that boat has sailed) but I'm interested in applying a similar approach in other languages.


I will just repost my old post, but a lot has happened since then:

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

- 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 and 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

- 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 and 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

- 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.... . 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

- 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


Your gist link under functional programming support is a 404 for me.


A part of the URL was missing. Here you go: https://gist.github.com/komerdoor/70d9c25820952624cf797890a1...


How is for target iOS/Android?


It can target everything that C89 can target, but it may require some additional steps like writing the Nim interface code for target specific system libraries etc. There are also tools to help with this, but I prefer to write the Nim interface to existing C code myself.

A thread about the added Android support: https://forum.nim-lang.org/t/3098

An old article about targeting IOS: http://www.thomasdenney.co.uk/blog/2015/1/27/nim-on-ios/

Also have a look at the following list: https://forum.nim-lang.org/t/2670 (nimx, a cross-platforn GUI library, seems to support Android/IOS)

The following shows how to interface with ObjectiveC code / libraries: https://github.com/jangko/objc (Of course, if they are not already available, you will have to create the Nim interface to the IOS libraries yourself)

One of the tools that can be used to create Nim interface code from existing C header files: https://github.com/nim-lang/c2nim




Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: