What does HackerNews think of nimpy?

Nim - Python bridge

Language: Nim

I mean honestly, the closest language to Mojo really is Nim. In the latest Lex Fridman interview with Chris Lattner [0] when he talks about his ideas behind Mojo it pretty much sounds like he's describing Nim. Ok fair, he wants Mojo to be a full superset of Python, but honestly with nimpy [1] our Python interop is about as seamless as it can really be (without being a superset, which Mojo clearly is not yet). Even the syntax of Mojo looks a damn lot like Nim imo. Anyway, I guess he has the ability to raise enough funds to hire enough people to write his own language within ~2 years so as not have to follow random peoples whim about where to take the language. So I guess I can't blame him. But as someone who's pretty invested in the Nim community it's quite a shame to see such a hyped language receive so much attention by people who should really check out Nim. ¯\_(ツ)_/¯

[0]: https://youtu.be/pdJQ8iVTwj8?si=LfPSNDq8UKKIsJd3

[1]: https://github.com/yglukhov/nimpy

You can also do this in Nim, which basically means you can write any program you could in Python with libraries in Nim. https://github.com/yglukhov/nimpy
If are a data scientist and come from python take a look at nimpy, a great way to just import python libraries and use them! https://github.com/yglukhov/nimpy Numpy, pandas, pytorch all usable in Nim.

Nim is the ultimate glue language, use libraries from anything: python, c, js, objc.

I've come to really enjoy programming in Nim. Note that Nim is very different language despite sharing a similar syntax. However, I feel it keeps a lot of the "feel" of Python 2 days of being a fairly simple neat language but that lets you do things at compile time (like compile time duck typing).

There's a good Python -> Nim bridge: https://github.com/yglukhov/nimpy

Related: Nimpy[0] provides an easy way to write Python extensions in Nim, which manages the ABI side very well.

Python 2 is now gone, but until it was, Nimpy was an easy way to write Python extension modules that only needed to be compiled once, and would work with any of your installed Python 2 and Python 3. Magic.

[0] https://github.com/yglukhov/nimpy

Erg looks fun for small programs. Though Erg's syntax choices seem less Pythonic than I'd expected. Interesting though, some of the idioms seem handy.

Though Nim definitely can be described as a statically typed Python-compatible language! I haven't used them but https://github.com/Pebaz/nimporter https://github.com/yglukhov/nimpy both seem great. Nimporter in particular looks fantastic for writing fast python libraries.

Actually come to think of it that might be the easiest way to write fast KiCad 6 plugins.. I really want to try making a native KiCad autorouter. But I don't want to figure out the C++ plugin setup and since KiCad 6 the Python APIs seem better documented and supported anyways. Problem is that Python would likely be too slow. Nimporter could be perfect. It looks really simple to setup.

Maybe things have changed over the years. I've played around with Hy in 2017 and in the end felt like it combines the bad parts of Python with the bad parts of a Lisp.

