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] 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). -
Asta [AMP]replied to Xandra Granade 🏳️⚧️ last edited by
@[email protected] @[email protected] @[email protected] ask me about how chemical symmetry, which forces chemists to learn group theory so they can understand how rotational symmetry and groups (and the operators that define certain rotation operations on the chemicals) can actually impact reactivity, has totally fucked my brain.
Super useful stuff though. It's why I can't ever let myself not be in love with operator overloads. -
Xandra Granade 🏳️⚧️replied to Asta [AMP] last edited by
@aud @yosh @hipsterelectron Oh, the abuses of operator overloading I've committed in the name of fun--- I mean, concise and readable notation.
(People get salty if you use & to mean the tensor product, even if there's no other better options available.)
-
Asta [AMP]replied to Xandra Granade 🏳️⚧️ last edited by [email protected]
@[email protected] @[email protected] @[email protected] I stand by my assessment that implementing operator overloads for the structures of a genetic algorithm to create both a programmatic and representational syntax is super super useful for code readability
(oh, you want to 'mix' two genetic lines A and B?(A + B)/2
aaaand you're done)