900 to 25000 in 3 days!

I've just written nearly 25 thousand lines of code in just 3 days! Well, to be honest, I've only written nearly 900 lines of code, and then Py++ then went and generated the other 25 thousand! This may sound like nothing, that an auto-code generator tool has produced lots of code, but the key thing here is that before Py++ I had had to write thousands of lines of python wrapping code by hand (I used to have over 10 thousand lines of python wrapping code which were written and maintained by hand). Py++ has changed this into 900 lines, which are much easier to maintain, understand and configure. Indeed, the Py++ generated code is of a higher quality than what I had written, includes default arguments, named arguments and can be completely updated from the source code in less than 10 minutes. This means that my python wrappers can now remain in sync with the C++ code, leading to a faster turn around of my write, compile, wrap, test in python, unit test in C++ cycle. I don't want to gush, but I am very pleased with Py++.

Indeed, looking back at my last post, I was perhaps a bit harsh. I had some very specific problems to solve, and while the documentation of Py++ was not that helpful, the actual Py++ source code was very readable, and I was quickly able to add the functionality that I required (the ability to add classes from one namespace to the list of base classes of another, despite each namespace being wrapped independently, and also the ability to remove all virtual overload classes and thus "finalise" each of my virtual C++ classes). In doing this, I reaffirmed my like of Python. In particular, it is pretty cool that if I don't like a modules function, I can always write my own and then dynamically replace it when I want, e.g.

#save an old copy of the function
legacy_function = LegacyClass.legacy_function

#define my replacement
def my_new_function(...):
    # here I write how I want the function to behave!
    # Ha ha ha - I have the power!

#tell the code to use my replacement
LegacyClass.legacy_function = my_new_function

#All code now uses my replacement function!

....
....

#Put the old function back, so that I don't have to
#deal with edge-cases
LegacyClass.legacy_function = legacy_function

#Everything is now back as it was.

This is why Python is great for quick editing and understanding - it allows very rapid modification and messing with library code without the need to edit the library itself! This is also why, perhaps, Python is a bit dangerous for anything big - it is too easy for the user to completely change all of your functions and definitions. I like the fact that C++ is fixed at compile time - it means that I can assume that a function is immutable within a running program, and that the interface provided by the header file is a contract that must be honoured at all times in the program (especially as it is the programmer, rather than the user, who is responsible for ensuring that the code actually honours the contract). In contrast, the mutable functions in python mean that I cannot assume that all contracts are honoured, and users are free to change functions in ways that violate those contracts, either through ignorance or deliberately to satisfy a short-term requirement. This leads me to the suspicion that bug hunting a large Python program is a never-ending job, as you can't independently verify the correctness of each class (as they can be changed dynamically by the user), and you can't also test all use cases, as the there are no firm foundations on which to build those use cases. The upshot of this is that I am very happy to provide a Python interface for my Sire C++ classes, but I definitely don't want those classes to be modified or extended in Python itself. The possibilities for user-created errors that are impossible to debug should be sufficient to put anyone off!