6 ms·
Your argument makes no sense. I say the type checker is not the key differentiator then you say for python the key differentiator is the garbage collector. So
by deltasevennine 4y ago
Your argument makes no sense. I say the type checker is not the key differentiator then you say for python the key differentiator is the garbage collector.
So that makes your statement contradictory. You think type checkers are important but you think python works because of garbage collection.
Either way I'm not talking about the implementation of the language. I'm talking about the user interface. Why is one user interface better than the other?
I bet you if c++ has sane error messages and was able to deliver the exact location of seg faults nobody would be complaining about it as much. (There's an implementation cost to this but I am not talking about this)
Even an ugly ass language like golang is loved simply because the user interface is straight forward. You don't get non deterministic errors or unclear messages.
- za3faran 4y agoGC was one of the most important and relevant features (if not the most important) that allowed Java to penetrate, and eventually dominate the space where C++ used to be relevant in terms of middleware/business type applications. This detail matters a lot in this discussion. Then once that is taken as a given, you can compare different GC enabled languages based on other factors, such as type safety (or lack thereof in the case of python).
- deltasevennine 4y agoIf it does matter to the conversation then it's evidence supporting my point. I'm saying type checking isn't a key differentiator between something like JS/ruby/python vs. C++. You're implying the GC is the key differentiator. 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++.
- za3faran 4y agoGC is not just for memory leaks, but memory safety in general. It also enables several paradigms that are extremely difficult to get right without memory safety. 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.
- deltasevennine 4y ago>GC is not just for memory leaks, but memory safety in general. 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 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.
- gary17the 4y agoNo contradiction, really, it's just that we are talking about two different programming goals: I emphasize the goal of producing well-behaved software (especially when it comes to large software systems), while you emphasize the goal of producing software in an easier (more productive) manner. For my goal, a strong type system is a key differentiator. For your goal, a garbage collector is a key differentiator. The discussion probably comes to down to the question of whether garbage-collected, weakly-typed Python is as "bug-prone" as memory-managed, strongly-typed C++. I have no significant experience with Python, so I cannot answer authoritatively, but I suspect your assumption that "100,000 lines of code of python tend to be safer and more manageable then 100,000 lines of C++" might be wrong. In a large codebase, there will probably be many more dynamic-typing error opportunities (after all, the correct type has to be used for every operation, every function call, every calculation, every concatenation, etc.) than memory-management error opportunities (the correct alloc/dealloc/size has to be used for every pointer to a memory chunk; but only if C++ smart pointers are not used).
- deltasevennine 4y ago>but I suspect your assumption that "100,000 lines of code of python tend to be safer and more manageable then 100,000 lines of C++" might be wrong. I can give you my anecdotal experience on this aka "authoritative" in your words. I am a really really really good python engineer with over a decade of experience. For C++ I have 4 years of experience, I would say I'm just ok with it. Python is indeed safer then C++. Basically when you check for type errors at runtime, you actually easily hit all reasonable use cases pretty quickly. This is why unit testing works in reality even though your only testing a fraction of the domain. Sure this isn't a static proof but in Practical terms static type checking is only minimally better then run-time type checking. You can only see this once you have extensive experience with both languages and you see how trivial type errors are. Practicality of technologies isn't a property you can mathematically derive, it's something you get a feel for once you've programmed enough in the relevant technologies. It helps you answer the question of "How often and how easy do type errors occur uncaught by tests?" Not that much more often and not hard at all to debug. The thing that is actually making C++ less usable are the errors outside of type checking. The memory leaks, the segfaults, etc. The GC basically makes memory leaks nearly impossible and python doesn't have segfaults period. What python does is fail fast and hard once you write something outside of memory bounds. Basically it has extra run time checks that aren't zero cost that make it much much more safe. All of this being said, I am talking about type-less python above... when I write python, I am in actuality a type Nazi. I extensively use all available python type hints including building powerful compositional sum types to a far more creative extent then you can with C++. I am extremely familiar with types and python types. I have a very detailed viewpoint from both sides of the spectrum from both languages. That's why I feel I'm qualified to say this. >No contradiction, really, it's just that we are talking about two different programming goals: I emphasize the goal of producing well-behaved software (especially when it comes to large software systems), while you emphasize the goal of producing software in an easier (more productive) manner. I'm actually partly saying both. Python is both easier and more well-behaved and more safe. The "well-behaved" aspect has a causal relationship to "easier". It makes sense if you think about it. Python behaves as expected more so then C++. Literally I repeat: Python (even without types) is categorically safer then C++. I have a total of 14 years of experience in both. I would say that's enough to form a realistic picture.