If you're saying that you CAN'T compare the python to C++ because of the GC then I disagree. GC only stops memory leaks. That is not the most frequent error that happens with C++. Clearly if you just subtract memory leak issues from C++ there's still a usability issue with just C++.
In order to have a proper comparison, you should control for variables that are irrelevant to the experiment. In this case, you want to look at the effect of typing, so you should control for GC. Which is why you should compare python to other GC'd static languages, but not to static non-GC'd languages.
No this is not true. Memory safety and memory leaks are different concepts. You can trigger a memory leak without violating memory safety. In fact a memory leak is not really an error recognized by an interpreter or a compiler or a GC. It is a logic error. A memory leak is only a leak because you interpret it as a leak. Otherwise the code is literally doing what you told it to do. It's similar to a logic error. I mean think about it, the interpreter can't know whether you purposefully allocated 1gb of memory or whether you accidentally allocated it.
Memory safety on the other hand is protection against violation of certain runtime protocols. The interpreter or runtime knows something went wrong and immediately crashes the program. It is a provable violation of rules and it is actually not open to interpretation like the memory leak was.
See python: https://docs.python.org/3/library/gc.html. You can literally disable the GC (during runtime) and the only other additional crash error that becomes more frequent is OOM. The GC literally just does reference counting and generational garbage collection... that's it.
I can tell you what makes python MORE memory safe then C++. It's just an additional runtime checks that are not zero cost.
x = [1,2]
print(x[2])
The above triggers an immediate exception that names the type of error (out of bounds) and the exact line that triggered it. This error will occur regardless of whether or not you disabled the GC. It happens because every index access to a list also checks against a stored length. If you're above that length it raises an exception. It's not zero cost but it's more safe.For C++:
int x[] = {1,2};
std::cout<<x[2]<<std::endl;
This triggers nothing. It will run even though index 2 is beyond the bounds of the array. There is no runtime check because to do so would make the array data structure not zero cost. This is what happens during buffer overflows. It's one of the things that makes C++ a huge security problem.Let's look at the type issue.
def head(input_list: List[int]) -> Optional[int]:
return input_list[0] if len(input_list) > 0 else None
x: int = head(2)
-------------------- #include <optional>
#include <vector>
std::Optional<int> head(const std::vector<int>& input_list){
return (input_list.length() > 0) ? input_list[0] : std::nullopt;
}
int main(){
auto x = head(2)
return 0;
}
Both pieces of code are identical. Python is type annotated for readability (not type checked). But both literally produce the same error messages (wrong input type on the call to head). Both will tell you there's a type error. It's just python happens at runtime and C++ happens at compile time. C++ has a slight edge in the fact that the error is caught as a static check. But this is only a SLIGHT advantage. Hopefully this example will allow you to see what I'm talking about as both examples literally have practically the exact same outcome of a type error. A minority of bugs are exclusively caught with type checking because runtime still catches a huge portion of the same bugs... and in general this is why overall C++ is still MUCH worse in terms of usability then python despite type checking.Those other people your copying your argument from likely only had jobs doing Java or C# and they did some python scripts on the side and came to their conclusions like that. I have extensive experience for production work in both and I can assure you my conclusions are much more nuanced.
Python and java stack up pretty similarly in my experience. There's no hard red flags that make either language a nightmare to use when compared to the other. People panic about runtime errors, but like I said those errors happen anyway.
Python does however have a slight edge in the fact that it promotes a more humane style of coding by not enforcing the oop style. Java programmers on the otherhand are herded into doing oop so you have all kinds of service objects with dependency injection and mutating state everywhere. So what happens is in Java you tend to get more complex code, while python code can be more straightforward as long as the programmer doesn't migrate their oop design patterns over to python.
That's the difference between the two in my personal experience. You're mostly likely thinking about types. My experience is that those types are not that important, but either way, modern python with external type checkers actually has a type system that is more powerful then Java or C#. So in modern times there is no argument. Python wins.
But prior to that new python type system my personal anecdotal experience is more relevant and accurate then other people's given my background in both Java and python And C++. Types aren't that important period. They are certainly better then no types but any practical contribution to safety is minimal.