soooooo I had this like, weird structure in Rust that was a struct that held an Option> and I used a match statement on the From implementation to determine whether it was a 'real' instance of the struct that contained all the real values, or whether i...
-
@[email protected] well, actually, I only have to unpack the ones I want, which isn't too bad but in this case I want literally all of them.
-
Xandra Granade 🏳️⚧️replied to Asta [AMP] last edited by
@aud Is it possible to use the @ operator to name the match pattern, `Foo { .. } @ foo` or something?
-
Asta [AMP]replied to Xandra Granade 🏳️⚧️ last edited by [email protected]
@[email protected] hmmm... so hilariously I didn't realize that operator existed
(me earlier: "time to put Rust on my CV!")
But also... I'm not sure it does work here, although I'm still playing around with it. I can definitely use it but it doesn't seem to match what I want (which is basically packing all the internal struct fields into a variable).
https://doc.rust-lang.org/beta/book/ch18-03-pattern-syntax.html
The use case they have there (search for bindings) is definitely useful, although not quite what I'd like in my case.
What I would like is something like this:
(where Object has a field called id). This doesn't seem to work. Neither does:match self { Object::Object { obj } => { if obj.id.is_some() { ds.field("id", &self.id().unwrap()); }
that one is sort of easy; I'm just like... pointing to the struct variant rather than a real thing. But even if I try and add anything such as...match self { obj @ Object::Object => { if obj.id.is_some() { ds.field("id", &self.id().unwrap()); }
The error complaining aboutmatch self { obj @ Object::Object { .. } => { if obj.id.is_some() { ds.field("id", &self.id().unwrap()); }
obj
just pointing to a struct variant goes away, but I still can't access the fields.
I'm guessing I have little choice except to basically unpack all the struct fields.
Still, really cool stuff with the@
operator. -
@[email protected] ... also ignore all the unclosed braces. hah.
-
Xandra Granade 🏳️⚧️replied to Asta [AMP] last edited by
@aud I apologize for the distraction, but is there a bit you can throw into a pastebin or Rust Playground or something? I'm really curious now, you've kind of nerdsniped me with this!
-
Asta [AMP]replied to Xandra Granade 🏳️⚧️ last edited by
@[email protected]
sure! Just gimme a second here... -
@[email protected] https://play.rust-lang.org/?version=stable&mode=debug&edition=2021&gist=69b24bbfcad69237ac308502691c0eb6
Okay! That's a cut down version of what I'm working on
(normally I never use the termObject
in a program, ever, for a trillion reasons, but this is from the ActivityStreams stuff I'm doing and there areObjects
everywhere) -
@[email protected] The 'goal' here (because my real
Object
has like, 33 fields) would be to not have to write something like:Object::Object { _contextAndType, id, attachment, attributedTo, audience, content, context, contentMap, name, nameMap, endTime, generator, icon, image, inReplyTo, location, preview, published, replies, startTime, summary, summaryMap, tag, updated, url, to, bto, cc, bcc, mediaType, duration, _extra, _extends }
in the match statement, but instead something much more concise -
@[email protected] Not only is this rather unreadable (I want readable code!) because it's just a lot, but maintenance would be a nightmare (not that I expect ActivityPub/ActivityStreams to change)
-
Xandra Granade 🏳️⚧️replied to Asta [AMP] last edited by
@aud `fucksticks`, I love it! Thanks for posting that, I'll go take a look (she said, as a form of procrastination and sharing in something cool with adjacent nerds).
-
Asta [AMP]replied to Xandra Granade 🏳️⚧️ last edited by
@[email protected] thanks. I usually use song lyrics when I'm in a professional setting (or silly movie quotes; pretty sure I wrote a unit test at Cray that used lines from Blade Runner just because I could)...
... but here, it's fuck all the way! Interestingly, I'm still at only 5 instances of the word "fuck" in the codebase. -
Xandra Granade 🏳️⚧️replied to Xandra Granade 🏳️⚧️ last edited by
@aud Oh, I see the problem, yeah. The enum case is a struct variant, but that struct isn't its own named type. That makes it impossible to name in a pattern, since a match to that pattern then wouldn't have a type at all.
There was some discussion in RFCs for making enum variants types in their own right (https://github.com/rust-lang/rfcs/pull/2593#issuecomment-823429982), and I seem to recall there being a crate that had a macro for doing that...
-
Xandra Granade 🏳️⚧️replied to Xandra Granade 🏳️⚧️ last edited by
@aud It's a bit ugly, but if you define the struct externally to the enum, then the patterns work out great.
Rust Playground
A browser interface to the Rust compiler to experiment with the language
(play.rust-lang.org)
-
Asta [AMP]replied to Xandra Granade 🏳️⚧️ last edited by
@[email protected] aha! Yeah, I briefly did that... then realized it messed with my elegant change from earlier and would require rewriting the other functions
It's sort of a balance, isn't it, between getting as much out of the type system as possible and also retaining flexibility. As an unrelated example, in this code, currently anything that extends fromObject
in ActivityStreams (which is like 99% of it) is ... well, anObject
. I'm like... well, I didn't really retain much benefit from the type system in this case, did I.
I see why other crates have done it with traits now, but my brain just still kind of hates it and I think it makes it a lot harder to grok both the code and the ActivityStreams objects themselves.
I hardly think it's a code requirement, but I don't think you could easily learn ActivityStreams from the crates I've seen thus far. I would like for my own code to be able to do that for someone, however, if possible. I guess that's why I'm torturing the type system like this. -
Xandra Granade 🏳️⚧️replied to Xandra Granade 🏳️⚧️ last edited by
@aud @yosh's blog post on state machines from a few years ago goes into that a bit as well: https://yosh.is/writing/state-machines
-
Xandra Granade 🏳️⚧️replied to Asta [AMP] last edited by
@aud There does in general seem to be a bit of a mismatch between the JavaScript everything-is-a-dict kind of view and the much more strongly typed view that Rust takes.
Shit like C# gets around it by using open-ended polymorphism, but it's surprisingly nontrivial to just write down what the type of a JSON object *is*.
-
Xandra Granade 🏳️⚧️replied to Xandra Granade 🏳️⚧️ last edited by
@aud Bonus points if you can somehow avoid `dyn` in writing that type.
-
Asta [AMP]replied to Xandra Granade 🏳️⚧️ last edited by
@[email protected] @[email protected] Okay, SO, a couple paragraphs in and I'm realizing I've actually done some of this before
(one of my biggest issues with a non-CS background is sometimes I'm missing key vocab terms despite understanding the concept)State machines not only encode which transitions are valid, in doing so they also encode which transitions are invalid.
I actually did a whole huge ass graph like this back at Cray where the transition between states had a defined syntax and represented alterations to an underlying matrix. Being able to reword this in the language of state machines would be useful. But also, now I'm sort of starting to understand some @[email protected] 's excitement for parsers because I found it immensely satisfying to work out the proper mathematical rules for transitions and implement them.
I should read more, here... -
Xandra Granade 🏳️⚧️replied to Asta [AMP] last edited by
@aud @yosh @hipsterelectron The downside to having a mixed CS/physics background is being able to bore everyone with useless pedantry, even if that "pedantry" is just a useful set of structures for my brain to think in. But I digress.
-
Asta [AMP]replied to Xandra Granade 🏳️⚧️ last edited by
@[email protected] Yeah, I suspect there's some dyn going on. I considered it.
I was trying to come up with the schema I've used here and all I can think of is de-heritance or out-heritance. I can't decide if I love it or hate it, but I also realized it's absolutely applicable even when you don't know all the possible children you'd want to create.
https://codeberg.org/Astatide/satyr/src/commit/667664b2e6d62bafb574459cce6cc2da65ac5384/src/primitives/activity_streams/extended/mod.rs#L117
It's basically an enum map of all the ActivityStreams types that inherit from Object (with some imperfections and kludges here and there).