bb010g is a user on You can follow them or interact with them if you have an account anywhere in the fediverse. If you don't, you can sign up here.


Pinned toot

keybase proof Show more

Pinned toot

Hey all, I'm back from the virtual grave! If you followed, you'd probably want to follow me again here. I toot mostly about random tech stuff (which I'm trying to be more regular about now), with a focus on making computers more reliable and sustainable (defensive programming, alternative UX, etc).

If you followed me before, a boost would be appreciated to help other previous followers catch this.

bb010g boosted

The Great and The Gatsby
2 Great 2 Gatsby
The Great and the Gatsby: '20s drift
Great & Gatsby
The Great 6
Gatsby 7
The Gr8 Gatsby

bb010g boosted
sonicfox donated 10k of his recent tournament winnings to his opponent so he could pay for his dad's cancer treatment, thats like sportsmanship level over 9000
bb010g boosted

Man, Scott Pilgrim vs. the World is a beautiful film.

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

point is, you don't have to go full named Rust-style enum to get safer with your sum types, but I'm confused as to why nobody seems to do that.

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

or maybe not, apparently others have already been insane enough to make a property-based testing lib in C:

it even has auto-shrinking in its own, strange C way

current mood: considering bolting Haskell onto a C library just for the test suite

less fancy macro magic, but much nicer in general

Source is up at , but this'll probably become its own crate when I get the spoons.

shoutouts to `cargo +nightly rustc --profile=check -- -Ztrace-macros` and

bb010g boosted

“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 *
*phones ring*
“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.”