News for hackers. Stuff that matters.
Re:Writing Pythonic Rust by bsder on Monday May 24, 2021 @06:08PM (#27270276)
I get why its unsetlling. I hear you, too.

The issue in Rust is that "spawn" is generally the first time that a programmer is forced to confront closures--before that they can completely ignore them.

It is a quirk of Rust that someone who "just wants to spawn a thread" suddenly gets all this language overhead dumped on them in a block.

Re:Writing Pythonic Rust by saghm on Monday May 24, 2021 @06:21PM (#27270373)
What about iterators? My instinct is that people would run into wanting to use `map` or `filter` or something before they feel the need to spawn threads when using a new language, although that might be my bias coming from a more functional background before learning Rust. The types of closures used as predicates tend to be a lot simpler though, so I guess this may not be what you mean by "confronting" them.
Re:Writing Pythonic Rust by bsder on Monday May 24, 2021 @06:43PM (#27270548)
Iterators? Nope. You can happily live in "for x in foo" land without ever touching map/filter/collect.

> might be my bias coming from a more functional background before learning Rust

This is exactly the problem. The people I'm dealing with are coming from "imperative land" and haven't had a functional background. Someone stepping up to Rust as "C with memory safety" does not have any of that functional background.

Please do remember that a "closure" is built on a lot of prior abstractions. What is a "scope"? What is "variable capture"? What is "heap" and "stack"? Why does that matter here and not normally?

No programming language is only used by experts, and Rust is no exception.

The issue is that "spawn" smacks you with a bunch of that baggage all at once.

Re:Writing Pythonic Rust by scoutt on Tuesday May 25, 2021 @03:55AM (#27274105)
Yes! That time I wanted to learn Rust every time I saw a complicated closure my mental parser/linter crashed (from a lifetime C developer PoV).

I don't understand how a function that is defined in-place is more clear than a nice function on its own. Perhaps because it gives a sense of continuity (like in async code), but man, it's really painful to read (at least to me). In fact, if I have to write some Rust right now, all my closures would be defined elsewhere, whenever possible.

Re:Writing Pythonic Rust by nicoburns on Monday May 24, 2021 @07:00PM (#27270683)
I guess someone coming from only C might not have encountered closures, but most languages have them these days (modern javascript code uses them everywhere), and I don't think they should be considered especially advanced. "How do closures work?" Was a question I was expected to know how to answer when going for my first ever junior programming job with zero professional experience (and no CS degree either).
Re:Writing Pythonic Rust by saghm on Monday May 24, 2021 @07:06PM (#27270743)
Someone coming from C also would certainly know about the difference between the stack and the heap too, so it's a little strange to me that GP called that out
Re:Writing Pythonic Rust by bsder on Monday May 24, 2021 @07:18PM (#27270842)
Why?

A lot of embedded code NEVER calls malloc (thus the need for no_std in Rust). Consequently, you can go a long way in embedded without really knowing the difference between stack and heap.

"Embedded programmer" does not imply "Linux Kernel Hacker".

Re:Writing Pythonic Rust by throwaway894345 on Monday May 24, 2021 @08:42PM (#27271451)
There’s a pretty wide chasm between kernel hackers and people who have used malloc before. :) And an embedded programmer ought to have the ability to intuit (a naive) malloc on their own (you can have malloc without a kernel).
Re:Writing Pythonic Rust by gbear605 on Monday May 24, 2021 @06:39PM (#27270526)
Map/filter closures almost always never actually enclose variables, instead just acting on the elements from the iterator. They’re basically a one-off nameless function. On the other hand, closures used for spawning threads almost always enclose variables from the outer context. That’s an important distinction that makes them seem quite different even if they’re the same underneath.

When I started with Rust, I actually thought that the common

spawn(|| …)

syntax was something special, not just a closure with no variables.