Hacker News new | past | comments | ask | show | jobs | submit login
Nim for scientific computing: Back to the future (rnduja.github.io)
116 points by nkurz on Oct 21, 2015 | hide | past | favorite | 38 comments



Nim looks great! I especially appreciate the types and validations.

You mention Nim for scripting - can I pique your curiousity to add a Nim script example to the Num statistics project? http://github.com/numcommand/num


I will have a look, but I cannot promise anything. There are a lot of things that I want to do and only so much time... :-)


Would be nice if NIM could be called from pyton passing numpy arrays. That would speed up adaptation until the NIM ecosystem grows.


For the last 9 months I've been working (part-time) on a project that does exactly that. The startup where I work makes extensive use of this project to speed up our Python.

The basic infrastructure was in place after ~2 months. Since then, our team has been using it extensively, and I've been filling out the functionality & evolving the API (for example, testing different array iteration & access interfaces, to see what feels awkward vs convenient, balancing the trade-off between Nim-ness vs Numpy-ness vs Pythonic-ness, etc.).

You write your Nim procs, then annotate them with a special annotation (that's valid Nim, but inert most of the time). When you want to auto-generate Python wrappers around your Nim procs, there's a Python script you run that creates & compiles Python C-API code that exposes the Nim procs in Python as a shared library. This auto-generated code also translates Nim exceptions (including back-traces) to Python exceptions, calls the Nim GC before you return to Python runtime, etc. The auto-generated code also includes auto-generated Python docstrings, extracted from the Nim procs.

There's a Nim type that provides a nice Nim interface to Numpy arrays, so you can pass Numpy arrays into your Nim procs and access them natively. We've also recently added support for a few cute features, like the tuple return types & default parameter values. :)

The API is not yet solidified, so I'd call the project "alpha" or "beta", but it definitely works! The intention is to open-source it soon (once we're happy with the API).

Would you be interested in using something like this? What features would you need? Even better, are you a Python+Nim coder who could contribute?

Feel free to reply here or contact me via email (contact info in profile).


I certainly would be happy to know about it when it comes out!

I would rather avoid the double ecosystem in the long run, but it would be a great thing to have until the Nim ecosystem grows.


I assume you're the article author? If so, I know who you are on the Nim forums, so I'll certainly keep you informed. :)

In terms of ecosystems, I think that there is deployed Python code in the world that will never be re-written in Nim. I would prefer that Nim can be used to write drop-in extension modules for this Python code, rather than not at all.

I also think that there are situations where Python is a better fit for a problem than Nim. For example, handling JSON files in Nim (or any statically-typed language) will always be awkward (you have the choice between a double-dispatch Visitor Pattern or accessor methods that cast), but in Python, handling JSON is the easiest thing in the world. Likewise for any heterogeneous container.

By the way: Great article about Nim, as always. :)


Have you and your employer thought about making this project open source?


We haven't just thought about it, we intend to do it! :)

We're just waiting until we're happy enough with our Numpy array API that we'd be confident in calling it "mostly stable".

The (real) Numpy's C API is a perfect example of an API in which gradual accretion of new functions & functionality has given rise to a monstrous (both huge & horrible) API. The naming scheme & parameter patterns are inconsistent; sometimes the names are ambiguous (ie, unclear because they are overly general) or confusing (ie, the function does something other than what you'd expect from the name); and there are several very-similar functions, where it's not always clear which one you should use.

I do understand why the Numpy C API has evolved this way: Once you introduce a function in an API, you can't remove it / rename it / change its parameters, or you will break backwards compatibility with your earlier releases and cause headaches for many of your users. (And of course, there are constraints upon an API written in C, that do not affect an API exposed in Python or Nim.)

So we're really trying to dogfood our own API as much as possible before we inflict it upon the public. :)


Sounds very interesting... I'd love to have a look.


