Nibbles of Rust – Restructuring Patterns
catmonad.xyz
catmonad.xyz
I honestly am a bit frustrated with Rusts pattern matching ergonomics, cuz it ends up requiring me to introduce indentation in places where I don’t want it, mainly to futz around with unwrapping structures or the like.
Lots of helper methods exist on standard library enumerations but I really want there to be some nice built in macros to just give me the innards when I need it, and have a control flow block for when I _cant_ pattern match (and thus want to do an early return or blow up). Maybe this already exists!
Too much indentation makes languages unfun (see every lisp struggle with this with name binding)
let MyEnum(foo, bar, baz) = input but otherwise { do some stuff return some value }
Point being I don’t have to check for MyEnum-ness twice (like with matches! + if let) and the indented code is for the exception (no match) not the norm.
Tho I … guess !matches(MyEnum{ .. }) is not the worst… but it’s annoying to have this pattern all over my code instead of as some encoded concept we all use
let Some(y) = x else { do_stuff(); return };
I think it was a fairly recent addition to Rust.Here the type being matched is:
enum Option<T> {
None,
Some(T)
}
let x = Some(42);
let Some(y) = x else { panic!("None") };"Restructuring Pattern" sounds like you can put back together a struct from its constituents, but that's done by normal struct instantiation.
Rust Has this with "match" but only via a single ref.
You would have to make alternative restructuring syntax to go into the match expression if you want it to work.
Hypothetically:
fn g(v: Option<i32>) -> Option<Option<i32>> {
match v {
Some(_Some(_Some(x))),
None(_None)
}
}
Any character with an underscore is a "restructuring" syntax here. Rust only does restructuring with references via the ref keyword and it only does it once per var per expression. The syntax I presented here is hypothetical of course.I would say it's more syntactic sugar as you can do the restructuring on the right side of the match expression. You can make up an entire functional language using this technique and eliminate the => and everything after it.
I largely agree with you that it's not exactly necessary to do this. Arguably it makes things harder to read.
Or am I missing something?
Really, they are adding a new view, so perhaps this is like Haskell lenses, where you can make views with a different type that acts on underlying data
Let’s consider the case where T is u8. There are 256 inhabitants of the u8 type (0u8-255u8).
Now consider &u8. Each u8 referent is still some value between 0 and 255, but the number of references you could have is dependent on the pointer width of your target system — let’s say 64 bits. So that’s 2^8 possible u8 values times 2^64 possible references, or 2^72 inhabitants. Well, minus one to account for null, and I’m probably missing other details, but you get the idea.
So going from T to &T introduces structure in the same sense that going from T to (T, U) does; and going from &T to T destructures in the same sense that going from (T, U) to T does. That structure may not be directly observable (as in the case of a reference: you’d have to go out of your way to observe the underlying address), but conceptually the structure is there nonetheless.
Edit:
Another way to look at it is this:
Consider a Rust “newtype”, like struct Days(u8).
If you pattern match on that to obtain the inner u8, we call that destructuring. Destructuring is to reduce or break down the structure of a thing, so the opposite must be building up structure, or “restructuring”. Therefore going in the opposite direction — stuffing a u8 value in a Days - must be restructuring. In this case both types have the same number of inhabitants (256); regardless, one direction is destructuring and the other direction is restructuring.
document.getElementsByTagName('body')[0].children[0].style.margin = '0 auto';My goal in leaving out the link to my home page was to make the Writing Gaggle home page more prominent than my personal blog. (I manage hosting both, see.) I only added my blog index page as an afterthought when I saw a ton of 404 errors on my server a few months ago because people were manually navigating to it.
I'll consider adding actual navigation to my page template though, so maybe you'll be less annoyed ;)
document.getElementById('wrapper').style.margin = '0 auto';
Though if you're in the habit of customizing sites you read, I'd personally recommend using a browser extension like Stylus (https://add0n.com/stylus.html) to do CSS, so you could write it like this: #wrapper {
margin: 0 auto;
}