I've been swapping back and forth between C++ and Python a lot in the past month, which causes me to reflect on Russel's theory of types, which was an attempt to avoid certain kinds of conceptual recursion by distinguishing the type of the "two" in "two apples" from the "two" in "two oranges."
It didn't get a lot up uptake from the other philosophers in the playground, and is now considered not much more than a footnote.
Except in software.
The biggest distinction between C++ and Python, after you get over the "oh my god it's full of whitespace" thing, is the type systems, which I'm obviously obsessed with given the content of the postings on this blog. But it's an important question, both philosophically and from a practical software engineering point of view.
Rather than asking "which is better", it is more profitable to ask, "What are the strengths and weaknesses of strongly vs weakly typed languages?"
Advocates of strong typing believe that making the type part of the public interface of any object allows for stronger error checking. Advocates of weak typing believe that advocates of strong typing are smoking some pretty interesting stuff.
In practical terms, I've noticed that the (relatively) strong typing of C++ really does add a significant cognitive burden when writing code. At times it seems like about half the code is type declarations of some kind, often repeated ones. I saw this when writing my Python code generators: entire sub-systems of the C++ generator got sidelined because they were concerned with tracking type information that is irrelevant to Python.
But does the weak typing of Python produce more errors, and if so of what kind?
So far, I have to say: no. With reasonable testing--about which more later--and ordinary best practises in design and implementation, I don't see any errors in Python that can be pinned on not having a strong(er) type system.
I'm aware that Stroustrup once said that C's type system is "promiscuous and stupid", or words to that effect, but I've worked in languages with stronger type constraints and found no greater level of safety with them, either. And modern C++, while still labouring under the burden of C compatibility, is a lot tighter than it once was.
One sees the burden most severely in things like the size-types in the STL, where:
std::string::size_type
is different from:
std::vector<float>::size_type
is different from:
std::vector<std::set<int> >::size_type
even though they are all "really" unsigned ints under the hood in most implementations. Not being able to inter-change values with these types without generating warnings (at best) or errors (at worst) does not make for safer code. It makes for developers who spend some of the precious and limited cognitive capacity on remembering typical trivia, rather than concentrating on design and implementation issues that matter.
The one thing that strong typing does is move a vast range of run-time errors to compile time, and that's a good thing if you never test your code. For those of us who do test early and well, it isn't such a big deal.
The other thing strong types do is permit the compiled code to run more efficiently, because all those run-time checks don't have to happen. But I can't help thinking the concept of type as such is probably the biggest instance of premature optimization we have ever seen.
It didn't get a lot up uptake from the other philosophers in the playground, and is now considered not much more than a footnote.
Except in software.
The biggest distinction between C++ and Python, after you get over the "oh my god it's full of whitespace" thing, is the type systems, which I'm obviously obsessed with given the content of the postings on this blog. But it's an important question, both philosophically and from a practical software engineering point of view.
Rather than asking "which is better", it is more profitable to ask, "What are the strengths and weaknesses of strongly vs weakly typed languages?"
Advocates of strong typing believe that making the type part of the public interface of any object allows for stronger error checking. Advocates of weak typing believe that advocates of strong typing are smoking some pretty interesting stuff.
In practical terms, I've noticed that the (relatively) strong typing of C++ really does add a significant cognitive burden when writing code. At times it seems like about half the code is type declarations of some kind, often repeated ones. I saw this when writing my Python code generators: entire sub-systems of the C++ generator got sidelined because they were concerned with tracking type information that is irrelevant to Python.
But does the weak typing of Python produce more errors, and if so of what kind?
So far, I have to say: no. With reasonable testing--about which more later--and ordinary best practises in design and implementation, I don't see any errors in Python that can be pinned on not having a strong(er) type system.
I'm aware that Stroustrup once said that C's type system is "promiscuous and stupid", or words to that effect, but I've worked in languages with stronger type constraints and found no greater level of safety with them, either. And modern C++, while still labouring under the burden of C compatibility, is a lot tighter than it once was.
One sees the burden most severely in things like the size-types in the STL, where:
std::string::size_type
is different from:
std::vector<float>::size_type
is different from:
std::vector<std::set<int> >::size_type
even though they are all "really" unsigned ints under the hood in most implementations. Not being able to inter-change values with these types without generating warnings (at best) or errors (at worst) does not make for safer code. It makes for developers who spend some of the precious and limited cognitive capacity on remembering typical trivia, rather than concentrating on design and implementation issues that matter.
The one thing that strong typing does is move a vast range of run-time errors to compile time, and that's a good thing if you never test your code. For those of us who do test early and well, it isn't such a big deal.
The other thing strong types do is permit the compiled code to run more efficiently, because all those run-time checks don't have to happen. But I can't help thinking the concept of type as such is probably the biggest instance of premature optimization we have ever seen.




Leave a comment