this post was submitted on 18 Jun 2023
12 points (100.0% liked)
Programming
13386 readers
2 users here now
All things programming and coding related. Subcommunity of Technology.
This community's icon was made by Aaron Schneider, under the CC-BY-NC-SA 4.0 license.
founded 2 years ago
MODERATORS
you are viewing a single comment's thread
view the rest of the comments
view the rest of the comments
If your goal is to rewrite your python code in C with minimal hassle, start thinking of objects as structs with functions attached to them. If you detach the functions from the structs, instead having them take structs as an argument, then you can obtain something which is C-like but likely very unoptimised.
Personally, I think I would steer you towards Rust or C++ instead - both can run just as quickly, but have more OOP features and modern features which may make moving easier. Learning C is still a very good thing to do, but I'm not sure this project would be the best project to do that with.
I second everything said here. I would add that C++ might be a better candidate in this case as translating Python's OOP and Context Management would be more easily done in C++ than rust IMO. Thought it might involve a bit of template if your code heavily rely on duck typing, and you will have to get familiar with the weird move semantic of C++. Also make sure to activate ASAN and maybe UBSAN for the development phase and have an optimized build with debug symbols to run with valgrind (this is also valid if you decide to stick with C).
But if you're already familiar in rust, pick that.
Unless you have specific platform requirements, I would avoid C for any large projects nowadays. It's OK when learning low level stuff because it's one of the languages with the fewest abstraction layers, but this aspect becomes a weakness at scale. And especially when porting from higher level languages.
Also, something not mentioned yet, do you actually need to move everything to C? It might be that the core of the logic is only a few function that you can more easily translate to C and then call from ctypes or a native module. So you get to discover C for 80% of the benefits and 20% of the hassle.
The main reason why one would want to use C is likely Foreign Function Interface (FFI), whatever code you write in C (apart from emitting assemblies) would likely be usable and extensible from any other programming languages so long that some of the conventions are followed. Rust and C++ could likely produce code just as fast as well optimized C code, but inaccessible or not readily accessible to other programming languages IE Name Mangling that are compiler implementation dependent, missing FFI access to STL and Traits and so forth. If it was readily accessible, then I would ask where is QT API (complete API access, not API-Lite) access for any other programming language.
FFI is pretty much the only reason why I am still writing in C in a very large project like GUI Toolkit to replace GTK and QT by using Vulkan. I would not recommend doing what I do when it come to implementing OOP manually in C to ensure that other programming language could extend my library. (I would write VTable manually and establish some of the OOP paradigms. C compiler does extremely well when optimizing out virtual dispatches to static dispatch.)
That's about it, as you said, it have a lot of hassles in C, so that why I am now working on Compiler Generator to create dialects on top of C similarly to MLIR so it would compile to readable C at the end of it as well as generating LSP server, FFI-JSON, and other things for it.
Deep down, C++ class functions take a pointer to their objects as a first "invisible" parameter.