Live data from Hacker News

Rust – A hard decision pays off

pinecone.io

221–230 of 386 posts

Re: Rust – A hard decision pays off

#221
post #173
post #142

Earlier quoted context omitted.

The thing is in Rust this is totally ok. Is NOT un-idiomatic to mix imperative + functional paradigms in the same block.

The first version isn't what I'd write in a purely functional language either, a recursive version would be much saner. Isn't recursion idiomatic in rust?

In addition to Steve's sibling comment, I'm responding narrowly to iterators versus for-loops. Recursion is out of scope.

Re: Rust – A hard decision pays off

#222

Earlier quoted context omitted.

Hah, it took me and a bunch of other people in the Rust discord a fair amount of time to figure out how to get the first example to compile correctly in the first place, and I find the “transpose()” business to be particularly convoluted. I think even Rust people would prefer the imperative version. I also suspect there’s some hindsight benefit at play in that it’s easier to make sense of the first snippet than it wa…

Honestly the closure + `transpose` is really ugly as sin. I had to do a double take and reason through the steps which you took to get that particular snippet (while not reading the imperative one).

Thanks, I feel validated. (:

Re: Rust – A hard decision pays off

#223

> Dev velocity, which was supposed to be the claim to fame of Python, improved dramatically with Rust. I don't doubt this in the least. I've been a professional Python developer for 15 years, and I can't believe Python ever had the reputation for "high dev velocity" beyond toy examples. In every real world code base I've worked in, Python has been a strict liability and the promise that you can "just rewrite the slow…

A lot of people seem to believe that dynamically typed languages make development easier, because you don't have to worry about writing type annotations or going through the extra steps to fix compile-time errors.

This is arguably true for small scripts, but for anything non-trivial I find that static typing means I can be more productive, because type errors are caught straight away (rather than potentially in production), and I can be much more confident in refactoring code because I know certain kinds of errors will be caught by during type checking. This doesn't remove the need for automated testing, but does reduce the number of test cases you have to write.

Things have improved a lot in the Python ecosystem of late with the introduction of type annotations and mypy, so to the extent possible I treat Python as if it's a statically typed language, putting type annotations everywhere and always making sure the codebase passes type checking before pushing a commit.

However, the fact that this is optional sadly means that not everyone does it, and if you're working with parts of a codebase written without this level of discipline, you're basically back to square one. I've come to the conclusion that for medium to large projects, dynamic typing encourages sloppy programming, because it doesn't force people to think as carefully about what exactly their data types are, and whether they're being used correctly.

Re: Rust – A hard decision pays off

#224
post #163

Earlier quoted context omitted.

I actually don't care as much for iterators as I thought I would. Beyond some simpler map().reduce() stuff they tend to fall over pretty fast, and I end up spending too much time trying to make iterator chains work before defaulting to for loops. I also dislike how anemic Rust's stdlib is. I'm sure there are good reasons, but I like that I can just reach for Go's stdlib for annotating errors or dealing with JSON. Oth…

Now, compare a parallel version of both.

It's not obvious to me that the parallel version of the first is going to be cleaner (or more performant) than a parallel version of the second, but even if it is, I don't agree with mangling (to put it nicely) single-threaded code on the off chance that it might be made parallel one day.

Re: Rust – A hard decision pays off

#225
post #134

Earlier quoted context omitted.

I would say in this case it's more the API designers' fault than Go's fault. Looks like the Python API is operating at a higher abstraction level than the Go API - using the Python API you can just call a "macro" that does everything required, in Go you have to call each operation individually.

Quoted post unavailable.

Can you please avoid flamebait comments and make your substantive points thoughtfully, per https://news.ycombinator.com/newsguidelines.html? We don't want flamewars here. Programming language flamewars are especially tedious.

Re: Rust – A hard decision pays off

#226
post #142

Earlier quoted context omitted.

The thing is in Rust this is totally ok. Is NOT un-idiomatic to mix imperative + functional paradigms in the same block.

Agreed, but I think people make too big a deal about iterators. The simple for loops that they’re fit to replace aren’t that hard to read or write, so they aren’t causing real problems, and on the more complex end you’re writing imperative stuff anyway. Iterators certainly aren’t a bad thing, but they’re not the game changer that Go-critics made them out to be in all of the Rust-vs-Go debates.

> Agreed, but I think people make too big a deal about iterators.

I may just have more time to dick around, but I've been forcing myself to write everything as an iterator in Rust (instead of a for loop) just to learn the paradigm and, honestly, it's been pretty great.

First, there is a performance impact. You may think this would be small, but, in my experience, it can be relatively large. There must be several reasons of which I am ignorant, but they probably include mutable no alias inside closures, bounds check elision, etc.

Second, there is a mutability advantage to just using filter/flatten/map/collect for 90% of your use cases.

Third, the more advanced iterator methods will cover the other 5-10% of your use cases, and will make your code much easier to read, once you understand how to use them (if you're trying to learning something/anything more complex at the same time, save your brain power!). I don't have a single traditional for loop in my personal projects.

My take on iterators is, for iterator/Rust beginners (like me!/perhaps not you) -- the best way to learn is to get it working as imperative code, and when you have the time, go back a rewrite as an iterator. In the beginning, it's super frustrating. But you'll get better and better and, after awhile, you'll much, much prefer writing as an iterator. You won't even think of using a for loop.

Re: Rust – A hard decision pays off

#227
post #212

Earlier quoted context omitted.

I disagree. Most startups that YC has funded that became successful (Series B or higher) were written in Python or Ruby. Now you can say that this is a tradeoff for post Series B, and for that I don't know. I've never worked on a massive Python mono-repo for a company that size. But I know what I've done in Python and, yes, it includes performance optimization in Numpy / Scipy / Cython, and other than Ruby, no other…

> I disagree. > Most startups that YC has funded that became successful (Series B or higher) were written in Python or Ruby. It depends on what your goal is. If you want to get rich off of VC money, Python and Ruby might be a good fit. If you, on the other hand, want to write good, performant, maintenable and (relatively) bug-free software, then there are better choices.

Dev teams that are unable or willing to properly architect and test their projects will end up with buggy and difficult to maintainable code regardless of language.

Re: Rust – A hard decision pays off

#228
post #134

Earlier quoted context omitted.

Docker is built with Go. Compare doing things with Docker api between Go and Python. I usually recommend people to "script" things with Go but I start to think that Go has to go... https://docs.docker.com/engine/api/sdk/examples/

I would say in this case it's more the API designers' fault than Go's fault. Looks like the Python API is operating at a higher abstraction level than the Go API - using the Python API you can just call a "macro" that does everything required, in Go you have to call each operation individually.

It probably is Go's propensity to return error values whereas Python would bubble them up. Every action in Docker involves an I/O error at a minimum (since you're talking to the Docker daemon) so this is basically a worst-case scenario for error handling boilerplate. I don't doubt that Python is better for scripting in this case, but if you want to make an application that interfaces with Docker, Go is probably the better of the two (despite its boilerplate). In fact, I vaguely recall running into a bunch of Python-related bugs in docker-compose (it was at an old gig, and I haven't used docker-compose since, so I don't recall the particulars).

Re: Rust – A hard decision pays off

#229
post #170

Earlier quoted context omitted.

I disagree. If I can avoid an index variable, I’m going to have less bugs since I won’t have to index.

I'm not sure what you mean. You don't have to deal with index variables in a for loop: for item in iterator { vector.push_back(foo(item)); } You're not explicitly indexing the source iterator or the destination vector at any point.

Agreed. That's why I enjoy iterators, and use them whenever possible. I think they're important.

Re: Rust – A hard decision pays off

#230

> Dev velocity, which was supposed to be the claim to fame of Python, improved dramatically with Rust. I don't doubt this in the least. I've been a professional Python developer for 15 years, and I can't believe Python ever had the reputation for "high dev velocity" beyond toy examples. In every real world code base I've worked in, Python has been a strict liability and the promise that you can "just rewrite the slow…

Dev velocity in Rust is directly proportional to how well you grok lifetimes and ownership.

Eh, I like Rust and started my career doing embedded C and C++, so I definitely "grok lifetimes" but I'm probably always going to be more productive with Go than Rust (for general app development, anyway) if only because I don't have to think about memory at all with GC (again, general app development, not talking about performance optimizations). Even if I do a bunch of unnecessary cloning + Rc/etc in Rust, I'm not going to move as fast as I would do in Go.
Post reply on HN