6 ms·
C++ is one of the least Pythonic languages I know. It clashes with nearly every point on the Zen of Python[0], and C++'s "modern" libraries do nearly nothing to
by Veedrac 9y ago
C++ is one of the least Pythonic languages I know. It clashes with nearly every point on the Zen of Python[0], and C++'s "modern" libraries do nearly nothing to change that.
[0]: https://www.python.org/dev/peps/pep-0020 https://www.python.org/dev/peps/pep-0020
- dmix 9y ago> Beautiful is better than ugly. This one is the most apparent. Almost every example in the C++ v. Python in the article above the C++ version is notably uglier. Just look at Lambda expressions: Python def adder(amount): return lambda x: x + amount C++ auto adder(int amount) { return [=](int x){ return x + amount; }; } I'm assuming [=] is used to represent Lambda here? That seems like a strange syntactic choice to me. Edit: turns out there are various forms of Lambda (of course there wouldn't just be one in C++), for ex: [a, &b], [this], [=], [&], [] Depending on how the variables are captured. Capturing that additional complexity in a tight space is the cause of the ugliness here. http://en.cppreference.com/w/cpp/language/lambda http://en.cppreference.com/w/cpp/language/lambda
- gpderetta 9y agoAlso note that C++ needs the curly brackets because, differently from python, lambdas can contain arbitrary statements, not just one expression (one would use a local function in python). There have been discussions about adding a lighter syntax for single expression lambdas that doesn't require the curly brackets and the 'return' keyword, but so far no actual progress.
- swordfeng 9y ago[] marks the beginning of a lambda. In which declares whether variables are passed by value(=) or reference(&).
- marcosdumay 9y agoThat C++ line is very C++nic... It's much better specified, gives you much more power than the Python one, tells you exactly what is happening, is so short it's cryptic, and is ugly as hell.
- Veedrac 9y agoThat's excessively tame for C++. If you want to really see the difference, look at actual libraries. Tracing through libcxx is a lot of fun. Here's <optional>, for example. https://github.com/llvm-mirror/libcxx/blob/master/include/optional https://github.com/llvm-mirror/libcxx/blob/master/include/op...
- dmix 9y agoI'm sure there's plenty of uglier stuff on far bigger scales. But good design is all in the small details. Looking at this one small syntactic difference explains a lot about why C++ is as ugly as it is. It has to pack in a lot of complexity everywhere, even at the most basic level, such as how to label a lambda expression. The ugliness may simply be a cost of offering much more power (simplicity is difficult/impossible when you need to support complex base abstractions). But it's still ugly. And therefore a big reason why it's not very Pythonic as the OP said.
- smitherfield 9y agoMost of the ugliness there is coming from using "__"-prefixed identifiers (reserved for implementations) and macros hiding code specific to certain platforms or versions of the standard.
- Veedrac 9y agoEven if those weren't directly caused by flaws in C++, a find/replace to remove "__"s and the five conditional macros does little to make this code less complex.
- amelius 9y agoBut Python 2.7 has this problem: def f(): x = 0 def add(amount): x += amount # UnboundLocalError: local variable 'x' referenced before assignment add(10) add(20) add(30) return x print f() In C++, this problem doesn't exist.
- dmix 9y agoThe question is the cost of supporting it (assuming this is a problem needing fixing) as it has far reaching implications in all of the added complexity to all the abstractions layered on top of it. I'm not making a good/bad argument that one is better than the other. The two languages have widely different usecases and rationale in the language design. But I'm not convinced C++ is (or can become) very Pythonic given the complexity it must support at all the basic levels.
- deleted 9y ago[deleted]
- js2 9y agoThis is fixed in Python 3 with the nonlocal keyword. In Python 2, the idiomatic work-around is to have x be list of one item: def f(): x = [0] def add(amt): x[0] += amt add(10) return x[0]
- Veedrac 9y agoPython 3 release date: 3 December 2008 C++11 release date: 12 August 2011
- amelius 9y agoTrue, but in C++ the problem never existed.
- ajross 9y agoLiterally everything you're complaining about is down to differences in abstraction and detail, not aesthetics. The stuff in square brackets is the capture list. Unlike python, which implicitly captures the full outer scope by reference, C++ allows/requires you to specify which outer variables you want to reference in the lambda, and whether they are captured by value ("=") or reference ("&"). This allows C++ to implement the lambda with a simple static function in most cases, where python needs a bunch of tracking data to preserve the outer stack from collection. The rest of it is all just following the existing syntax of the language: C++ uses curly braces where python uses bare expression. C++ is typed and requires an "int" declaration on the argument. C++ puts a semicolon at the end of its expressions. You don't have to like this per se, and you're welcome to call it ugly if you want. You're just 30-ish years late to the argument, though.
- dmix 9y ago> Literally everything you're complaining about is down to differences in abstraction and detail, not aesthetics. I'm not complaining. Just pointing out how it's notably uglier, a critical part of being 'Pythonic', which affects both aesthetics (emotional experience) and functionality. That's not a value judgement but an observation. Python is obviously more limited in power (functionality), which is a product of decisions made about base abstractions. That filters upwards and becomes apparent in both visuals and utility (and as a result learning curves, developer happiness, applicability to problem sets, etc).
- dragonwriter 9y ago"Ugly" is a subjective aesthetic judgment, not an observation.
- dmix 9y agoIf it's merely a consequence of choices made to support complexity then I disagree. The aesthetic and utility of the design is a product of many limitations and hard choices made early on. C++ will always be an ugly language because those trade offs were made from the beginning to support a breadth of functionality and configuration. Simplicity and accessibility are extremely challenging things to support when you have a product that does everything for everyone. The need for 5 different lambda expressions is a perfect example of that. I personally think C++ still has a role in the world, as it clearly has lots of adoption. But if you want non-Ugly then those various use-cases have to be broken up into single-purpose (or niche) languages such as Rust for systems programming and Python for 'scripting' and Lua for glue/config code. All of those languages listed have made hard tradeoffs to be good at certain things. C++ and Java did not - largely because they are "yes" languages, as Steve Yegge calls it (the language designers said yes to everyone early on). If Ugly languages were merely 'bad' or 'wrong' for being ugly then they both would be the most used languages. They clearly have long-lasting value in the industry - which people like Yegge believe is because they are okay with being ugly.
- deleted 9y ago[deleted]
- jcelerier 9y ago> It clashes with nearly every point on the Zen of Python I'd argue that C++ is more pythonic than Python. For instance: > Explicit is better than implicit. Since when is dynamic typing more explicit than static typing ? > Errors should never pass silently. Well guess what, with C++ they don't even pass compilation.
- mjburgess 9y agoSince dynamic typing and static typing are not the same thing. "Dynamic" doesnt mean hidden. It means types are features of objects at run time. "Static" doest mean explicit. It means types are rules the compiler applies to the program text.
- Veedrac 9y agoI've just been debugging/fixing a bunch of C++ code that was incorrect due to a bunch of implicit casts and normally-invisible undefined behaviour, neither of which would have been possible in Python. I am not convinced.
- disconnected 9y ago>> Errors should never pass silently. > Well guess what, with C++ they don't even pass compilation. int * a; *a = 5; Segmentation fault. Oopsy. To be fair, "g++ -Wall" does complain that "a" is not initialized. But it is a warning, not an error. (And don't tell me that "you are not supposed to use pointers". They exist, someone is going to use them and proceed to shoot themselves in the foot.).