4 ms·
Nim is a statically typed language that is syntactically close to Python and there are some attempts at integrating the two.
by gregwebs 4y ago
Nim is a statically typed language that is syntactically close to Python and there are some attempts at integrating the two.
- elcritch 4y agoErg 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/Pebaz/nimporter https://github.com/yglukhov/nimpy 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.
- bb88 4y ago> 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. So I find this to be super interesting, particularly when it comes to parts with lots of pads that one has to route. Python would let you iterate the algorithm quickly. It's far easier to optimize the big O notation of your autorouter than in C++, say. Once you're happy with the algorithm, then you can try to optimize the slow bits in C/C++. But even things like dicts in python are still going to be super fast. As far as speed up goes, there's PyPy, Nuitka, and Cython, which are all interesting. There's also a restricted version of python called RPython which PyPy uses to compile everything to C. If it's me in 2022, I'd probably go with Cython. A lot of packages uses it. It's well known, and it's (mostly) python -- mostly because it would be easier to go back and forth in python rather than switching mental contexts between Nim and C and Python. See here for the examples. https://cython.readthedocs.io/en/latest/src/tutorial/cython_tutorial.html https://cython.readthedocs.io/en/latest/src/tutorial/cython_... Good luck with the project!
- elcritch 4y agoThanks! Good to hear others would be interested in something like that. It's one of those borderline "oh man that would be nice". > Python would let you iterate the algorithm quickly. It's far easier to optimize the big O notation of your autorouter than in C++, say. The hard part wouldn't be the routing algorithm itself. It's getting the algorithm and code to handle all of the corner cases. That's really what has kept me from it.. Getting all the correct data in and out of KiCad seems like a pain. > mostly because it would be easier to go back and forth in python rather than switching mental contexts between Nim and C and Python. If I were to tackle it, I'd do it in Nim since my overall productivity is as fast or faster than with Python. The Python layer would just be necessary to act as the glue layer to KiCad and `nimpy` looks great. It looks like `nimporter` builds binary wheel's too! That's awesome. Cython seems handy but involves more mental switching between Python-to-C types than Nim would (IMHO). Taking an example from the Cython docs and writing it in Nim with nimpy would be: proc randomNoise(number: int = 1): seq[float] {.exportpy.} = result = newSeq[float](number) for i in 0 .. number: result[i] = rand(1.0) Versus the original Cython: def random_noise(int number=1): cdef int i # allocate number * sizeof(double) bytes of memory cdef double *my_array = <double *> malloc( number * sizeof(double)) if not my_array: raise MemoryError() try: ran = random.normalvariate for i in range(number): my_array[i] = ran(0, 1) return [x for x in my_array[:number]] finally: free(my_array)
- bb88 4y agoIn that case I would wrap it with a class to enjoy programming with the reference counted python garbage collector here. from cython.cimports.cpython.mem import PyMem_Malloc, PyMem_Free @cython.cclass class SomeMemory: data: cython.p_double def __cinit__(self, number: cython.size_t): # allocate some memory (uninitialised, may contain arbitrary data) self.data = cython.cast(cython.p_double, PyMem_Malloc( number * cython.sizeof(cython.double))) if not self.data: raise MemoryError() def __dealloc__(self): PyMem_Free(self.data) # no-op if self.data is NULL Extending it into a typical python array type doesn't look that hard. Just need to map the appropriate dunder functions into C array operations. Then optimized functions can directly interact with the C types. Basically any utility function you might need with C data types you would just add to the class. And at that point, you're back to coding in regular python again. I hope this helps but good luck with your project no matter which option you take.