oh yeah, other thing: you can still probably get benefits out of doing (Seal((A | B | C)) | B | D) instead of full types, such as your hidden tag being something like A/B1/C/B2/D instead of Seal/B/D where Seal unpacks to match tag A/B/C, but I guess you could also do that with full enums? More to write, though, and doing this either way still requires more inlining / monomorphization, but it's an optimization that could be neat for hot stuff
you probably never meant to mess with the inner type like that. this is solvable by introducing an explicit separator, something like (Seal((A | None)) | None), maybe with some custom syntax? but you want a default way to say that you're not normally walking inside that type, and I don't think it's too far to say that should be the default behavior—which introduces a new issue of how to make ((A | B) | C) be (A | B | C) by default in stuff like function bodies, but that's worth thinking about.
if you have a dedicated None type, then something like a fallible getter of ints returning (U8 | None) seems obvious. extending that, if you want to communicate how it fails, doing (U8 | ErrFoo | ErrBar) looks nice and is easy to extend or reduce later. However, you change that U8 to a generic type var (e.g. A), and now you've introduced a function that's fine ~as long as~ you never use ErrFoo / ErrBar / None as a union component for A. The former two are reasonable, but the latter feels *bad*
what bugs me the most about languages that emphasize anonymous flattened sum types (your value is a member of a set of types that you can extend, and the details for that are managed for you behind the scenes) is that they seem to fly in the face of doing the obvious thing as complexity naturally grows.
examples in next toot
The fact that I just now stumbled upon explicit wrapping solving some sum problems seems like a bad sign—what's so bad about Rust/Haskell style algebraic data types, and why wouldn't the language docs mention a way to get around potential issues like this at all?
maybe I'll just go focus on Elixir instead and let Pony mature some more before coming back, but I really do want this to be a good language
how do you express what type of error you have?
I feel like the answer is "make a clearer API", but if I'm stuck expressing multiple types of failure, what do I do? the stark simplicity seems counter to a lot of the rest of the language that aims for clear and concise actor code that lets you really do what you need
you could probably hack together your own Rust-like tagged union, but now your union involves (A | B) sums, and you're screwed unless you introduce an explicit wrapping maybe?
it's like null pointer handling again, but reinvented with a bit more fancy type handling behind the scenes
I don't like this, and am hoping that at some point I discover that I'm just looking at it wrong, but stuff like collection/HashMap's apply lookup erroring on keys not being present and Iterator's general design isn't looking too good
I'm also not sure how I feel about the prevalence of anonymous sum types all over the places over more traditional compositional stuff like Option
on the one hand, it's simple to quickly slap together a set of whatever and match on it, but on the other hand, it seems you have to prefer error / ? to show that you have no value instead of doing an Option or (… | None) because your generic type could be (A | None) and the set union there would eat your None, and weh
So, I'm trying some Pony dev, but tuples apparently have some major kinda-fuzzy soundness issues, which is making development weird
it's like coding on eggshells
(related reading material: https://github.com/ponylang/ponyc/issues/1892 https://github.com/ponylang/ponyc/issues/2808 https://github.com/ponylang/ponyc/issues/2408 https://github.com/ponylang/ponyc/issues/2741 https://github.com/ponylang/ponyc/issues/2609 https://github.com/ponylang/ponyc/issues/1465 https://github.com/ponylang/ponyc/issues/2227 https://github.com/ponylang/ponyc/pull/2558 )
or maybe not, apparently others have already been insane enough to make a property-based testing lib in C: https://github.com/silentbicycle/theft
it even has auto-shrinking in its own, strange C way
Source is up at https://github.com/Streetwalrus/plywood/pull/1/commits/e890d9ba7665dad016543091c84178acec4cca37 , but this'll probably become its own crate when I get the spoons.
shoutouts to `cargo +nightly rustc --profile=check -- -Ztrace-macros` and https://github.com/dtolnay/cargo-expand
“Porkins old boy, you’re a popular fellow. Care for help with your following?”
“Oh no bother. No boooootheeee....”
*pushes more blocks around map of southern Britain *
“Death Star in range in five minutes.”
“Red Leader, we count thirty bogies headed your way over the drink, I’d say 109s.”
“Luke, check your high six.”
“Can’t shake him. Oh DO pot that fellow Biggs, there’s a love.”
“Good shot Wedge.”
“Damn fine shot.”
I do stuff.
Rustacean, Haskeller, & assorted strange langs. Fraudulent Etalus main. Tiny equine enthusiast. Seeking gender. #ActuallyADHD
A community that skews thoughtful and weird. Everyone who abides by the code of conduct is welcome, thoughtful weirdos most of all! :)