6 ms·
I was anyway thinking that his example looked incomprehensible, but your Python example makes a complete mockery of it. The difference is night and day, I'm di
by blub 8y ago
I was anyway thinking that his example looked incomprehensible, but your Python example makes a complete mockery of it.
The difference is night and day, I'm dismayed at how horrible that C++ code is, hope I never have to deal with such crap.
- Sharlin 8y agoThe big difference is that it's a pure library solution in C++. The code inside main is not too bad once you have the building blocks in place (implemented in a library, of course, not by yourself).
- mehrdadn 8y ago> but your Python example makes a complete mockery of it. I mean, try getting the same kind of performance and static verification in Python? So much of the complexity of C++ is due to the static typing and the optimizations that can come with it. If you're willing to give up and make everything dynamic then of course it'll simplify your code, but you get a massive penalty both in terms of performance and in terms of error-checking.
- Sharlin 8y agoUpvoted, but to be fair, Rust shows that expressiveness and performance aren't mutually exclusive. It does not (currently) have language-level list comprehensions, but those could be easily enough implemented as simple syntactic transformations over the existing iterator combinators, the way Scala does it.
- mehrdadn 8y agoThanks, yeah, I was very careful to avoid claiming they're mutually exclusive. However, although I stopped trying to learn Rust back in 2016, unless it's changed its fundamentals radically (which I understand it hasn't), I'm not sure if it's really a counterexample here for expressiveness. Can you use different allocators for different vectors in the same function in Rust? Can you have custom move semantics for objects that might know about pointers to them? And does the compiler no longer complain about code that really should work just fine? [1] I understand the answers to most if not all such questions is still "no", at which point I stop believing it really has the same flexibility as C++ or the same ease of writing as Python, but would be happy to hear if things have changed. [1] http://softwaremaniacs.org/blog/2016/02/12/ownership-borrowing-hard/en/ http://softwaremaniacs.org/blog/2016/02/12/ownership-borrowi...
- couchand 8y ago> And does the compiler no longer complain about code that really should work just fine? In the general case that's theoretically impossible, and also not really a good measure anyway.
- mehrdadn 8y agoOkay, how about in the practical cases that actually come up and make you have to work around the compiler?
- Sharlin 8y agoNon-lexical lifetimes, which were just recently stabilized [1], make many of the most common cases of borrow checker frustration "just work". And now that the groundwork is done, even more cases will likely be supported in the future. [1] https://rust-lang-nursery.github.io/edition-guide/rust-2018/ownership-and-lifetimes/non-lexical-lifetimes.html https://rust-lang-nursery.github.io/edition-guide/rust-2018/...
- mehrdadn 8y agoConfused, how are these common use cases, and how is this "just working"? In both examples on that page there is an unused variable (seems rare to do intentionally?) and in the second case where one of them is used, it seems they just elaborated the error message.
- staticassertion 8y agoA common use case might be something along these lines: https://play.rust-lang.org/?version=stable&mode=debug&edition=2018&gist=7929c7ee98bf530888173d51a71f96a1 https://play.rust-lang.org/?version=stable&mode=debug&editio... While the `entry` API provided an ergonomic, more performant way to do this, this is an example of a common pattern one might expect from other languages that, until recently, did not compile. NLL and other ergonomics improvements have helped a lot with these paper-cuts.
- blub 8y agoThe terrible thing about the C++ and Rust solutions is that one needs to understand many idioms and quirky syntax choices in order to comprehend what's going on. In Python it's blindingly obvious what is happening: one is creating a group of 3 values, where the values are in specific ranges if a certain condition is met. Itertools.count() is perhaps opaque, but otherwise this is literally how the code reads! Rust is already going into the weeds after the first '=' with its flat_maps and (1..) = c, whatever the heck that means and the C++ code is not even worth talking about. Performance is not an excuse, since loops can solve this with good performance and probably the best readability.
- DougBTX 8y ago> and (1..) = c, whatever the heck that means The 1..=c is Rust syntax for an inclusive range. Rust also has syntax for ranges that exclude the last value like Python’s range(1, c + 1), which is 1..(c + 1). Using that would make it look more like the other examples, though since the language has syntax for the idea “1 to c inclusive”, it makes sense to just use it. For comparison Ruby uses a..z and a...z for inclusive and exclusive ranges respectively. I like that Rust’s inclusive range is more visually distinct, and I can see why they went for a symbol that implies the last element “equals” another value, but it does look unusual at first glance.
- mclehman 8y agoThis exact thing is one feature I like about Perl 6 and (minorly) dislike about Rust. In P6, 1..10 is exactly the range you'd expect, while ^ is used to exclude either end of the range. For example, 1..^11 is the same as 1..10, as is 0^..^11 (can't say I've ever needed that, but I could see a couple of possible uses). This also carries over into range syntactic sugar. ^10 is shorthand for 0..^10, and as a result ^@list.elems is a list of valid indices of a list. I personally find Rust's syntax noisier, but it's a small issue.
- mehrdadn 8y agoA downside of 1..10 is, how do you represent an empty range starting from 1? 1..0? That looks so weird... I'd expect it to mean a backward range starting from 1 and going up to 0 inclusive. A nice thing about end-exclusive notation is you can denote backward ranges, forward ranges, and empty ranges with the same notation.
- peheje 8y agoI'm not sure about the specific code sample, but take a look at Nim. It's python syntaxy but 'fast' and compiled.
- mehrdadn 8y agoThanks, I've heard good things about it! I tried for a bit but then had to do other stuff, but I'll finally have to dig into it at some point... just haven't managed to bring myself to make the full investment.
- philwelch 8y agoIf you want static typing and better performance than Python, there’s still Java and Go.
- hellofunk 8y agoThe trade-offs between the two languages are so huge, and you seem unaware of what those trade-offs are.