top | item 32340516

(no title)

isofruit | 3 years ago

I do not have any experience with C++ and thus none about its python interop, which makes it hard for me to compare it to nim's python interop which I do have some experience with.

Given that, I'm curious what bits of C++/python interop are easier.

I'm mostly asking because my experience of nim-python interop consisted of: Compile nim module with nimpy imported. Put compiled nim module somewhere where your python can find it. write `import <Name_of_module>` in the python file Done, you now have access to the exported functions and symbols defined in the nim module.

Is it that C++ wouldn't need any additional imports to make it work that makes it more seamless?

discuss

order

rich_sasha|3 years ago

Well, I certainly wouldn't call C++/Python interop easy. It is, IMO, verbose, arcane and complex. BUT, once it works, you have truly seamless integration of Python and C++ code. It feels as magical as, say, two languages interacting on JVM or .NET (not that I used either). Or different languages talking through a REST API.

In C++, you'd write your C++ code as if you don't care about Python. Then, you add the "glue" code, which tells C++ how to convert objects to and from Python (there's more options than that but let's leave it here). That, plus a lot of boilerplate. Then, in effect, you can pass objects back and forth between Python and C++, create objects in C++, return them to Python, pass them back to more C++ functions, and so on.

I haven't used Nim+Python; but looking at Nimpy documentation, it looks like, for example, to export a class from Nim to Python, it needs to inherit from a special underlying class. You can't just take a class and make it available in Python. And even then, can you pass that back to Nim to call a function with?

Maybe yes, and if so, that bumps Nim higher up my priority list.

isofruit|3 years ago

Thanks for the Infos! For context: I used nimpy for a bit for a reimplementation on how Django hashes passwords, making use of one of python's std lib modules.

In terms of seamlessness, I can not confirm that it is exactly like having a python class, merely "fairly close". If you define a type, you can pass it to python, python can instantiate (with the typical way of Type() ) or even receive instances (if you define e.g. a constructor proc yourself). It can pass the instances back to nim to work with no problem (see e.g. quick example I whipped up: https://pastebin.com/v5wAqGxZ).

However, I have found that there are differences of a nim-type to a pythonclass:

1) In python you do not have direct access to the fields of an instance of a nim-type. You can access them via getters and setters, but you'll get runtime errors if you try to access them directly. To make that behave seamlessly you'd need to define a python wrapper class and hide stuff with @property decorators. Without such a wrapper class you could also not add a field to an instance of a nim-type like you could a normal python object.

2) An imported nim-type can not be inherited from in python (not sure if that works in C++, but at least it's a nim-python-interop limitation).

If you wanted to make a library in nim available in python that wasn't originally intended for the export, you'd likely also need to write a glue-layer in nim. The efffort there would consist mostly in copy pasting the proc signatures you want to make available and annotating them with the export-pragma, copy pasting the nim-type to make it inherit from the type needed for exporting and converting from the exported nim-type to the imported nim-type or vice-versa when jumping from python to nim or vice versa. Further, to hide the short-comings (that you can't inherit and that you don't have access to fields or can add fields) you'd need to wrap the nim-type in a python-class as described in 1).

My conclusion from what I heard from you so far and what I know of nimpy would be, that nimpy is 90% of the way there, workable but not as seamless, given that exported nim types and their instances aren't functioning exactly like python classes and their instances. Further the fact you'd need to wrap them in a Python class to hide that means, in comparison, extra work to C++ (though that may balance out with if the glue layer in C++ is more involved than the one in nim, I don't know).