If you're forced to use Python it's usually because of one of 2 reasons: Either you need to work with colleagues on something (in which case almost certainly they wouldn't accept a lispified version of it) or because you need some of the libraries that are already implemented.

In the latter case, you might say Hy is a good option. But why bind yourself to the slowness of Python when you could just as well use some fast Lisp (e.g. Common Lisp) that interacts with a Python interpreter similar to nimpy [0] from Nim? Not sure if such a thing already exists for CL, but it should be quite feasible to write and then you get access to all your Python library needs while actually using a better language for the rest of your code.

But I'm all ears on the real advantages Hy provides aside from being neat.

[0]: https://github.com/yglukhov/nimpy

I've used https://github.com/yglukhov/nimpy and I have to say the package, the author and the nim community were all phenomenal in helping me implement nim code that works as a Python package.
https://github.com/yglukhov/nimpy gives very, very solid access to the Python ecosystem from Nim - I've copied code from Python docs and have had it work with hardly any changes. Hopefully that's a good enough excuse to try Nim out for a personal project!
I love Trio, much better than the standard asyncio.

> It's not needed, yes, but neither is Python itself. You could just write C.

I'm currently learning C, so I can use Python as a front-end for C, giving users a nice interface while using C to handle the hard work, which is what lots of Python libraries do under the hood.

If C is not your thing, there are some interesting projects to use other languages with Python [https://github.com/PyO3/PyO3] | [https://github.com/yglukhov/nimpy]

We don't want to automatically convert between `int` and `float` because there's a loss of information, since floats aren't able to represent integers precisely.

However, we don't need to specify types until the point of conversion:

    let a = 1
    let b = a.float
> Python's behavior (though correct to spec) is arguably worse

Yeah that is not ideal. Looking at the code it seems logical at first glance to expect that `b` would be a `float`. In this case, the type hints are deceptive. Still, it's not as bad as JavaScript which doesn't even have an integer type! Just in case you haven't seen this classic: https://www.destroyallsoftware.com/talks/wat

Another gotcha I hit in Python is the scoping of for loops, e.g.,https://stackoverflow.com/questions/3611760/scoping-in-pytho...

Python takes a very non-obvious position on this from my perspective.

Ultimately, all these things are about the balance of correctness versus productivity.

I don't want to be writing types everywhere when it's "obvious" to me what's going on, yet I want my idea of obvious confirmed by the language. At the other end of the scale I don't want to have to annotate the lifetime of every bit of memory to formally prove some single use script. The vast majority of the time a GC is fine, but there are times I want to manually manage things without it being a huge burden.

Python makes a few choices that seem to be good for productivity but end up making things more complicated as projects grow. For me, being able to redefine variables in the same scope is an example of ease of use at the cost of clarity. Another is having to be careful of not only what you import, but the order you import, as rather than raise an ambiguity error the language just silently overwrites function definitions.

Having said that, as you mention, good development practices defend against these issues. It's not a bad language. Personally, after many years of experience with Nim I can't really think of any technical reason to use Python when I get the same immediate productivity combined with a static type checking and the same performance as Rust and C++ (also no GIL). Plus the language can output to C, C++, ObjC and JavaScript so not only can I use libraries in those languages directly, and use the same language for frontend and backend, but (excluding JS) I get small, self contained executables that are easily distributable - another unfortunate pain point with Python.

For everything else, I can directly use Python from Nim and visa versa with Nimpy: https://github.com/yglukhov/nimpy. This is particularly useful if you have some slow Python code bottlenecking production, since the similar syntax makes it relatively straightforward to port over and use the resultant compiled executable within the larger Python code base.

Perhaps ironically, as it stands the most compelling reason not use Nim isn't technical: it's that it's not a well known language yet so it can be a hard sell to employers who want a) to hire developers with experience from a large pool, and b) want to know that a language is well supported and tested. Luckily, it's fairly quick to onboard people thanks to the familiar syntax, and the multiple compile targets make it able to utilise the C/C++/Python ecosystems natively. Arguably the smaller community means companies can have more influence and steer language development. Still this is, in my experience, a not insignificant issue, at least for the time being.

Nim can use Python's ecosystem in both directions with nimpy https://github.com/yglukhov/nimpy and nimporter https://github.com/yglukhov/nimpy

This lets you gradually transition hot path Python modules to Nim, get compiled performance generally on par with C and Rust, whilst enjoying strong, static typing with great type inference.

In my experience (6-7 years 4 of which are full time) Nim strikes the perfect balance of the productivity you get with Python with high performance at the same time.

Also the metaprogramming features are incredible and, importantly, don't use a language subset but use the base Nim language itself.

Another nim & python thread that has not been mentioned yet here

https://news.ycombinator.com/item?id=28506531 - project allows creating pythonic bindings for your nim libraries pretty easily, which can be useful if you still want to write most of your toplevel code in python, but leverage nim's speed when it matters.

If you want to make your nim code even more "pythonic" there is a https://github.com/Yardanico/nimpylib, and for calling some python code from nim there is a https://github.com/yglukhov/nimpy

Nimpy: https://github.com/yglukhov/nimpy

A good test as an example: https://github.com/yglukhov/nimpy/blob/master/tests/tpyfromn...

I've tried it and it works fine. The only problem I ever had was trying to call a specific Python function at the same time from multiple Nim threads. I'm not sure where the fault lay exactly, I just made that part of the code single-threaded and moved on.

> FFI: Can nim use a C++ class and vtables? D does it all the time, nearly every language proclaims to have the best C++ interop but only D seems to be actually able to do it. Templates, classes, structs, and more all work.

Well, it depends on how you define "best". Beyond an ABI, FFI is obviously a function of the implementation rather than the language per-se.

The main Nim implementation can use C++ as a backend language, and when it does, it can use any C++ construct very easily by way of the .emit and .importcpp directives. For sure, classes, structs, exceptions all work, and IIRC templates do too (although you might need to instantiate a header yourself for each concrete type or something .... haven't done that myself). This implementation also means that it can use any C++17 or C++20 construct, including lambdas and friends. Does D's C++ interop support C++17? C++20? Can you guarantee it will support C++27? Nim's implementation already does, on every single platform you'll be able to use C++27 on (as long as C++27 can compile modern C++ code; there had been backward incompatible changes along the C++ history).

You can't just #include a C or C++ header and call it a day; You need to have a Nim compatible definition for any symbol (variable, macro, function, class, ...). There are tools that help you and make it almost as easy as #include, such as nimterop[0] and and nimline[1], and "c2nim" which is included with the Nim compiler is enough to generate the Nim definitions from the .h definitions (though it can't do crazy metaprogramming; if D can do that, then D essentially includes a C++ compiler. Which is a fine way to get perfect C++ compatibility - Nim does that)

But Nim can also do the same for JS when treating JS as a backend.

And it can basically do the same for Python, with nimpy[2] and nimporter, generating a single executable that works with your installed Python DLL (2.7, 3.5, 3.6, 3.7) - which is something not even Python itself can do. There was a similar Lua bridge, but I think that one is no longer maintained.

> We also have Mir, which I haven't benchmarked for a while but was faster than OpenBLAS and Eugene

There's quite a bit of scientific stack built natively with Nim. It is far from self-sufficient, but the ease with which you can use a C library makes up for it. I haven't used it, but Laser[3] is on par with or exceeds OpenBLAS speedwise, and generalizes to e.g. int32 and int64 matrix multiplication; Arraymancer[4] does not heve all of numpy's functionality but does have quite a few nice bits from scikit-learn, supports CUDA and OpenCL, and you can use numpy through nimpy if all else fails. Also notable is NimTorch[5]. laser and arraymancer are mostly developed by mratsim, who occasionally hangs out here on HN.

D is a fine language, I used it a little in the D1 days, and it was indeed a "better C++" but did not deliver enough value to be worth it for me, so I stopped. I know D2 is much better, but I've already found my better C++ (and better Python at the same time!) in Nim, so I haven't looked at it seriously.

[0] https://github.com/nimterop/nimterop

[1] https://github.com/sinkingsugar/nimline

[2] https://github.com/yglukhov/nimpy

[3] https://github.com/numforge/laser

[4] https://github.com/mratsim/Arraymancer

[5] https://github.com/sinkingsugar/nimtorch

> Syntax wise Nim it is a step back. It's hard to read and understand while any C/C++ dev will have next to no effort reading through D code. And of course while D is C ABI compliant it interoperates with C++ well too.

On the other hand, people coming from Python, Ruby, Pascal, Ada will appreciate the minimal amount of sigils.

> I seriously doubt that Nim or any other language in this regard has better metaprogramming than D.

Can you write an Embedded DSL + compiler running at compile-time in D

- https://github.com/numforge/laser/tree/master/laser/lux_comp...

Can you write a cryptographic library with hex conversion to big integer and modular arithmetic running at compile-time in D?

- https://github.com/mratsim/constantine/blob/master/constanti...

Can you generate a state machine that lowers down to optimized computed gotos with no dynamic allocation suitable for multithreading runtimes and embedded devices and able to display the actual graph at compiletime?

- https://github.com/mratsim/Synthesis

Can you describe x86 opcodes in a declarative way for a JIT assembler and do all the rex/modrm/sib computation at compile-time?

- https://github.com/mratsim/photon-jit/blob/master/photon_jit...

And the same thing for an emulator?

- https://github.com/mratsim/glyph/blob/master/glyph/snes/opco...

Can you implement async as a library?

Can you emulate classes with ADTs to solve the expression problem, avoid cache misses and multithreading problem due to OOP and the double indirection due to the visitor pattern?

- https://github.com/mratsim/trace-of-radiance/blob/master/tra...

> Nim might have a speed overhead in certain tasks but that depends on a benchmark. Besides, does Nim have anything similar to NumPy which is actually faster? D does.

It does:

- https://github.com/mratsim/Arraymancer

With CPU, OpenCL and Cuda backends (in differing state of maturity)

and it's being used for data analysis for example ancestry prediction:

- http://home.chpc.utah.edu/~u6000771/somalier-ancestry.html

You can even run a neural network and see its training live:

- https://github.com/Vindaar/NeuralNetworkLiveDemo

AFAIK D doesn't have any plotting library while Nim has plot.ly integration and a ggplot2 port in pure Nim:

- https://github.com/brentp/nim-plotly

- https://github.com/Vindaar/ggplotnim

And lastly nim can easily call Python:

- https://github.com/yglukhov/nimpy

or be called from Python:

- https://github.com/Pebaz/nimporter

Nim has an automated generator for C/C++ wrappers or translating from C.

Also there are very easy ways to create Python modules in Nim:

https://robert-mcdermott.gitlab.io/posts/speeding-up-python-...

https://github.com/yglukhov/nimpy

I am trying to improve Nim data science ecosystem with https://github.com/mratsim/Arraymancer.

I think today the best way to try Nim is for slow Python utilities vi nimpy: https://github.com/yglukhov/nimpy

You can also use Nim in Jupyter the following way: https://github.com/apahl/nim_magic

My next step would be to improve interop between Arraymancer tensors and Numpy ndarrays.

Have you seen Nimpy[0]?

It allows for a nice integration between Nim and Python. At least for the examples I have tried, it could be used in place of Cython, when there's a need for extra speed in some hot loops and similar situations.

[0] https://github.com/yglukhov/nimpy

I'll mention another great library from the same author:

https://github.com/yglukhov/nimpy

A library which allows you to connect Python and Nim so you could, for example, use Nim (instead of Cython) for speeding up some parts of your code, compile it, and call it from your Python program.

A year ago I've started experimenting with Nim as a "faster Python" — put some declarations, change some keywords and you're ready to go — your "compiled Python" is now ~30x faster.

Recently I've used Nim for the first time for an official project at my job (at university). Instead of doing a simulation with Python+Numpy, I've decided to do it with Nim, and just plot the results with matplotlib. The whole experience was very pleasant.

Speaking of interoperability with Python, there is a great Nim library called Nimpy [0], which makes possible to use Nim as a more pleasant Cython — you can keep writing Python, and just use Nim for the intensive/slow stuff.

[0] https://github.com/yglukhov/nimpy