Live data from Hacker News

A guide to closures in Rust

hashrust.com

21–30 of 102 posts

Re: A guide to closures in Rust

#21

Earlier quoted context omitted.

It would’ve been trivial to make the language disallow nil, separate goroutine address spaces, crash the process on unhandled panic in any goroutine, etc. The reason Go annoys people is the unforced errors. Sure, it gets a lot right. But what it gets wrong had solutions long before Go existed and those solutions were wilfully ignored.

> It would’ve been trivial to make the language disallow nil Which would interfere with Go's philosophy that zero should be a valid (usable) state for types. What would be the default value of a reference type without nil? > separate goroutine address spaces This is not trivial to implement. The only way I can think of is to start each goroutine in a new process, which brings along other downsides - everything must b…

>Which would interfere with Go's philosophy that zero should be a valid (usable) state for types. What would be the default value of a reference type without nil?

... but nil is not actually a usable reference. You can't do anything with it that you can do with a real reference.

The whole zero values for every type might seem neat philosophically, but never struck me as sensible.

Re: A guide to closures in Rust

#22

The content is interesting but the use of ligature really put me off guard at first, and I am very familiar with Rust. I cannot imagine it being good for beginners to grok its syntax. This has reminded me of https://news.ycombinator.com/item?id=35925821 recently reposted, which boils down to: > if you’re preparing your code for others to read—whether on screen or on paper—skip the ligatures.

Yeah I think the ligature debate is a bit tiring frankly but one place where putting ligatures is very clearly a bad idea is in code examples. A blog is not my IDE, I can't turn them off and even worse I don't even know they are on! Can you use a unicode arrow for Rust closures? Is that what this is? I don't know!

Re: A guide to closures in Rust

#24

Earlier quoted context omitted.

> It would’ve been trivial to make the language disallow nil Which would interfere with Go's philosophy that zero should be a valid (usable) state for types. What would be the default value of a reference type without nil? > separate goroutine address spaces This is not trivial to implement. The only way I can think of is to start each goroutine in a new process, which brings along other downsides - everything must b…

Sum types let you have default values without pervasive nil. That’s not new either, it’s been done since at least ML. Separate address spaces are trivial when you have a runtime, just look at Erlang. Go could’ve also copied Erlang’s supervision trees to ensure safe and bounded goroutine lifetime. For all their impressive achievements, Go’s creators suffer from extreme NIH syndrome. Just look at Plan 9.

When you see the performace of Erlang, you understand why Go did not want to go this way.

Re: A guide to closures in Rust

#25

Earlier quoted context omitted.

"And sure, plenty of people will tell if you do it "right" you'll have no issues." My answer to that is always that if you are able to do it right in C or C++ (and maybe golang) you should not run into any issues with Rust. Especially you should not ever have to fight to borrow checker because it does the job you should be doing as a C/C++ programmer in your head anyway.

> Especially you should not ever have to fight to borrow checker because it does the job you should be doing as a C/C++ programmer in your head anyway. It adds mental overhead. I don't even like the "const" qualifier for functions in C++. It is so hard to get a design right upfront when thinking about non trivial 'const'-chains.

> It adds mental overhead.

The borrow checker removes the mental overhead of borrow-checking. You don't have to do it by yourself, you can lean on the borrow-checker to do that for you. In C++ you're all by yourself. You may pretend you don't need to do it, but you will run into troubles pretty fast.

Re: A guide to closures in Rust

#26

I had a hard time with closures when doing async programming. Is that something one should avoid?

Async code is hard to reason about. Async closures is what I like most about JavaScript (JS) though. Because JS pass all variables by value they get frozen in time when passed to a function. This make async code easier to reason about, as all variables are immutable.

Re: A guide to closures in Rust

#27
> let add_closure = |a, b| a + b; let sixty_six = add_closure(42, 24);

Woah woah, how did it not occur to me that I could just…construct a closure that directly in Rust? This feels like one of those “incredibly obvious and reasonable in hindsight” things. I don’t know why I was labouring under the assumption they could only be invoked in very special and specific places, but it’s good to know I was wrong.

Re: A guide to closures in Rust

#28

Earlier quoted context omitted.

> Especially you should not ever have to fight to borrow checker because it does the job you should be doing as a C/C++ programmer in your head anyway. It adds mental overhead. I don't even like the "const" qualifier for functions in C++. It is so hard to get a design right upfront when thinking about non trivial 'const'-chains.

> It adds mental overhead. The borrow checker removes the mental overhead of borrow-checking. You don't have to do it by yourself, you can lean on the borrow-checker to do that for you. In C++ you're all by yourself. You may pretend you don't need to do it, but you will run into troubles pretty fast.

Moving stuff into a closure is a perfect example of that. Try to capture an arcmutex to a bunch of threads in a closure? The compiler will note that arc can't be copied and to try moving it. It will then say you are trying to move the same arc to multiple threads, so you clone the arc. And if you try to just use an Rc it will tell you that can't be sent between threads (not thread safe) use arc instead. Those messages can absolutely guide you a long way before you realize your whole concept won't work, and that is frustrating, but those steps usually make you understand the whole issue.

Re: A guide to closures in Rust

#30

I had a hard time with closures when doing async programming. Is that something one should avoid?

I may be biased because I generally avoid closures entirely (I prefer the certainty over ownership and type signatures that traditional functions give), but I do my best to avoid closures when working with async in Rust. A lot of examples for frameworks will make use of async closures, and I typically convert those to functions as quickly as possible, which can be tricky the first time because of the elided types.
Post reply on HN