Aw jeez, that month went by fast. Partly because the weather has gotten good here, and with the vaccines kicking in we have been doing some stuff again, like some outdoor dining and hikes and hosting some vaccinated visitors. All of that is good, though.
My aforementioned game / tech demo thing was my main hacking project, now all cleaned up from a javascript prototype mess to some almost reasonable TypeScript. I'm taking the opportunity to play with that since several have recommended it as likely an upgrade over JS for my sensibilities. I do find that it is catching some bugs and is probably worth using, but I am not loving it, for these reasons:
I think I actually want a compiler that uses the type information to do optimizations/transformations (like say variable and property renaming). I think when I write code I'm often thinking about easy transformations that the compiler can do (discarding unused code, for example) and making use of that; without it, I find I need extra discipline to keep myself from optimizing by hand.
The very first thing I wanted to do with it, which was to parameterize some class by some set of types with operations, was quite awkward to do. This seems partly because of the way TypeScript is committed to erasure-based features (see prev), but also more annoying than it would need to be due to several ergonomic omissions (like, why can't I say "type T = F<T1, T2>" inside a generic class?). jcreed did help me figure out a livable approach though.
The type system is not complete (normal) and I kind of knew it was not actually sound either, but I was surprised to immediately find out how unsound it is. For example, consider this trivial program: let a = [];
if (a.length != 0) throw 'no';
a.push(5);
if (a.length != 1) throw 'no'; This program is correct JavaScript and I encountered a similar situation trying to unit-test my code, so I don't even think it's weird? And it is fine for TS to not be able to type-check all correct JS (as type systems are generally incomplete). But here the error message represents an unsoundness; on the last line: "This condition will always return 'true' because the types '0' and '1' have no overlap." This is just wrong. What's happening is that, if we get to the second if statement then the first if must be false (otherwise we'd throw an exception). Because the first if is false, a.length must be 0. This is OK so far. But then TS assumes that nothing can change the length property of a other than the code it's looking at right now, and so a.length must still be 0 in the second if. Incorrect! It thinks the branch must not be taken when in fact it is always taken. This means that it allows programs that would actually have runtime errors (unsound) or in this case, rejects my program with a useless and false claim. What's particularly annoying with this setup is that even if I fix it (e.g. a = a;) my program could typecheck fine in 2021, but then if TypeScript's type system gets "smarter" in 2022 and is able to track an expression's type in more situations (incorrectly), the same correct program might later be rejected. Bleh.
Kinda makes you want to just make your own language, right? But aside from that, I needed to do some pixel animations, which Photoshop is only minimally suited for. I was proud of myself for buying the well-liked Aseprite sprite editor (still need that tilemap mode though!!) instead of "just writing my own," although it was a somewhat agonizing decision.
I made some progress on my Pac Tom endgame strategy (video, CAD, basement workshop, and software work) and some other miscellaneous hacking, but a relatively project-light month.
I started reading Project Hail Mary (same author as The Martian), which is fun in its way. I really like the setup of "problem-solving sci-fi where the problems and solutions are compelling," although the writing is mostly just tolerable and the disbelief is inherently (to the genre) fragile if you notice something conceptually wrong with the fiction part (like, why not one waking crewmember and two in comas?). I think it's part of what drives me instead to non-fiction problem solving like "Eight Amazing Engineering Stories." Happy to hear recommendations along these lines though. In video games, I finished Blasphemous (decent exploration platformer with stiff combat/movement but excellent atmosphere), Rite (small hard precision platformer with great controls), Willy Jetman (silly exploration platformer that nonetheless had its charms), and Sayonara Wild Hearts (beautifully stylish animation and music with good-enough gameplay; recommended!). Wow, that's actually a lot. I'm letting myself play another roguelike now, Caveblazers. Might be a mistake though. It's quite fun but the difficulty curve on the later levels is starting to worry me. |