Live data from Hacker News

Rust's Block Pattern

notgull.net

21–30 of 121 posts

Re: Rust's Block Pattern

#21

I often employ this pattern in Ruby using `.tap` or a `begin` block. It barely adds any functionality but it's useful for readability because of the same reasons in the OP. It helps because I've been bitten by code that did this: setup_a = some_stuff setup_b = some_more_stuff i_think_this_is_setup = even_more_stuff the_thing = run_setup(setup_a, setup_b, i_think_this_is_setup) That's all fine until later on, probably…

Clojure also has the threading macro -> and ->> which are great at converting exactly the same type of code into a stream of modifications instead of breaking out everything into variables. Naming things can be very useful sometimes but sometimes it is entirely gratuitous and distracting to have

let input = read_input(); let trimmed_input = input.trim(); let trimmed_uppercase_input = trimmed_input.uppercase();

...

The extra variable names are almost completely boilerplate and make it also annoying to reorder things.

In Clojure you can do

(-> (read-input) string/trim string/upcase)

And I find that so much more readable and refactorable.

Re: Rust's Block Pattern

#22

More significantly the new variables x and y in the block are Drop'd at the end of the block rather than at the end of the function. This can be significant if: - Drop does something, like close a file or release a lock, or - x and y don't have Send and/or Sync, and you have an await point in the function or are doing multi-threaded stuff This is why you should almost always use std::sync::Mutex rather than tokio::sy…

oops: Of course the Mutex is Sync/Send, that's the whole point of a Mutex. It's the std::sync::MutexGuard that's not.

Re: Rust's Block Pattern

#23
Not mentioned in the article but kinda neat: you can label such a block and break out of it, too! The break takes an argument that becomes the value of the block that is broken out of.

Re: Rust's Block Pattern

#25

More significantly the new variables x and y in the block are Drop'd at the end of the block rather than at the end of the function. This can be significant if: - Drop does something, like close a file or release a lock, or - x and y don't have Send and/or Sync, and you have an await point in the function or are doing multi-threaded stuff This is why you should almost always use std::sync::Mutex rather than tokio::sy…

Can this also affect stack usage? Like if `x` gets dropped before `y` is introduced, can `y` reuse `x`'s stack space (let's assume they are same size/alignment). Or does the compiler already do that if it can see that one is not used after the other is introduced?

Re: Rust's Block Pattern

#26
post #24

I have one better: the try block pattern. https://doc.rust-lang.org/beta/unstable-book/language-featur...

I want that stabilized so bad but it's not been really moving forward.

I was not a fan when I first saw it but I'm becoming desperate to have it the more Rust I write.

Re: Rust's Block Pattern

#27
post #23

Not mentioned in the article but kinda neat: you can label such a block and break out of it, too! The break takes an argument that becomes the value of the block that is broken out of.

I just learned this one, and am gradually starting to use it! It applies for loops too. I saw it in ChatGPT code, and had to stop and look it up. Rust is a big language, for worse and for better.

Re: Rust's Block Pattern

#30
post #28

I have one better: the try block pattern. https://doc.rust-lang.org/beta/unstable-book/language-featur...

Why does this need special syntax? Couldn't blocks do this if the expression returns a result in the end?

One reason is that would be a breaking change.
Post reply on HN