Nim is the ultimate glue language, use libraries from anything: python, c, js, objc.
There's a good Python -> Nim bridge: https://github.com/yglukhov/nimpy
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.
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.
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.
> 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]
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 worseYeah 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.
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.
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 PyGotham talk: https://www.youtube.com/watch?v=IVgNVJdizHg another blog post: https://robert-mcdermott.gitlab.io/posts/speeding-up-python-...
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.
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
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:
Also there are very easy ways to create Python modules in Nim:
https://robert-mcdermott.gitlab.io/posts/speeding-up-python-...
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.
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.
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.
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.