6 ms·
Nibbles of Rust – Restructuring Patterns
- cinericius 4y agoSince the author mentions at the end that they were motivated to write and publish this as a part of a writing group, I'd like to say that this was a very pleasant read. Tightly-scoped but insightful and informative!
- Monadic-Cat 4y agoThanks! (Post author. I made an HN account to reply here, haha.)
- juancampa 4y agoI don't understand why go through the complication of giving this a new name (i.e. "Restructuring Pattern") where the second explanation seems more intuitive and correct. "Restructuring Pattern" sounds like you can put back together a struct from its constituents, but that's done by normal struct instantiation.
- fkcgnad 4y agoThe author is talking about restructuring syntax in the destructing match. 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.
- ebresafegaga 4y agoThis sounds like view patterns in Haskell / active patterns in F#
- pflanze 4y agoThe author talks about adding structure, and I've been puzzled about what they are talking about until realizing that they apparently mean that a reference to something is "more" than the something hence it "adds structure". That doesn't make sense to me. More structure is if there are more elements in the data (more fields in a struct, or more alternatives in an enum), whereas a reference is just an indirection of access. Or am I missing something?
- clord 4y ago&T, &mut T, and T are all different types in a sense. Hence ref is transmuting types during restructuring. 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
- fkcgnad 4y ago[dead]
- bobbylarrybobby 4y agoI think it's “more” in the same sense that Some(x) is more than x. You can destructure &x in exactly the same way.
- cstrahan 4y agoThe set of all &T is larger than the set of T. 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.
- rtpg 4y agoNice tip. 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)
- spease 4y agoYou mean like ‘matches!’? https://doc.rust-lang.org/std/macro.matches.html https://doc.rust-lang.org/std/macro.matches.html
- rtpg 4y agoWhat I want is.. 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
- ljsb 4y agoYou were pretty close with your hypothetical syntax! You can write: let Some(y) = x else { do_stuff(); return }; I think it was a fairly recent addition to Rust.
- rtpg 4y agoThank dog for that. I feel like I even read the release notes for that but it was while I hadn’t been touching a specific codebase with loads of early returns. Thanks for pointing this out!
- 4y ago
- fmiras 4y agonice reading!
- lloydatkinson 4y agoI think there needs to be a "center the page" browser extension because this is just absurd: https://imgur.com/a/HZqaA4V https://imgur.com/a/HZqaA4V
- muattiyah 4y agoI always thought it was weird when people have websites like this, anyways, for those phased away and want to read this article while centered, execute in the console: document.getElementsByTagName('body')[0].children[0].style.margin = '0 auto';
- lloydatkinson 4y agoThat's a good tip! I also think its just as weird when sites have zero links to their home page. On what planet is "go to the address bar and delete the last part of the url and hit enter to go to the index" good user experience?
- Monadic-Cat 4y agoAgreed. It was a good tip. 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 ;)
- Monadic-Cat 4y agoI'll go ahead and promise to leave the '#wrapper' id on that element in my blog template, so this can be shortened to: 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 https://add0n.com/stylus.html) to do CSS, so you could write it like this: #wrapper { margin: 0 auto; }
- 4y ago