6 ms·
But there's a paradox. Why does 100,000 lines of code of python tend to be safer and more manageable then 100,000 lines of C++ despite the fact that python has
by deltasevennine 4y ago
But there's a paradox.
Why does 100,000 lines of code of python tend to be safer and more manageable then 100,000 lines of C++ despite the fact that python has no type checker and C++ has a relatively advanced type checker?
Why do startups choose a python web stack over a C++ web stack?
I don't think it's "self-evident." I think there's something more nuanced going on here. Hear me out. I think type systems are GREAT. I think python type hints and typescripts are the way forward. HOWEVER, the paradox is real.
Think about it this way. If you have errors in your program, does it matter that much if those errors are caught during runtime or compile time? An error in compile time is caught sooner rather then later but either way it's caught. YOU are protected regardless.
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. I mean we all run our code and test it anyways despite whether the system is typed or not so the programmer usually finds most of these errors anyways.
So what was it that makes python easier to use then C++?
Traceability and determinism. Errors are easily reproduced, languages that always display the same symptoms from certain errors and in turn deliver error messages that are clear and are readable. These are really the key factors. C++ on top of non-deterministic segfaults, astonishingly even has compile time messages that can confuse users even further.
- tikhonj 4y agoThere is no "paradox". C++ is dangerous because of memory management and awful semantics (undefined behavior/etc), both of which are orthogonal to static typing. It's a bit like saying that there's a paradox: everyone says that flying is safer than driving, but experimental test pilots die at a much higher rate than school bus drivers!
- deltasevennine 4y agoParadoxes don't exist in reality. It's a figure of speech based on something that was perceived as a paradox. This much is obvious. Much of the fervor around dynamically typed languages in the past was driven largely by the dichotomy between c++ and other dynamically typed languages. Nowadays it's more obvious what the differentiator was. But the point im making here is that type checking is NOT the key differentiator here.
- 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.
- icedchai 4y agoI think it is simpler than that: C++ is an incredibly complex and verbose language. Most of web development is working with strings, and C++ kinda sucks there. There is also a compilation/build step, so overall productivity is lower. Python is "easier" all the way around (we'll ignore the dependency management/packaging debates.) It depends on how you define "safer." Run-time errors with Python happen frequently in large programs due to poor type checking all the time. Often internal code is not well documented (or documented incorrectly) so you may get back a surprise under certain conditions. Unless you've have very strict tooling, like mypy, very high test coverage, etc. there is less determinism with Python. Also, this may come as a surprise, but many people do not run or test their code. I've seen Python code committed that was copy-pasta'd from elsewhere and has missing imports, for example. Generally this is in some unhappy path that handles an error condition, which was obviously never tested or run.
- deltasevennine 4y agoI know it happens "all the time" but these runtime errors happen fast and quick. You catch most of these issues while testing your program. Statistically more errors are caught by python runtime then an equivalent type checked c++ program simply because the python user interface fails hard and fast with a clear error message. C++ on the other doesn't do this at all. The symptoms of the error are often not related to the cause. Python is safer then C++. And this dichotomy causes insight to emerge. Why did python beat c++? In this case the type checker is irrelevant. Python is better because of clear and deterministic errors and hard and fast failures. If this is exemplary of the dichotomy between c++ and python and if type checkers are irrelevant in this dichotomy it points to the possibility that type checking isn't truly what makes a language easier to use and safer. The current paradigm is rust and Haskell are great because of type checking. This is an illusion. I initially thought this was well. Imagine a type checker that worked like c++. Non deterministic errors and obscure error messages. Sure your program can't compile but you are suffering from much of the same problems, it's just everything is moved to compile time. It's not about type checking. It's all about traceability. This is the key. >there is less determinism with Python You don't understand the meaning of the word determinism. Python is almost 100 percent deterministic. The same program run anywhere with an error will produce the same error message at the same location all the time. That is determinism. Type checking and unit testing does not correlate with this at all. This is not the case with c++.
- mamcx 4y ago> and C++ has a relatively advanced type checker? But why it NEEDS that? Because C++ is FAR MORE DANGEROUS. And worse language, in so many aspects, that you need everything to tame it. In contrast, other langs like python have the luxury of see what C/C++ do wrong and improve over it. Just having a `String` type, for example, is a massive boost. So for them, the type system already have improved the experience! --- So this is key: Langs like python have a type system (and that includes the whole space from syntax to ergonomics - like `for i in x`, to semantics) and the impact of adding a "static type system checker analysis" is reduced thank to that. And considering that if you benchmark for a "static type system checker analysis" is what C++/C#/Java (at the start?) is then the value is not much. Is only when you go for ML type systems where the value of a static checker become much more profitable.
- deltasevennine 4y agoHindley mindler allows for flexibility in your types and this high abstraction and usability in code. The full abstraction of categories allows for beautiful and efficient use of logic and code but it's not safety per se. Simple type systems can also offer equivalent safety with less flexibility. What make Haskell seem more safe is more the functional part combined with type safety. Functional programming eliminates out of order errors where imperative procedure were done in the wrong order.
- jjav 4y ago> If you have errors in your program, does it matter that much if those errors are caught during runtime or compile time? Of course it matters. If an error can be caught by the compiler, it will never get to production. Big win. With typeless languages like python the code will get to production unless you have 100% perfect test coverage (corollary: nobody has 100% perfect test coverage) and then some unexpected moment it'll blow up there causing an outage. This happens with metronomic regularity at my current startup (python codebase), at least once a month. It is so frustrating that in this day and age we are still making such basic mistakes when superior technology exists and the benefits are well understood.
- deltasevennine 4y agoThat's fine. A type checker won't catch everything. Run time errors happen regardless. I find it unlikely that all the errors your code base is experiencing is the result of type errors. Something like c++. You get a runtime errors. You have no idea where it lives or what caused it. Your python code base delivers an error but a patch should trivial because python tells you what happened. Over time these errors should become much less.
- jjav 4y ago> A type checker won't catch everything. That's a strawman, nobody has claimed a statically typed language will catch all possible errors. It will however catch an important category of common errors at compile-time, thus preventing them from reaching production and blowing up there. Other types of logic error of course exist, in all languages. > Something like c++. You get a runtime errors. You have no idea where it lives or what caused it. I don't know what this means? You seem to be suggesting that code in a statically typed language cannot be debugged? Clearly that's not true. Debugging is in fact usually easier because you can rule out the type errors that can't happen.
- deltasevennine 4y ago>I don't know what this means? You seem to be suggesting that code in a statically typed language cannot be debugged? You don't know what it means probably because you don't have experience with C++. These types of errors are littered throughout C++. What you think I'm suggesting here was invented by your own imagination. I am suggesting no such thing. You talk about strawmen? Literally what you said can be viewed as an aspect of deception at it's finest. I literally in no way suggested what you accused me of suggesting. Accusatory language is offensive. Just attack the argument... don't use words like "strawman" to accuse people of being deliberately manipulative here. We both believe what we're saying, no need to accuse someone of an ulterior agenda when ZERO motive for one exists. What I am suggesting here is that there is an EXAMPLE of a statically typed language that is FAR less safe and FAR harder to debug then a dynamically typed language (C++ and python). This EXAMPLE can function as evidence for the fact that static type checking is not a key differentiator for safety or ease of use or ease of debugging. >Debugging is in fact usually easier because you can rule out the type errors that can't happen. You don't get it. Type errors that happen at runtime or compile time contain the same error message. You get the same information. Therefore you rule out the same thing. Type checking is only doing extra checking in the sense that it checks code that doesn't execute while runtime checks code that does execute. Python was programmed with sane error messages and runtime checks that immediately fail the program and gives you relevant logic about where the error occurred. This is the key differentiator that allows it to beat out a language like C++ which has none of this. C++ does have static type checking but it does little to make it better then python in terms of safety and ease of use.
- jejones3141 4y ago> If you have errors in your program, does it matter that much if those errors are caught during runtime or compile time? The passengers on the fly-by-wire jet running the program might well say that it matters.
- deltasevennine 4y agoWell there's an irony to your statement. Those programmers who write embedded systems (I'm one of them) tend to use C++. C++ lacks memory safety and has segfaults, python doesn't. They literally used the most unsafe programming language ever that literally doesn't even alert you to errors either at compile time or runtime. C++ is chosen for speed. Not for safety. The amount of run-time and compile time checks C++ skips is astronomical. The passengers may think it matters, but the programmers of those systems by NOT using a program that does compile time or run time checks are saying it doesn't matter.
- xigoi 4y ago> Why does 100,000 lines of code of python tend to be safer and more manageable then 100,000 lines of C++ despite the fact that python has no type checker and C++ has a relatively advanced type checker? Because C++ sucks, but static types are not to blame for that.
- deltasevennine 4y agoMy point here is that static types didn't do much to improve C++. We should be focusing on what made C++ bad. The things that made C++ bad and the fixes for those things are what makes python Good. I'm saying type checking is not one of those things.
- xigoi 4y agoWell, I personally find Python much more pleasant to code in when using type annotations and MyPy. Have you tried that?
- deltasevennine 4y agoOf course. I'm a python guru. I know the python type annotation inside and out. I'm a type nazi when it comes to writing python. That's why I know exactly what I'm talking about. I can unbiasedly say that from a practical standpoint the type checker simply let's you run and the "python" application less, and the "mypy" application more. Example: def addOne(x: int) -> int: return x + 1 addOne(None) The above... if you run the interpreter on it, you get a type error. Pretty convenient, you can't add one to None. But if you want to add type checking you run mypy on it. You get the SAME type error if you run mypy. They are effectively the same thing. One error happens at runtime the other happens at before runtime. No practical difference. Your manual testing and unit testing should give you practically the amount of safety and coverage you need. Keyword here is "practically." yes type checking covers more. But in practice not much more.
- xigoi 4y ago> No practical difference. For a simple example like this, no. But consider this: def add_one(x: int) -> int: return x + 1 data = load_huge_database() expensive_computation(data) add_one(None) MyPy will show you the error instantly. Python, on the other hand…
- za3faran 4y agoYou shouldn't compare a Python web stack with a C++ web stack, as C++ and Python target very different use cases. You can compare however with a Java or C# web stack, both of which offer a superior developer experience, as well as a superior production experience (monitoring, performance, package management, etc.).
- deltasevennine 4y agoThe comparison isn't happening because everyone is getting caught up in some language war. I compare C++ and python because I'm trying to make a statement about types. How types are actually not as important as people think. C++ and python are good examples because python is safer and easier to use then C++ yet python doesn't have type checking.
- throwaway2037 4y agoI would not use C++ in your comparison. Try with C# or Java. Not even close. They will crush in developer productivity and maintenance over Python, Ruby, Perl, JavaScript.
- deltasevennine 4y agoFirst off python now has types (you can place type annotations on the interpreter and run an external type checker) and javascript people use typescript. In terms of type safety i would argue python and javascript are now EQUAL to C# and Java. Developer productivity in these scripting languages is also even higher. Simply because of how much faster they are to program in with the code then run/test loop. Java and C# can have loong compile times. Python and typescript are typically much much more quicker. With the additional type safety python and typescript are actually categorically higher in developer productivity then C# or Java. But that's besides my point. Let's assume we aren't using modern conventions and javascript and python are typeless. My point is that whether or not C# or java crushes python and javascript over maintenance it doesn't win because of type checking.
- throwaway2037 4y agoYou wrote: <<Java and C# can have loong compile times.>> Yes, for initial build. After, it is only incremental. I have worked on three 1M+ line Java projects in my career. All of them could do initial compile with top spec desktop PC in less than 5 mins. Incremental builds were just a few seconds. If your incremental build in Java or C# isn't a few seconds, then your build is broken. Example: Apache Maven multi-module builds are notoriously slow. Most projects don't really need modules, but someone years ago thought it was a good idea. Removing modules can improve compile time by 5x. I have seen it with my own eyes.
- deltasevennine 4y ago><<Java and C# can have loong compile times.>> Yes, for initial build. After, it is only incremental. I work with C++ currently. Even the incremental build is too slow. Also eventually you have to clear the cache for various reasons including debugging, a new library, etc, etc/ 1M line python is 0s compilation time. You hit the runtime section instantaneously. Go was created with fast compilation times to get around this problem. I would say in terms of compilation, go basically is the closest in terms of the python experience. Basically when things are fast enough "5x compilation time" isn't even thought about because things are too fast to matter anyway. Go hits this area as well as python (given no compilation)