5 ms·
> So basically compile time type checking just makes some of the errors get caught earlier which is a slight benefit but not a KEY differentiator. Unfortunatel
by gary17the 4y ago
> So basically compile time type checking just makes some of the errors get caught earlier which is a slight benefit but not a KEY differentiator.
Unfortunately, I have to completely disagree here, at least based on my experience. Shifting software error detection from runtime to compile time is absolutely paramount and, in the long run, worth any additional effort required to take advantage of a strong type system.
Firstly, writing unit tests that examine all the possible combinations and edge cases of software component input and state is... an art that requires enormous effort. (If you don't believe me, talk to the SQLite guys and gals, whose codebase is 5% product code and 95% unit test code.)
Secondly, writing automated UI tests that examine all the possible combinations and edge cases of UI event processing and UI state is... next to impossible. (If you don't believe me, talk to all the iOS XCUI guys and gals who had to invent entire dedicated Functional Reactive paradigms such as Combine and SwiftUI. ;) J/K)
Thirdly, I don't even want to get into the topic of writing tests for detecting advanced software problems such as memory corruption or multi-threaded race conditions. Almost nobody really seems to know how to write those truly effectively.
> So what was it that makes python easier to use then C++?
The Garbage Collector, which is side-stepping all the possible memory management problems possible with careless C++. However, a GC programming language probably cannot be the tool of choice for all the possible problem domains (e.g., resource-constrained environments such as embedded and serverless; high-performance environments such as operating systems, database internals, financial trading systems, etc.)
- deltasevennine 4y agoYour 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.
- throwaway2037 4y ago"financial trading systems" This is a myth. Many financial trading systems are written in C# and Java. Don't be distracted by the 1% of hedge funds with lousy funding that need nanosecond reactions to make money. If you have good funding, product diversity matters more than speed. Otherwise, your post is excellent. Lots of good points. SQLite is something that EADS/ESA/NASA/JAXA would write for a aeroplane / jet fighter / satellite / rocket.
- gary17the 4y agoThanks, glad you found the post useful. I'm sure C# and Java make excellent programming languages for many if not most financial applications, but I meant that in the context of high-volume Enterprise Application Integration (EAI). Basically financial message transformation, explosion, summarization, audit, etc. across multiple financial institutions. The volume of messages to be processed was quite considerable, so nobody even thought about taking the risk of switching from battle-tested C++ to anything else.
- throwaway2037 4y agoI am sure your use case was incredibly specific. For insane performance requirements plus enterprise software that is not greenfield, basically everything is C++. No trolling. Have you ever seen the high-frequency Java stuff from Peter Lawrey's Higher Frequency Ltd.? It is insanely fast. Also, LMAX Disruptor (Java) data structure (ring buffer) is also legendary. I have seen it ported to C++. That said, you can beat all of this with C++, given enough time and resources!
- deltasevennine 4y agoAnother thing you're not addressing here is basically Type checking solves none of the problems you describe. You claim it's extraordinarily hard to write tests for UI and for memory corruption. And that's your argument for type checkers? It's next to impossible to type check UI and memory corruption. So your argument has no point here. SQlite is written in C. It has type checking. Yet people still write unit tests for it. Why? Because type checking is mostly practically inconsequential. All your points don't prove anything. It proves my point. All the problems you talk about can be solved with more advanced proof based checkers. These systems can literally proof check your entire program to be fully in spec precompile time. It goes far beyond just types. Agda, Idris, Coq, and Microsofts lean have facilities to prove your programs to be fully correct 100% of the time. They exist. But they're not popular. And there's a reason for that. You say it's paramount to move error detection to compile time. I say, this problem is ALREADY solved, but remains unused because these methods aren't PRACTICAL.
- gary17the 4y ago> It's next to impossible to type check UI Incorrect. Have a look at the Swift OpenCombine library. Multiple Publishers of a particular type that emits a single boolean value (e.g., an "Agree to Terms" UI checkmark and an "Agree to Privacy Policy" UI checkmark) are combined at compile-time to be transformed into a single Publisher of a type that emits only a single boolean value (e.g., the enabled/disabled state of a "Submit" button). Effectively, it is not possible to even compile an app that incorrectly ignores one of the "Agree" checkmarks before enabling/disabling the "Submit" button. > It's next to impossible to type check (...) memory corruption Incorrect. Have a look at the Rust standard library. Sharing data across multiple treads requires passing a multi-threaded Mutex type; attempting to share data through a single-threaded Rc (reference-counted) type will not compile. Once the Mutex type is passed, each thread can only access the memory the Mutex type represents by acquiring another type, a MutexGuard, through locking. Effectively, it is not possible to even compile a program that incorrectly ignores multi-threading or incorrectly accesses memory in a race condition with other threads thus possibly corrupting that memory. Moreover, it is also not possible for a thread not to properly release a lock once the MutexGuard type goes out of scope. > All the problems you talk about can be solved with more advanced proof based checkers. Unlikely. Without feeding strong type information that describes your problem domain into a checker, the checker cannot reason about your code and figure out possible errors. A strong type system is a "language" for a programmer to communicate with his or her checker. > You say it's paramount to move error detection to compile time. I say, this problem is ALREADY solved, but remains unused because these methods aren't PRACTICAL. > [the C language] has type checking. Yet people still write unit tests for it. Why? Because type checking is mostly practically inconsequential. Please do not hold it against me if I do not continue commenting here - you must be from a different, parallel Universe. (How is Elvis doin' on your end? ;) J/K)