Great! I see that you created "pyexperiment" [ https://github.com/duerrp/pyexperiment ], so it's safe to assume you know your way around Python & Numpy.

Is there a good way to get in contact with you?


https://github.com/micklat/NimBorg/tree/master/nimborg/py works for general py objects - I would guess numpy support shouldn't be hard


Can we realistically expect a competent, officially supported REPL for Nim over time? I would be immediately sold if this otherwise very promising looking language could remove this obstacle.


I certainly hope so. It is of course the biggest missing element in sight, but I do not think we will see anything before 1.0 comes out


What's wrong with `nim i`? That's a repl, and it's hardly possible to get more official than that


It's been removed* - provided a bad UX for people coming into Nim since it doesn't support C extensions / importing of modules that use C extensions, which can be a fair bit. If you try to use them regardless, it's easy to crash the REPL.

* It's not entirely removed, just obfuscated so that if needed it can be still used as long as you "know what you're doing" and are willing to put up with it not being a general purpose REPL. Use

nim secret

to run it.


Not sure why Nim keeps getting compared to Python. It's quite evidently influenced by the Wirthian languages, though I suppose contemporary programmers aren't really versed into those.


I believe Nim's creator has a background using Borland's Pascal compilers (Delphi, Turbo Pascal). Nim is basically a modernized ObjectPascal with GC, generics and whitespace sensitivity. He even started out prefixing type names with T and P, just like Borland did, though fortunately that's going away.


I only compare it to python because of the use case. Actually, if you read the post, I also consider Lua and other languages.

Still, I think, the similarity in syntax can help. If there is one thing that python got right, in my opinion, is its straightforward syntax, and that helps saving brain power for something other than parsing


GC, indentation-significant syntax?


Whitespace significance is practically the only resemblance, then. Wirth's languages obviously were garbage collected.


Algol and Oberon were garbage collected, but Pascal and Modula-2 weren't. Not sure about others (Euler? Modula-3? Oberon-2?)

Nim feels a lot more like Python than one would think just reading the descriptions. I can't put my finger on why, exactly - maybe the type inference that gives an almost duck-type experience, maybe the incredibly helpful dogfooding community; I'm not sure.


You have plenty of options to interface C and Python. You can use Cython to create Python bindings to C libraries or even better you can use cffi which works with PyPy as well


My issue with Cython is that (at least as I've understood it from the tutorials I've read) it's a sub-language within Python, where you add Cython elements iteratively+incrementally (diverging from Python in the process) until the code runs "fast enough".

I'd rather work directly in a full-featured, internally-self-consistent language (and Nim is a very nice language) from the start. Hence -- for me, at least: Nim. :)


Have you looked at Julia (http://julialang.org/)?


Yes, I have, and Julia does look nice. It clearly has some very good libraries for scientific computing, and its syntax looks (to me) like an interesting combination of Python (which I like) and Matlab (which I don't like).

Aside from an entirely-subjective preference that caused me to fall in love with Nim at first sight, there are practical reasons for choosing Nim over Julia.

The overarching reason is that there is much more Python code in the world than Nim or Julia put together, and I think it will remain this way for a long time. (My startup previously worked almost completely in Python, for example, aside from some C or C++ extension modules and the usual Bash scripts for sysadmin.) Python also has some solid webserver frameworks, and is great for a variety of general-purpose tasks.

So, I wanted a solution that would enable us to incrementally rewrite code as necessary, without needing to rewrite everything from Python all at once. Also, I have no desire to rewrite our webserver code from Python. Flask & Django are just fine.

As I understand it (and please correct me if I'm wrong), Julia doesn't compile to C. So I can't compile snippets of Julia code and call them from my Python main-loop.

In contrast, not only is this possible in Nim, but Nim's macro system & well-developed AST spec make it very easy to traverse my Nim procs during compilation, to auto-generate per-proc wrapper code in C.


You're right that you can't compile Julia to static libraries (yet). Calling Julia from Python is not very mature at the moment, but calling Python from Julia is actually pretty robust via PyCall.jl (https://github.com/stevengj/PyCall.jl).


Hey -- working on similar things here. Would love to follow up but don't see your email in your profile. Mind adding it or sending me a note? (mine is in my profile)

Cheers!


Great! Email sent to the address in your profile.


The fact is that all these options are more complex than just using Nim.

Cython is certainly great, but still Python objects and C structs differ, and you have to keep in mind the difference. Same for C functions and Python functions. And if you use the dynamic features of Python, you do not gain much in efficiency, because Cython does not have static dispatch, hence it has to rely on runtime checks.

In a way, Cython is its own language, and it is not a particularly powerful one. The help you get from types is limited, as many things will just have type object. At this point, I just prefer to use Nim, which is friendly enough, and has overloading, generics, macros and many other features.


If only the Nim project had access to a few of the tens of millions being spent by Yahoo in order to more effectively deliver clickbait about the Kardashians and the like.

I mean, if the money actually came from a different organization than Yahoo.

Its good they do have support from 3DICC though.


What about Numba for Python in order to get the speed? Or is that a stupid suggestion for your requirements?


Numba is a great technology, but I find it still a little disappointing.

The way I see it is this. Python is not a particularly fast language, but has evolved a big ecosystem of scientific libraries. Now people are running into the language limitations, hence the development of various tools to compile parts of Python - either AOT or JIT - with PyPy, Numba, Cython, Numexpr and so on.

The problem is that all these tools (save from PyPy, which is just a different interpreter) introduce their ow sublanguage, slightly incompatible from one another. For instance, both Numba and Cython have to infer types, but their type systems are not equal.

Nim does not have the reach of Python ecosystem, but it is a solid language, that manages to combine well the speed of C and the simplicity and flexibility of Python.

I would rather start from a solid foundation and add libraries on top of it gradually, rather than start from a developed ecosystem and add a host of tools that try to fix the inherent limitations of the platform.

Hence, in the short term it is great that the projects created by Continuum exist, but eventually I would like to have something a little more consistent


Lovely write up, thanks! The syntax is so much nicer than Rusts is. :)


Nim's garbage collector is indeed very fast. I wrote an application which makes heavy use of string concatenation and a lot of regexp matches in native Perl syntax. I am amazed how performant the code is. Also compilation works pretty fast.

However I didn't know yet that the Nim language is that powerful.


> there is no FFI to C

What? Nim's homepage has the phrase "C FFI is easy in Nim.." along with some example code.


I think this is referring to the lack of FFI support in NimScript (http://nim-lang.org/0.11.3/nims.html).


In the comparison with torch you are translating x:dot(y) as x * y, but it should be x.t() * y


No, it is right like that. In linalg, * on vectors is the scalar product. I have designed linalg to agree with mathematical conventions, rather than numpy conventions.




Consider applying for YC's Summer 2025 batch! Applications are open till May 13

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

Search: