Rust's Block Pattern
111–120 of 121 posts
Re: Rust's Block Pattern
#112 func foo(cfg_file string) (parsed, error) {
config := func() {
return json.Parse(cfg_file)
}
return config.parsed
}
All of these are however poor solutions to the problem, because they're not true nested functions — they can access arbitrary variables defined outside their scope. Python at least restricts their modification, but Go doesn't. I'm guessing in Rust it's at least explicit in some way?In any case, the real solution here is to simply allow proper nested functions that behave exactly like freestanding functions in that they can only access what's passed to them:
func foo(cfg_file string) (parsed, error) {
func config(cfg_file) config {
return json.Parse(cfg_file)
}
return config.parsed
}
This way you can actually reason about that block of code in isolation—same effect as when calling a freestanding function, except this doesn't expose the nested function to callers outside the parent function, which is valuable.Re: Rust's Block Pattern
#113Block expression https://doc.rust-lang.org/reference/expressions/block-expr.h... Also in Kotlin, Scala, and nim.
I think this comes from functional programming. I'd just call it "everything is an expression" (which isn't quite true in Rust but it's a lot more true than it is in traditional imperative languages like C++ and Python).
Re: Rust's Block Pattern
#114Earlier quoted context omitted.
I think this comes from functional programming. I'd just call it "everything is an expression" (which isn't quite true in Rust but it's a lot more true than it is in traditional imperative languages like C++ and Python).
The only things in Rust that are real statements are `let` statements, and item statements (e.g. declaring an `fn` inside a function). All other statements are in fact expressions, although some always return `()` so they're not really useful as such.
Re: Rust's Block Pattern
#115> This is why I generally avoid C’s “bottom-up” strategy for organizing code. I think the author misunderstood something....
Yeah, language choice and the way your organise your code seem orthogonal to me
Re: Rust's Block Pattern
#116Earlier quoted context omitted.
For the case where `try` is useful over the functional form (i.e. parent's situation of having a desired Result, plus some unrelated early-returning), that ends up with nested `Result`s though, i.e. spamming an `Ok(Ok(x))` on all the non-erroring cases, which gets ugly fast.
Why couldnt you flatten it?
Re: Rust's Block Pattern
#117Earlier quoted context omitted.
Variable shadowing felt wrong for a while because it's considered verboten in so many other environments. I use it fairly liberally in rust now.
It helps that the specific pattern of redeclaring a variable just to change its mutability for the remainder of its scope is about the least objectionable use of shadowing possible.
For example I feel this is right:
let x = x.parse()?;Re: Rust's Block Pattern
#118I love that this is part of the syntax. I typically use closures to do this in other languages, but the syntax is always so cumbersome. You get the "dog balls" that Douglas Crockford always called them: ``` const config = (() => { const raw_data = ... ... return compiled; })()' const result = config.whatever; // carry on return result; ``` Really wish block were expressions in more languages.
By the by, code blocks on here are denoted by two leading spaces on each line like this
Re: Rust's Block Pattern
#119Earlier quoted context omitted.
Wouldn't that also move any referenced variables too? Unlike the block example that would make this code not identical to what it's replacing.
No, unless you ask for it via the `move` keyword in front of the closure. This works fine: https://play.rust-lang.org/?version=stable&mode=debug&editio...
Re: Rust's Block Pattern
#120Earlier quoted context omitted.
So many options why oh why. let run with also apply
Each does different things, and Rust also has plenty of them. and_then(), or(), or_else(), then(), the list goes on. Kotlin just implements them more widely. Actually, Kotlin's with() and apply() are more powerful than what Rust can provide. Then again, Rust isn't designed with OO in mind, so you probably shouldn't use those patterns in Rust anyway.