Like chunking!
Posts by Hillel
You should be able to do chords? `^!b` is ctrl+alt+b, while `b&f` is press b and f at the same time. You can also use inputhook for vim-style sequenced keys
But I think your specific usecase might be better served by Ditto: sabrogden.github.io/Ditto/
How would you define an "abstraction" in software engineering? Not with examples, but like as a definition
My best tell for AI writing is the lack of grammatically complex sentences. "No x. No y. No z." instead of "No x, y, or z." Way more sentence fragments and no run-on sentences. AIs are drama queens
I think coincidence, but there's a similiarity
I think I'm a lot looser in my definition of #2 than most: I consider something like "pros/cons" list to at least be partially trying to convince people "in circumstances X, at least consider approach Y"
ok no lie the new "split tab view" feature in firefox is lifechanging
An interesting wrinkle with (3) is it may be a valid move to indicate you understand things the audience does not, but you have to do this in a way that doesn't lose them (or think you are pretentious). Like maybe give a REALLY high level description
Three major purposes of "educational" tech blog posts:
1. Inform people about topic X
2. Persuade people towards opinion X
3. Impress people with the bloggers expertise in X
I know a lot of tricks to do (1) and (2) better but haven't thought about how to do (3) better (a valid thing to do!)
Huh, I thought haskell had type erasure! How does this work? I'm guessing it sort of "hardcodes in" the crash?
I think both Swift and Rust learned a lot from those purity tests!
15/
"Safety properties": the system never does a bad thing, like break a database constraint or double-bill someone
"Liveness": system always does intended things, like send the bill once
Most engineering techniques are for ensuring safety, but many critical business requirements are liveness
14/ Most bugs have stupid causes. The stupidness of the cause does not correlate with how easy it is to debug
13/ Patterns were invented in/for OOP but the name-motivation-applicability-consequences core is actually useful in pretty much every area of software engineering that develops idioms. Smart Constructors are a "make illegal states unrepresentable" pattern, etc
I think this comes back to capability/tractability: even if you can easily statically type 95% of the codebase, sometimes that last 5% is too complicated to annotate, which a dynlang can encode more simply
I'm less believing of this argument now that Typescript has been so successful
12/ Software as a whole functions like the pop-science version of an ecosystem. Ads and analytics are basically ways of extracting extra "calories" out of various niches. SEO/clickbait is a natural outcome of having search engine/social media algorithm monocultures
11/ Another secret tradeoff: systems that are maximally efficient are less scalable, and vice versa. This is because maximal efficiency requires "overtuning" on assumptions. This is also why small companies can outperform large ones pound-for-pound, but get less efficient as they grow
Gonna do the rest tomorrow
Oh thank fucking god
10/ You can solve an enormous number of technical problems by taking a walk
9/ Be Suspicious of Success. If a system is working, look for ways to break it. If it doesn't break, identify the reasons it didn't break, and remove them. If the system still doesn't break, something fishy is going on
8/ Most engineering tradeoffs are dictated by currencies: work-hours, money, and performance are the most obvious ones. "Complexity" is more subtle but equally important: we can solve problems by adding complexity to our system. The question is when to burn that vs other currencies
7/ Expertise is primarily a space-time tradeoff. For example, knowing the times table replaces doing mental math with a mental-lookup. A lot of being good at something is not having to think about it, including software
6/ A tool or technology that is okay at solving three aspects of a problem tends to be more maintainable in the long run than three distinct tools that are each amazing at one aspect. This is a lot of the driver behind "choose boring technology"
5/ In general, work that shortens feedback loops is the most valuable "metaproject" work that can be done on a project. Doesn't matter what feedback loop: testing, compiling, deploying, getting customer feedback, analyzing data, whatever
4/ Refinement: the opposite of abstraction. Many refactorings and expansions of code are refinements. Optimizations, adding better handling of sad paths, subtyping, modifying data schemas, etc. Like abstract, refinements follow rules and heuristics that lead to them being safer or less safe
3/ Tests are formal properties of system correctness. Some tests are stronger than others. `P => Q` means `!P || (P && Q)`: either P fails or both pass. By the contrapositive, weak tests failing give more information about the bug than strong tests passing
2/ Use case poisoning: trying to support advanced use cases in a system can make it harder to do basic use cases. Imagine how a structure of, say, Spotify changes if they want to support the use case of "playing two songs at once" (or playing two songs on two devices, from one account)
1/ The more expressive a system is, the fewer guarantees you have about its limits. I call it the "capability/tractability" tradeoff but have been searching for a better name.
Also known as the "principle of least power", which I disprefer for reasons
buttondown.com/hillelwayne/...
Doomscrolling has made me unmotivated to do long-term work, so to force myself to be doing *something* besides doomscrolling:
n² likes = n obscure software engineering concepts/principles/memes I find super useful