From 2efcf477e3ccdd22c284825c65b708f21a9b99db Mon Sep 17 00:00:00 2001 From: David Eisinger Date: Sun, 2 Jul 2023 22:55:35 -0400 Subject: [PATCH] Dispatch 5 (and various misc. updates) --- content/journal/dispatch-5-july-2023/index.md | 88 ++ content/notes/first-it-must-work/index.md | 6 + content/notes/golang/index.md | 30 +- content/notes/good-tests/index.md | 5 + static/archive/benhoyt-com-vfdv1s.txt | 728 +++++++++++ static/archive/macwright-com-o4dndf.txt | 344 ++++++ static/archive/maggieappleton-com-7am49k.txt | 150 +++ static/archive/maggieappleton-com-fube9k.txt | 135 +++ static/archive/softwarecrisis-dev-7c7z9g.txt | 1069 +++++++++++++++++ static/archive/taylor-town-5siv9a.txt | 191 +++ static/archive/timharek-no-ah7ilz.txt | 142 +++ themes/v2/assets/css/style.scss | 9 +- 12 files changed, 2882 insertions(+), 15 deletions(-) create mode 100644 content/journal/dispatch-5-july-2023/index.md create mode 100644 static/archive/benhoyt-com-vfdv1s.txt create mode 100644 static/archive/macwright-com-o4dndf.txt create mode 100644 static/archive/maggieappleton-com-7am49k.txt create mode 100644 static/archive/maggieappleton-com-fube9k.txt create mode 100644 static/archive/softwarecrisis-dev-7c7z9g.txt create mode 100644 static/archive/taylor-town-5siv9a.txt create mode 100644 static/archive/timharek-no-ah7ilz.txt diff --git a/content/journal/dispatch-5-july-2023/index.md b/content/journal/dispatch-5-july-2023/index.md new file mode 100644 index 0000000..f7ff50d --- /dev/null +++ b/content/journal/dispatch-5-july-2023/index.md @@ -0,0 +1,88 @@ +--- +title: "Dispatch #5 (July 2023)" +date: 2023-07-02T16:55:57-04:00 +draft: false +tags: +- dispatch +references: +- title: "My thoughts on Helix after 6 months - Tim Hårek" + url: https://timharek.no/blog/my-thoughts-on-helix-after-6-months/ + date: 2023-07-02T12:53:51Z + file: timharek-no-ah7ilz.txt +- title: "What App is That?" + url: https://maggieappleton.com/apps + date: 2023-07-02T12:53:51Z + file: maggieappleton-com-7am49k.txt +- title: "Modern software quality, or why I think using language models for programming is a bad idea" + url: https://softwarecrisis.dev/letters/ai-and-software-quality/ + date: 2023-07-03T00:54:57Z + file: softwarecrisis-dev-7c7z9g.txt +- title: "The small web is beautiful" + url: https://benhoyt.com/writings/the-small-web-is-beautiful/ + date: 2023-07-03T00:52:08Z + file: benhoyt-com-vfdv1s.txt +- title: "Why You Own an iPad and Still Can’t Draw" + url: https://maggieappleton.com/still-cant-draw + date: 2023-07-03T01:05:26Z + file: maggieappleton-com-fube9k.txt +--- + +June was dominated by work and travel. Weekdays were filled up with a client project we were working hard to wrap, weekends by plans with friends and both of our families: [Running of the Bulls][1], canoe camping near Saxapahaw, our yearly trip to Beaufort with Claire's college friends, and then a cruise in the Caribbean with Claire's family followed immediately by a trip up to DC to see mine. + +[1]: https://bullcityrunning.com/our-races/running-of-the-bulls-8k/ + + + +
+ {{}} + {{}} + {{}} + {{}} +
+ +Most everything else fell by the wayside, but that's OK -- these were all awesome experiences, and I'm excited for a (relatively) quiet July. + +After getting the trailer hitch installed last month, we picked up a [bike rack][2] and a [seat for Nev][3] and brought the bikes with us to Beaufort. This was **awesome** -- Beaufort's an idyllic coastal town in just about every way but one: parking sucks. Being able to zip up and down the main street on our bikes (and parking them right at our destination) was such a joy, and Nev seems to enjoy the rack-mounted seat a lot more than the trailer we've been using. + +I'm still enjoying using Obsidian to collect link and make notes, though mostly in the "capture" phase[^1], collecting information and starting to put some structure around it. When something comes up and I think, man, I read something good about that at some point in the past, I'm using that as a cue to create a dedicated note, with the hope that the _next_ time it comes up, I'll have a useful thing to reference. + +I also read some good articles about [Helix][4] and [Procreate][5], and I'm hoping to give those some attention this month. + +[2]: https://1up-usa.com/product/2-super-duty-double +[3]: https://www.thule.com/en-us/child-bike-seats/rear-mounted-child-bike-seats/thule-yepp-nexxt-maxi-_-12080211 +[4]: https://timharek.no/blog/my-thoughts-on-helix-after-6-months/ +[5]: https://maggieappleton.com/apps + +This month: + +* Adventure: dust off the road bike, fill the tires, grease the chain, throw it on the rack, and get out for a long ride +* Project: publish an article on [testing][14] on my company's website +* Skill: learn [Helix][13] movements, see if it'd be a good Vim replacement (I still love Vim, and I'm pretty good at it, but my config's dated and I'm wary of how much effort it'll take to modernize) + +[13]: https://helix-editor.com/ +[14]: /notes/good-tests + +Reading: + +* Fiction: [_The Golden Enclaves_][6], Naomi Novik +* Non-fiction: + * [_Rapt_][7], Winifred Gallagher + * [_Visual Thinking_][8], Williemien Brand + * [_The Manual: A Philosopher's Guide to Life_][9], Epictetus + +[7]: https://bookshop.org/p/books/rapt-attention-and-the-focused-life-winifred-gallagher/7485226?ean=9780143116905 +[6]: https://bookshop.org/p/books/the-golden-enclaves-naomi-novik/17789027?ean=9780593158357 +[8]: https://bookshop.org/p/books/visual-thinking-empowering-people-and-organisations-through-visual-collaboration-williemien-brand/12408256?ean=9789063694531 +[9]: https://bookshop.org/p/books/the-manual-a-philosopher-s-guide-to-life-epictetus/15150488?ean=9781545461112 + +Links: + +* [Modern software quality, or why I think using language models for programming is a bad idea][10] -- I refer people to this article a lot in discussions around LLMs and software development +* [The small web is beautiful][11] +* [Why You Own an iPad and Still Can't Draw][12] + +[10]: https://softwarecrisis.dev/letters/ai-and-software-quality/ +[11]: https://benhoyt.com/writings/the-small-web-is-beautiful/ +[12]: https://maggieappleton.com/still-cant-draw + +[^1]: Tiago Forte's _Building a Second Brain_ outlines a four-step process: Capture, Organize, Distill, Express. diff --git a/content/notes/first-it-must-work/index.md b/content/notes/first-it-must-work/index.md index 943ce3f..b8e40f1 100644 --- a/content/notes/first-it-must-work/index.md +++ b/content/notes/first-it-must-work/index.md @@ -15,6 +15,10 @@ references: url: https://cerebralab.com/Imaginary_Problems_Are_the_Root_of_Bad_Software date: 2023-06-20T16:28:39Z file: cerebralab-com-qy5zqs.txt +- title: "When to Build Millennia Sewers" + url: https://taylor.town/millennium-sewer + date: 2023-07-03T00:32:43Z + file: taylor-town-5siv9a.txt --- ### Thoughts on priorities in software development @@ -28,7 +32,9 @@ references: * [The Grug Brained Developer][1] * [Even Amazon can't make sense of serverless or microservices][2] * [Imaginary Problems Are the Root of Bad Software][3] +* [When to Build Millennia Sewers][4] [1]: https://grugbrain.dev/ [2]: https://world.hey.com/dhh/even-amazon-can-t-make-sense-of-serverless-or-microservices-59625580 [3]: https://cerebralab.com/Imaginary_Problems_Are_the_Root_of_Bad_Software +[4]: https://taylor.town/millennium-sewer diff --git a/content/notes/golang/index.md b/content/notes/golang/index.md index 9fa064c..e5daa6d 100644 --- a/content/notes/golang/index.md +++ b/content/notes/golang/index.md @@ -47,6 +47,7 @@ I find [Go][1] really compelling, even though it's not super applicable to my jo * [SyncThing][5] * [Restic][6] * [Gotenberg][7] +* [Shiori][8] [2]: https://gohugo.io/ [3]: https://caddyserver.com/ @@ -54,29 +55,30 @@ I find [Go][1] really compelling, even though it's not super applicable to my jo [5]: https://syncthing.net/ [6]: https://restic.net/ [7]: https://gotenberg.dev/ +[8]: https://github.com/go-shiori/shiori ### Project Ideas * Bookmarking app (Pinboard replacement) * Note-taking / journaling app -* [StevieBlocks][8] +* [StevieBlocks][9] {{}} -[8]: https://gist.github.com/dce/f975cb21b50a2cf998bf7230cbf89d85 +[9]: https://gist.github.com/dce/f975cb21b50a2cf998bf7230cbf89d85 ### Resources -* [Standard Go Project Layout][9] -* [The files & folders of Go projects][10] -* [Why David Yach Loves Go][11] -* [One process programming notes (with Go and SQLite)][12] -* [Go Project Layout][13] -* [Gopher Wrangling. Effective error handling in Go][14] +* [Standard Go Project Layout][10] +* [The files & folders of Go projects][11] +* [Why David Yach Loves Go][12] +* [One process programming notes (with Go and SQLite)][13] +* [Go Project Layout][14] +* [Gopher Wrangling. Effective error handling in Go][15] -[9]: https://github.com/golang-standards/project-layout -[10]: https://changelog.com/gotime/278 -[11]: https://cloud.google.com/blog/products/application-modernization/why-david-yach-loves-go -[12]: https://crawshaw.io/blog/one-process-programming-notes -[13]: https://medium.com/golang-learn/go-project-layout-e5213cdcfaa2 -[14]: https://stephenn.com/2023/06/gopher-wrangling.-effective-error-handling-in-go/ +[10]: https://github.com/golang-standards/project-layout +[11]: https://changelog.com/gotime/278 +[12]: https://cloud.google.com/blog/products/application-modernization/why-david-yach-loves-go +[13]: https://crawshaw.io/blog/one-process-programming-notes +[14]: https://medium.com/golang-learn/go-project-layout-e5213cdcfaa2 +[15]: https://stephenn.com/2023/06/gopher-wrangling.-effective-error-handling-in-go/ diff --git a/content/notes/good-tests/index.md b/content/notes/good-tests/index.md index 194d8f8..420d60f 100644 --- a/content/notes/good-tests/index.md +++ b/content/notes/good-tests/index.md @@ -2,6 +2,11 @@ title: "Good Tests" date: 2023-05-12T23:40:19-04:00 draft: false +references: +- title: "A year of Rails - macwright.com" + url: https://macwright.com/2021/02/18/a-year-of-rails.html + date: 2023-07-03T02:52:03Z + file: macwright-com-o4dndf.txt --- _(Notes for a Viget article I'm putting together)_ diff --git a/static/archive/benhoyt-com-vfdv1s.txt b/static/archive/benhoyt-com-vfdv1s.txt new file mode 100644 index 0000000..bd88105 --- /dev/null +++ b/static/archive/benhoyt-com-vfdv1s.txt @@ -0,0 +1,728 @@ + [1]Ben Hoyt + * [2]Home + * [3]Resume/CV + * [4]Projects + * [5]Tech Writing + * [6]Non-Tech + * [7]Email + + * [8]benhoyt.com + * [9]benhoyt@gmail.com + +The small web is beautiful + + March 2021 + + Summary: I believe that small websites are compelling aesthetically, + but are also important to help us resist selling our souls to large + tech companies. In this essay I present a vision for the “small web” + as well as the small software and architectures that power it. Also, + a bonus rant about microservices. + + Go to: [10]Software | [11]Web | [12]Server-side | [13]Static sites | + [14]Dependencies | [15]Analytics | [16]Microservices + + About fifteen years ago, I read E. F. Schumacher’s Small is Beautiful + and, despite not being interested in economics, I was moved by its + message. Perhaps even more, I loved the terse poetry of the book’s + title – it resonated with my frugal upbringing and my own aesthetic. + + I think it’s time for a version of that book about technology, with a + chapter on web development: The Small Web is Beautiful: A Study of Web + Development as if People Mattered. Until someone writes that, this + essay will have to do. + + There are two aspects of this: first, small teams and companies. I’m + not going to talk much about that here, but [17]Basecamp and many + others have. What I’m going to focus on in this essay is small websites + and architectures. + + I’m not the first to talk about the “small web”, but, somewhat + surprisingly, only a few people have discussed it using that term. Here + are the main web pages I can find that do: + * [18]Rediscovering the Small Web by Parimal Satyal: a fabulous + article about the joy of small, independent (and sometimes retro) + websites in contrast to the “commercial web”. + * [19]What is the Small Web?, by Aral Balkan of the Small Technology + Foundation: more of a manifesto against the surveillance of Big + Tech than something concrete, but still interesting. + + Why aim small in this era of fast computers with plenty of RAM? A + number of reasons, but the ones that are most important to me are: + * Fewer moving parts. It’s easier to create more robust systems and + to fix things when they do go wrong. + * Small software is faster. Fewer bits to download and clog your + computer’s memory. + * Reduced power consumption. This is important on a “save the planet” + scale, but also on the very local scale of increasing the battery + life of your phone and laptop. + * The light, frugal aesthetic. That’s personal, I know, but as you’ll + see, I’m not alone. + + So let’s dive in. I want to cover a bunch of different angles, each + with its own subheading. + +Small software + + If we’re going to talk about a small web, we need to start with small + software. + + As a teen, I learned to program using x86 assembly and [20]Forth – + perhaps odd choices, but my dad was heavily into Forth, and I loved how + the language was so simple I could write [21]my own bootstrapped + compiler. + + In terms of career, I started as an embedded programmer – not as in + “embedded Linux” but as in microcontrollers where 16KB of RAM was + generous. My current laptop has 16GB of RAM, and that’s not a lot by + today’s standards. We were building IP-networked products with one + millionth the amount of RAM. Those kinds of micros are as cheap as + chips (ahem), and still widely used for small electronic devices, + sensors, internet-of-things products, and so on. + + You have to think about every byte, compile with size optimizations + enabled, and reuse buffers. It’s a very different thing from modern web + development, where a JavaScript app compiles “down” to a 1MB bundle, or + a single Python object header is 16 bytes before you’ve even got any + data, or a Go hello-world binary is 2MB even before you’ve added any + real code. + + How do you create small programs? I think the main thing is that you + have to care about size, and most of us don’t think we have time for + that. Apart from embedded development, there’s an entire programming + subculture called the [22]demoscene that cares about this. They have + competitions for the smallest 4KB demos: who can pack the most + graphical punch into 4096 bytes of executable. That’s smaller than many + favicons! ([23]Elevated and [24]cdak are two of the highest-rated 4K + demos.) Many demosceners go on to become game developers. + + It’s not just about executable size … when you’re developing your next + command line tool, if you use Go or Rust or even C, your program will + be much faster, smaller, and use less memory than a Python or Java + equivalent. And easier to install. If you don’t understand why, please + do learn. (It’s out of scope for this essay, but to summarize: Go, + Rust, and C compile to ready-to-execute machine code, don’t carry + around a virtual machine, and don’t have memory overhead for objects + like integers.) + + But why not apply some of the same principles to web development? In + the web world, I think the main trick is to be careful what + dependencies you include, and also what dependencies they pull in. In + short, know node_modules – or maybe better, no node_modules. More about + this [25]below. + + Niklaus Wirth of Pascal fame wrote a famous paper in 1995 called [26]A + Plea for Lean Software [PDF]. His take is that “a primary cause for the + complexity is that software vendors uncritically adopt almost any + feature that users want”, and “when a system’s power is measured by the + number of its features, quantity becomes more important than quality”. + He goes on to describe Oberon, a computer language (which reminds me of + Go in several ways) and an operating system that he believes helps + solve the complexity problem. Definitely wirth a read! + + I’ve been mulling over this for a number of years – back in 2008 I + wrote a sarcastic dig at how bloated Adobe Reader had become: [27]Thank + you, Adobe Reader 9! It was a 33MB download and required 220MB of hard + drive space even in 2008 (it’s now a 150MB download, and I don’t know + how much hard drive space it requires, because I don’t install it these + days). + + But instead of just complaining, how do we actually solve this problem? + Concretely, I think we need to start doing the following: + * Care about size: this sounds obvious, but things only change when + people think they’re important. + * Measure: both your executable’s size, and your program’s memory + usage. You may want to measure over time, and make it a blocking + issue if the measurements grow more than x% in a release. Or you + could hold a memory-reduction sprint every so often. + * Language: choose a backend language that has a chance, for example + Rust, C or C++, or for servers, Go. These languages aren’t right + for everything (like data transformation scripts), but they produce + small executables, and they’re good for CLIs and desktop apps. + * Remove: cut down your feature set. Aim for a small number of + high-quality features. My car can’t fly or float, and that’s okay – + it drives well. + * Say no to new features: unless they really fit your philosophy, or + add more than they cost over the lifetime of your project. + * Dependencies: understand the size and complexity of each dependency + you pull in. Use only built-in libraries if you can. + +Small websites + + I’m glad there’s a growing number of people interested in small + websites. + + A few months ago there was a sequence of posts to Hacker News about + various “clubs” you could post your small website on: the [28]1MB Club + ([29]comments), [30]512KB Club ([31]comments), [32]250KB Club + ([33]comments), and even the [34]10KB Club ([35]comments). I think + those are a fun indicator of renewed interested in minimalism, but I + will say that raw size isn’t enough – a 2KB site with no real content + isn’t much good, and a page with 512KB of very slow JavaScript is worse + than a snappy site with 4MB of well-chosen images. + + Some of my favourite small websites are: + + [36]Hacker News: I personally like the minimalist, almost brutalist + design, but I love its lightness even more. I just downloaded the home + page, and loading all resources transfers only 21KB (61KB + uncompressed). Even pages with huge comment threads only transfer about + 100KB of compressed data, and load quickly. Reddit has become such a + bloated mess in comparison. Hacker News, never change! + + [37]Lobsters: a similar news-and-voting site, with slightly more + “modern” styling. It uses some JavaScript and profile icons, but it’s + still clean and fast, and the total transfer size for the homepage is + only 102KB. You just don’t need megabytes to make a good website. + + [38]Sourcehut: I like the concept behind Drew DeVault’s business, but I + love how small and anti-fluff the website is. He has set up a mini-site + called the [39]Software Forge Performance Index that tracks size and + browser performance of the prominent source code websites – Sourcehut + is far and away the lightest and fastest. Even his homepage is only + 81KB, including several screenshot thumbnails. + + [40]SQLite: not only is SQLite a small, powerful SQL database engine, + the website is fantastically small and content-rich. Even their + 7000-word [41]page about testing is only 70KB. How do they do this? + It’s not magic: focus on high-quality textual content, minimal CSS, no + JavaScript, and very few images (a small logo and some SVGs). + + [42]LWN: I’m a little biased, because I’ve written [43]articles for + them, but they’re an excellent website for Linux and programming news. + Extremely high-quality technical content (and a high bar for authors). + They’re definitely niche, and have a “we focus on quality content, not + updating our CSS every year” kind of look – they’ve been putting out + great content for 23 years! Their homepage only downloads 44KB (90KB + uncompressed). + + [44]Dan Luu’s blog: this is one of the more hardcore examples. His + inline CSS is only about 200 bytes (the pages are basically unstyled), + and his HTML source code doesn’t use any linefeed characters. Kind of a + fun point, although then he goes on to load 20KB of Google Analytics + JavaScript… + + As a friend pointed out, those websites have something of an + “anti-aesthetic aesthetic”. I confess to not minding that at all, but + on the other hand, small doesn’t have to mean ugly. More and more + personal blogs and websites have adopted a small web approach but are + more typographically appealing: + * [45]Armin Ronacher’s Thoughts and Writings + * [46]Chris Wellons’ “Null program” blog + * [47]Eric Radman’s BSD and SQL blog + * [48]Hugo Tunius’ programming blog + * [49]James Hague’s “Programming in the Twenty-First Century” + * [50]Julia Evans’ programming blog + + There are many, many more. Programmer Sijmen Mulder created a nice list + of [51]text-only websites – not quite the same thing as small, but it + definitely overlaps! + + However, it’s not just about raw size, but about an “ethos of small”. + It’s caring about the users of your site: that your pages download + fast, are easy to read, have interesting content, and don’t load scads + of JavaScript for Google or Facebook’s trackers. Building a website + from scratch is not everyone’s cup of tea, but for those of us who do + it, maybe we can promote templates and tools that produce small sites + that encourage quality over quantity. + + For this website, I lovingly crafted each byte of HTML and CSS by hand, + like a hipster creating a craft beer. Seriously though, if your focus + is good content, it’s not hard to create a simple template from scratch + with just a few lines of HTML and CSS. It will be small and fast, and + it’ll be yours. + + Loading this essay transfers about 23KB (56KB uncompressed), including + the favicon and analytics script. It’s small, fast, and readable on + desktop or mobile. I don’t think it’s too bad looking, but I’m + primarily aiming for a minimalist design focussed on the content. + + In addition to making sure your HTML and CSS are small, be sure to + compress your images properly. Two basic things here: don’t upload + ultra-high resolution images straight from your camera, and use a + reasonable amount of JPEG compression for photos (and PNG for + screenshots or vector art). Even for large images, you can usually use + 75% or 80% compression and still have an image without JPEG noise. For + example, the large 1920x775 image on the top of my [52]side business’s + homepage is only 300KB. + + Speaking of hero images, you don’t need big irrelevant images at the + top of your blog posts. They just add hundreds of kilobytes (even + megabytes) to your page weight, and don’t provide value. And please + don’t scatter your article with animated GIFs: if there’s something + animated on the screen, I can hardly concentrate enough to read the + text – and I’m [53]not the [54]only one. Include relevant, non-stock + images that provide value equal to their weight in bytes. Bare text is + okay, too, like a magazine article. + + [55]IndieWeb.org is a great resource here, though they use the term + “indie” rather than “small”. This movement looks more organic than the + [56]Small Technology Foundation (which has even been [57]critiqued as + “digital green-washing”), and their wiki has a lot more real content. + IndieWeb also promotes local [58]Homebrew Website Clubs and + [59]IndieWebCamp meetups. + +Emphasize server-side, not JavaScript + + JavaScript is a mixed blessing for the web, and more often than not a + bane for small websites: it adds to the download size and time, it can + be a performance killer, it’s bad for accessibility, and if you don’t + hold it right, it’s [60]bad for search engines. Plus, if your website + is content-heavy, it probably isn’t adding much. + + Don’t get me wrong: JavaScript is sometimes unavoidable, and is great + where it’s great. If you’re developing a browser-based application like + Gmail or Google Maps, you should almost certainly be using JavaScript. + But for your next blog, brochure website, or project documentation + site, please consider plain HTML and CSS. + + If your site – like a lot of sites – is somewhere in between and + contains some light interaction, consider using JavaScript only for the + parts of the page that need it. There’s no need to overhaul your whole + site using React and Redux just to add a form. Letting your server + generate HTML is still an effective way to create fast websites. + + [61]Stack Overflow is a case in point. From day one, they’ve made + [62]performance a feature by rendering their pages on the server, and + by measuring and reducing render time. I’m sure the Stack Overflow code + has changed quite a lot since the Jeff Atwood days – it now makes a ton + of extra requests for advertising purposes – but the content still + loads fast. + + [63]Hacker News (there’s that site again) is a server-side classic. + With only [64]one tiny JavaScript file for voting, the HTML generated + on the server does the rest. And [65]apparently it still runs on a + single machine. + + Around fifteen years ago there was this great idea called + [66]progressive enhancement. The idea was to serve usable HTML content + to everyone, but users with JavaScript enabled or fast internet + connections would get an enhanced version with a more streamlined user + interface. In fact, Hacker News itself uses progressive enhancement: + even in 2021, you can still turn off JavaScript and use the voting + buttons. It’s a bit clunkier because voting now requires a page reload, + but it works fine. + + Is progressive enhancement still relevant in 2021? Arguably not, though + some die-hards still turn JavaScript off, or at least enable it only + for sites they trust. However, I think it’s the mentality that’s most + important: it shows the developer cares about performance, size, and + alternative users. If Hacker News voting didn’t work without + JavaScript, I don’t think that would be a big problem – but it shows a + certain kind of nerdish care that it does work. Plus, the JavaScript + they do have is only 2KB (5KB uncompressed). + + Compare that to the 8MB (14MB uncompressed) that the [67]Reddit + homepage loads. And this across 201 requests – I kid you not! – most of + which is JavaScript to power all the ads and tracking. Lovely… + + You don’t need a “framework” to develop this way, of course, but there + are some tools that make this style of server-side development easier. + [68]Turbolinks from the Basecamp folks was an early one, and it’s now + been superseded by [69]Turbo, which is apparently used to power their + email service [70]Hey. I haven’t used these personally, but the ideas + are clever (and surprisingly old-skool): use standard links and form + submissions, [71]serve plain HTML, but speed it up with WebSockets and + JavaScript if available. Just today, in fact, someone posted a new + article on Hacker News which claims [72]“The Future of Web Software Is + HTML-over-WebSockets”. If Hey is anything to go by, this technique is + fast! + + On the other hand, sometimes you can reduce overall complexity by using + JavaScript for the whole page if you’re going to need it anyway. For + example, the registry pages on my wedding registry website are rendered + on the client (they actually [73]use Elm, which compiles to + JavaScript). I do need the interactivity of JavaScript (it’s more + “single page application” than mere content), but I don’t need + server-side rendering or good SEO for these pages. The homepage is a + simple server-rendered template, but the registry pages are fully + client-rendered. + +Static sites and site generators + + Another thing there’s been renewed interest in recently is static + websites (these used to be called just “websites”). You upload some + static HTML (and CSS and JavaScript) to a static file server, and + that’s it. + + Improving on that, there are many “static site generators” available. + These are tools that generate a static site from simple templates, so + that you don’t have to copy your site’s header and footer into every + HTML file by hand. When you add an article or make a change, run the + script to re-generate. If you’re hosting a simple site or blog or even + a news site, this is a great way to go. It’s content, after all, not an + interactive application. + + I use [74]GitHub Pages on this site just because it’s a free host that + supports SSL, and automatically builds your site using the [75]Jekyll + static site generator whenever you push a change. I have a standard + header and include the same CSS across all pages easily, though you can + have multiple templates or “layouts” if you want. Because most people + only view one or two articles on my site, I include my CSS inline. With + HTTP/2, this doesn’t make much difference, but Lighthouse showed around + 200ms with inline CSS, 300ms with external CSS. + + Here’s an example of what a simple Jekyll page looks like (the start of + this essay, in fact): + --- + layout: default + title: "The small web is beautiful" + permalink: /writings/the-small-web-is-beautiful/ + description: A vision for the "small web", small software, and ... + --- + Markdown text here. + + I’ve also used [76]Hugo, which is a really fast static site generator + written in Go – it generates even large sites with thousands of pages + in a few seconds. And there are [77]many other options available. + +Fewer dependencies + + There’s nothing that blows up the size of your software (or JavaScript + bundle) like third party dependencies. I always find a web project’s + node_modules directory hard to look at – just the sheer volume of stuff + in there makes me sad. + + Different languages seem to have different “dependency cultures”. + JavaScript, of course, is notorious for an “if it can be a library, it + should be” attitude, resulting in the [78]left-pad disaster as well as + other minuscule libraries like the 3-line [79]isarray. There are also + big, heavy packages like [80]Moment.js, which takes [81]160KB even when + minified. There are ways to shrink it down if you don’t need all + locales, but it’s not the default, so most people don’t (you’re + probably better off choosing a more modular approach like + [82]date-fns). + + Go now has good dependency management with the recent [83]modules + tooling, but it also has a culture of “use the standard library if you + can”. Russ Cox wrote an excellent essay about the downsides of not + being careful with your dependencies: [84]Our Software Dependency + Problem. Go co-creator Rob Pike even made this one of his [85]Go + proverbs: “A little copying is better than a little dependency.” You + can probably guess by now, but I like this minimalist approach: apart + from reducing the number of points of failure, it makes programs + smaller. + + Python, Ruby, Java, and C# seem to be somewhere in between: people use + a fair number of dependencies, but from what I’ve seen there’s more + care taken and it doesn’t get as out of hand as node_modules. + Admittedly it is a little unfair, as Python (and those other languages) + have standard libraries that have more in them than JavaScript’s. + + The website [86]YouMightNotNeedjQuery.com shows how many of the tasks + you think you might need a library for are actually quite simple to do + with plain JavaScript. For example, in one of my projects I use a + function like the following to make an API request with plain old + XMLHttpRequest: +function postJson(url, data, callback) { + var xhr = new XMLHttpRequest(); + xhr.onreadystatechange = function () { + if (xhr.readyState === xhr.DONE) { + callback(xhr.status, JSON.parse(xhr.responseText)); + } + }; + xhr.open("POST", url, true); + xhr.setRequestHeader("Content-Type", "application/json"); + xhr.send(JSON.stringify(data)); +} + + The moral of the story: think twice before adding dependencies. You’ll + keep your websites and programs smaller and more reliable, and you’ll + thank Russ Cox later. + +Small analytics + + Most website owners want some form of analytics to see how many + visitors are coming to their site, and from where. The go-to tool is + Google Analytics: it’s easy to set up and the UI is pretty + comprehensive. But there’s a cost: it adds a significant amount of + weight to your page (19KB of JavaScript, 46KB uncompressed), and it + sends a lot of user data for Google to collect. + + Once again, there’s been renewed interest in smaller, more + privacy-friendly analytics systems in recent times. Just this morning I + read a provocative article that was highly-voted on Hacker News called + [87]“Google Analytics: Stop feeding the beast”. + + Last year I wrote two articles for LWN on the subject, so I won’t say + too much more here: + * [88]Lightweight alternatives to Google Analytics: replacing it with + lightweight open source and privacy-conscious alternatives, + specifically [89]GoatCounter and [90]Plausible. + * [91]More alternatives to Google Analytics: some heavier + alternatives, and a brief look at log-based analytics tools. + + For this website I use GoatCounter, which is available as a low-cost + hosted service (free for non-commercial use) or as a self-hosted tool. + I really like what Martin is doing here, and how small and simple the + tool is: no bells and whistles, just the basic traffic numbers that + most people want. + +Small architectures (not microservices) + + Small websites are great for users, but small architectures are great + for developers. A small, simple codebase is easy to maintain, and will + have fewer bugs than a large, sprawling system with lots of interaction + points. + + I contend that the “microservices everywhere” buzz is a big problem. + Microservices may be used successfully at Google and Amazon, but most + companies don’t need to build that way. They introduce complexity in + the code, API definitions, networking, deployment, server + infrastructure, monitoring, database transactions – just about every + aspect of a system is made more complex. Why is that? + * Code: you have lots of little repositories, possibly in different + languages, and each has to have some way to talk to the other + services (JSON over HTTP, gRPC, etc). With a monolithic system, + it’s all in one language (much better for a small team), calling + other modules is just a function call, and system-wide refactoring + is comparatively easy (especially in a statically typed language + like Go or Java). + * API definitions: with many services talking to each other, suddenly + you need standardized interfaces for how they communicate. You + spend a lot of time setting up gRPC or JSON schema definitions. In + a single codebase, a function signature is the API definition. + * Networking: with microservices, a function call is a network call, + and you spend time setting up your network infrastructure, thinking + about timeouts and retries, and maybe even designing inter-service + authentication. In monolithic systems, you only worry about + networking when talking to your database, cloud provider, and + users. + * Deployment: at a previous company I worked at, once we started + building with microservices, suddenly we needed fancy deployment + tooling and a dedicated infrastructure team to manage it all. You + can get by with a lot less if you’re only deploying a few services. + * Server infrastructure: you’ll probably need to set up new + infrastructure – lots of small virtual machines, or a + Kubernetes-based system. Kubernetes in itself is a complex + distributed application (even [92]Google admits it’s too complex), + and it takes a lot of work – or a lot of money – to run properly. + * Monitoring: to debug issues, you’ll need costly + distributed-monitoring software like Datadog to see what’s going + on. When an outage occurs, you’ll scramble to determine which + service is responsible, which team to page, and so on. Compare that + with a simple stack trace or single-service issue. + * Database transactions: these are difficult to impossible in a + microservices architecture. You may be able to design your way out + of them, but that’s not easy either. With a monolith, just type + BEGIN ... COMMIT, or however your database library spells it. + + It’s been said before, but microservices solve a people problem, not a + technical one. But beware of [93]Conway’s Law: your architecture will + mimic your company structure. Or the reverse – you’ll have to hire and + reorg so that your company structure matches the architecture that + microservices require: lots of engineers on lots of small teams, with + each team managing a couple of microservices. + + That doesn’t mean microservices are always the wrong choice: they may + be necessary in huge engineering organizations. However, if you’re + working at such a company, you’ve probably already been using + microservices for years. If you’re not “Google size”, you should think + twice before copying their development practices. + + What’s the alternative? The term “monolith” has a bad rap, but I agree + with David at Basecamp that [94]monoliths can be majestic. Basecamp is + a large, monolithic application, and they run it with just a dozen + programmers. David is quick to point out that “the Majestic Monolith + doesn’t pretend to provide a failsafe architectural road to glory”. You + still have to think, design, and write good code. + + Thankfully, people are bouncing back from the cargo culting. Just do a + search for [95]“why not microservices” and you’ll find lots of good + articles on the subject. One of the recent ones I’ve read is from + Tailscale: [96]Modules, monoliths, and microservices. + + So what’s my advice? + * Unless your company name is Google or Amazon, start with a + monolith. + * Once it starts having problems, optimize or refactor the pain + points. + * If it’s still having issues, buy a bigger server. + * If you have a specific technical reason to split it up, fix that + problem. + * If there are still problems, split off only the component that + needs splitting off. You’ll have two services to deploy and + monitor, but that’s far simpler than going all-in on microservices. + + Okay, so this became more of an anti-microservices rant than I was + planning, but so be it. + + In terms of counter-examples, Stack Overflow once again comes to mind. + They’re one of the web’s busiest sites, but they have a relatively + simple, two-tier [97]architecture that they’ve scaled vertically – in + other words, big servers with lots of RAM, rather than hundreds of + small servers. They have 9 web servers and 4 very chunky SQL servers, + with a few additional servers for their tag engine, Redis, + Elasticsearch, and HAProxy. This architecture helps them get great + performance and the ability to develop with a small team. + + My own side business, [98]GiftyWeddings.com, only gets a small amount + of traffic, so it’s nothing like Stack Overflow, but it uses a Go HTTP + server with SQLite on one of the smallest EC2 instances available, + [99]t2.micro. It costs about $8 per month, and I only have one tiny + piece of infrastructure to maintain. I deploy using [100]Ansible – a + tool that is another good example of simple architecture and boils down + to “just use ssh”. + + Speaking of SQLite, there’s a growing number of developers who advocate + using SQLite to run their websites. SQLite’s [101]“when to use SQLite” + page says “any site that gets fewer than 100K hits/day should work fine + with SQLite. The 100K hits/day figure is a conservative estimate, not a + hard upper bound. SQLite has been demonstrated to work with 10 times + that amount of traffic.” Here are some other SQLite success stories: + * [102]Litestream is an open source tool that provides streaming + replication for SQLite. Read author Ben Johnson’s article, [103]Why + I Built Litestream. + * Go developer David Crawshaw has an article about what he calls + [104]“one process programming” (with Go and SQLite), that can be + summed up with his phrase “don’t use N computers when 1 will do”. + He also created a [105]Go SQLite library that supports more + SQLite-specific features than the other drivers. + * Peewee ORM author Charles Leifer wrote an article [106]“Five + reasons you should use SQLite in 2016” that’s still very relevant + in 2021. It ends with “I hope you’ll give SQLite a try. Don’t + believe the FUD about it not being production-worthy, or not being + suitable for use in web-applications.” + * Sam Eaton of [107]Crave Cookie runs a $200,000 per month side + business (wow!) using a single server and SQLite. Read his + [108]Indie Hackers interview. + +Summing up + + Companies will do what companies do, and continue to make + flashy-looking, bloated websites that “convert” well. Maybe you can + have an influence at work, and come home to your better half and say + “honey, I shrunk the web”. Or maybe you’ll just focus on the small web + for your personal projects. (Disclaimer: I mostly do the latter – as + part of my day job, I work on [109]Juju, which is not a small system by + most measures.) + + Either way, I believe the “small web” is a compelling term and a + compelling aesthetic. Not necessarily in the visual sense, but in the + sense that you built it yourself, you understand all of it, and you run + it on a single server or static file host. + + There are thousands of excellent examples of small websites, and + hundreds of ways to create simple architectures – this essay touches on + only a few of the ones I’m passionate about. I’d love to hear your own + ideas and stories! Comment over at [110]Lobsters or [111]Hacker News or + [112]programming Reddit. + + I’d love it if you [113]sponsored me on GitHub – it will motivate me to + work on my open source projects and write more good content. Thanks! + +References + + 1. file:/// + 2. file:/// + 3. file:///cv/ + 4. file:///projects/ + 5. file:///writings/ + 6. file:///writings/non-tech/ + 7. mailto:benhoyt@gmail.com + 8. https://benhoyt.com/ + 9. mailto:benhoyt@gmail.com + 10. file:///var/folders/q9/qlz2w5251kzdfgn0np7z2s4c0000gn/T/L83225-8351TMP.html#small-software + 11. file:///var/folders/q9/qlz2w5251kzdfgn0np7z2s4c0000gn/T/L83225-8351TMP.html#small-websites + 12. file:///var/folders/q9/qlz2w5251kzdfgn0np7z2s4c0000gn/T/L83225-8351TMP.html#emphasize-server-side-not-javascript + 13. file:///var/folders/q9/qlz2w5251kzdfgn0np7z2s4c0000gn/T/L83225-8351TMP.html#static-sites-and-site-generators + 14. file:///var/folders/q9/qlz2w5251kzdfgn0np7z2s4c0000gn/T/L83225-8351TMP.html#fewer-dependencies + 15. file:///var/folders/q9/qlz2w5251kzdfgn0np7z2s4c0000gn/T/L83225-8351TMP.html#small-analytics + 16. file:///var/folders/q9/qlz2w5251kzdfgn0np7z2s4c0000gn/T/L83225-8351TMP.html#small-architectures-not-microservices + 17. https://basecamp.com/books + 18. https://neustadt.fr/essays/the-small-web/ + 19. https://ar.al/2020/08/07/what-is-the-small-web/ + 20. https://en.wikipedia.org/wiki/Forth_(programming_language) + 21. https://github.com/benhoyt/third + 22. https://en.wikipedia.org/wiki/Demoscene + 23. https://www.youtube.com/watch?v=jB0vBmiTr6o + 24. https://www.youtube.com/watch?v=RCh3Q08HMfs + 25. file:///var/folders/q9/qlz2w5251kzdfgn0np7z2s4c0000gn/T/L83225-8351TMP.html#fewer-dependencies + 26. https://cr.yp.to/bib/1995/wirth.pdf + 27. https://blog.brush.co.nz/2008/07/adobe-reader-9/ + 28. https://1mb.club/ + 29. https://news.ycombinator.com/item?id=25151773 + 30. https://512kb.club/ + 31. https://news.ycombinator.com/item?id=25450451 + 32. https://250kb.club/ + 33. https://news.ycombinator.com/item?id=25176663 + 34. https://10kbclub.com/ + 35. https://news.ycombinator.com/item?id=25556860 + 36. https://news.ycombinator.com/news + 37. https://lobste.rs/ + 38. https://sourcehut.org/ + 39. https://forgeperf.org/ + 40. https://sqlite.org/ + 41. https://sqlite.org/testing.html + 42. https://lwn.net/ + 43. https://lwn.net/Archives/GuestIndex/#Hoyt_Ben + 44. https://danluu.com/ + 45. https://lucumr.pocoo.org/ + 46. https://nullprogram.com/ + 47. http://eradman.com/ + 48. https://hugotunius.se/ + 49. https://prog21.dadgum.com/ + 50. https://jvns.ca/ + 51. https://sjmulder.nl/en/textonly.html + 52. https://giftyweddings.com/ + 53. https://news.ycombinator.com/item?id=26057078 + 54. https://news.ycombinator.com/item?id=11210860 + 55. https://indieweb.org/ + 56. https://small-tech.org/ + 57. https://news.ycombinator.com/item?id=24269071 + 58. https://indieweb.org/Homebrew_Website_Club + 59. https://indieweb.org/IndieWebCamps + 60. https://benhoyt.com/writings/seo-for-software-engineers/ + 61. https://stackoverflow.com/ + 62. https://blog.codinghorror.com/performance-is-a-feature/ + 63. https://news.ycombinator.com/ + 64. https://news.ycombinator.com/hn.js + 65. https://news.ycombinator.com/item?id=23876281 + 66. https://alistapart.com/article/understandingprogressiveenhancement/ + 67. https://www.reddit.com/ + 68. https://github.com/turbolinks/turbolinks + 69. https://turbo.hotwire.dev/ + 70. https://hey.com/ + 71. https://m.signalvnoise.com/html-over-the-wire/ + 72. https://alistapart.com/article/the-future-of-web-software-is-html-over-websockets/ + 73. https://benhoyt.com/writings/learning-elm/ + 74. https://pages.github.com/ + 75. https://jekyllrb.com/ + 76. https://gohugo.io/ + 77. https://staticsitegenerators.net/ + 78. https://www.davidhaney.io/npm-left-pad-have-we-forgotten-how-to-program/ + 79. https://github.com/juliangruber/isarray/blob/c9b0c5b4f44d366c9f51c7e85e70339bdeaa97b0/index.js#L3-L5 + 80. https://momentjs.com/ + 81. https://momentjs.com/docs/#/use-it/webpack/ + 82. https://date-fns.org/ + 83. https://golang.org/doc/modules/managing-dependencies + 84. https://research.swtch.com/deps + 85. https://go-proverbs.github.io/ + 86. http://youmightnotneedjquery.com/ + 87. https://casparwre.de/blog/stop-using-google-analytics/ + 88. https://lwn.net/Articles/822568/ + 89. https://www.goatcounter.com/ + 90. https://plausible.io/ + 91. https://lwn.net/Articles/824294/ + 92. https://www.theregister.com/2021/02/25/google_kubernetes_autopilot/ + 93. https://en.wikipedia.org/wiki/Conway's_law + 94. https://m.signalvnoise.com/the-majestic-monolith/ + 95. https://duckduckgo.com/?t=canonical&q=why+not+microservices&ia=web + 96. https://tailscale.com/blog/modules-monoliths-and-microservices/ + 97. https://stackexchange.com/performance + 98. https://giftyweddings.com/ + 99. https://aws.amazon.com/ec2/instance-types/t2/ + 100. https://www.ansible.com/ + 101. https://sqlite.org/whentouse.html + 102. https://litestream.io/ + 103. https://litestream.io/blog/why-i-built-litestream/ + 104. https://crawshaw.io/blog/one-process-programming-notes + 105. https://github.com/crawshaw/sqlite + 106. https://charlesleifer.com/blog/five-reasons-you-should-use-sqlite-in-2016/ + 107. https://cravecookie.com/ + 108. https://www.indiehackers.com/podcast/166-sam-eaton-of-crave-cookie + 109. https://jaas.ai/ + 110. https://lobste.rs/s/d6qwff/small_web_is_beautiful + 111. https://news.ycombinator.com/item?id=26305585 + 112. https://www.reddit.com/r/programming/comments/lvfdq9/the_small_web_is_beautiful/ + 113. https://github.com/sponsors/benhoyt/ diff --git a/static/archive/macwright-com-o4dndf.txt b/static/archive/macwright-com-o4dndf.txt new file mode 100644 index 0000000..9cb81bb --- /dev/null +++ b/static/archive/macwright-com-o4dndf.txt @@ -0,0 +1,344 @@ + #[1]macwright.com [2]macwright.com + +Tom MacWright + + tom@macwright.com + +Tom MacWright + + * [3]Writing + * [4]Reading + * [5]Photos + * [6]Projects + * [7]Drawings + * [8]About + +A year of Rails + + Railroad + + I spent most of 2020 working with [9]Ruby on Rails. I moved a project + from [10]Next.js + [11]Rust to… Rails, baby! Back to the future. My + earlier post on [12]Second-guessing the modern web was inspired by this + experience, that for the product we were building, a ‘modern’ stack was + not working as well as a traditional one. + + We didn’t do competitive analysis against Laravel, Django, or Phoenix. + They’re similar, not radically better or worse. There are multiple + acceptable solutions to a problem, and this was more a matter of + choosing the right kind of solution than pursuing some kind of perfect + choice and burning hours and motivation doing the window-shopping. + + What helped Rails win was that the team had a little more experience in + Ruby (with the exception of myself), and we found plenty of resources + for developing and deploying the stack. Rails fit perfectly into the + ideology of [13]Choosing boring technology. Another part of the product + would be the hard, innovative part, so it made no sense to grapple with + bleeding-edge web frameworks. + + This was a really fun experience. There’s a lot to love about Rails. + Other communities could learn a bit from the Ruby & Rails culture and + wisdom. I won’t implement everything in Rails, but it’ll be part of the + toolbox. + + Before this, I hadn’t touched the stuff. And I bet a lot of people are + like that - they came of age in the world of React and Go, and haven’t + tried anything even remotely similar to Rails. For their benefit, and + to debrief from 2020, here are some notes on the experience. Plus, + [14]Rails-like projects in JavaScript are ramping up quickly, and it’s + fun to know the origins. + +The good + +Debugging Rails apps is amazing + + A while ago, I [15]wrote on Twitter + + the real reason why javascript developers don’t use breakpoints and + use console.log is that breakpoints don’t work + + After years of working in JavaScript, I’m used to bad debugging + experiences. The Chrome debugger’s [16]automatic pause on caught + exceptions is amazing, sometimes. But throwing a debugger statement in + some React code is dodgy as hell. Sometimes it works, mostly it + doesn’t. You have to deal with code that might not have the right + [17]sourcemap to translate from bundled & minified code to original + source. Subtle abstractions like React hooks and advanced transpiler + stuff like [18]Regenerator mean that your code’s stacktrace probably + looks nothing like what you expect, with lots of internal garbage. + Sure, you can learn better techniques for diagnosing and debugging + errors, but it’s not just you - the debugging story in JavaScript is + pretty bad. This applies even to Node.js, where one of the debugging + stories is to connect Chrome’s debugger to a Node.js instance: a + finicky solution that doesn’t consistently work. + + In Rails, there is [19]byebug. You write byebug in your source code, + and you get an interactive REPL right there. It works in views, + controllers, database migrations, everywhere. It almost always works. + Variables are named what you expect. The whole system is paused at that + moment, and you can actually interact with it, using all of the Rails + utilities and your installed gems. + + If a page crashes unexpectedly, you get a similar REPL experience, in + your browser, automatically. With an automatically cleaned-up + stacktrace that excludes Rails’s own frames. Like the byebug interface, + this REPL actually works and is consistently helpful in finding root + causes. Rarely will you need to use puts to print something to the + console because this debugging system is so good. + +The magic mostly works + + Our Rails app didn’t have any require statements. You mention a + module’s name, and it’s automatically included, using [20]Zeitwerk, a + tool that comes standard with Rails. + + This kind of system was terrifying to me before. What if you + accidentally import something just by mentioning it? What if two things + have the same name and you import the wrong one? How do you really know + what’s happening? Sure, you’re happy now, with all of that annoying + importing and exporting taken care of, but the sky might fall. + + Or maybe it just… doesn’t. Maybe impure, vaguely risky techniques are + just a net positive over time, and making everything fully explicit + isn’t really necessary? Now when I’m using other systems, I wonder - + what if I could just mention one of my React components and it would + just… be there? Sure, the system would have to complain if there were + two components with the same name, and it would have to make + assumptions about directory structure, but overall, wouldn’t this be + nice? + + This applies to a lot of other parts of the system too. Rails is famous + for doing pluralization - you name a model Post and you automatically + get an interface called posts. But what, you ask, of words with uneven + pluralization rules? Rails actually [21]does the right thing, almost + always. And when it fails, you can override it. It actually just saves + time, reliably. + +Testing works + + I’ve tried to test front-end applications. I’ve set up [22]nightwatch, + [23]jest, [24]enzyme, [25]cypress, and probably 5-10 other frameworks. + Front-end testing is universally terrible. Projects like Cypress are + throwing untold hours into making it less terrible, taking on massive + amounts of complexity to abstract away from fickle browser behavior and + complex interactions. + + But it still sucks. Frontend testing has no good attributes: it’s + unreliable, hard to automate, hard to debug when it fails, and often + doesn’t even assert for important behaviors, so it doesn’t actually + identify regressions. Running frontend tests in CI is resource-heavy, + requiring you to set up headless X windows environments on servers or + use specialized CI services that produce screencasts of test runs. + + Testing fully-server-rendered applications, on the other hand, is + amazing. A vanilla testing setup with Rails & [26]RSpec can give you + fast, stable, concise, and actually-useful test coverage. You can + actually assert for behavior and navigate through an application like a + user would. These tests are solving a simpler problem - making requests + and parsing responses, without the need for a full browser or headless + browser, without multiple kinds of state to track. + + Not only do the tests work better, the testing culture is a completely + different universe. There are entire books written about how to write + RSpec tests that catch bugs, allow software evolution, and aren’t + filled with boilerplate. + +Gems are so powerful + + Powerful and dangerous. + + I’m used to modules as they work in other systems - Python, Node, Elm, + and so on. They provide objects, functions, and variables that you can + import and combine into your code explicitly. Usually they sit on some + specific level of abstraction - it’s a utility for connecting to + servers or a React component you can use. + + Gems can do so much more. You install something like [27]Devise into + your system and it adds views, routes, methods, utilities, you name it. + It’s not like “loading some functions”, it’s more like composing a + whole different app into your app, implicitly. + + This is obviously terrifying. It means that you can’t look at your + directories of views and your file of routes.rb and know what exists at + a glance. There are other layers, lurking in the ephemeral space of + third-party code. They interact in serious but uncertain ways. + + But it’s also pretty incredible - the idea that something like + [28]passport, Node’s middleware, could instead be a full-fledged + authentication system. It means that you have to write a lot less code, + and it also means that the people who use that code have a lot more + code in common. That gems can work on a higher level of abstraction, + making it possible to cobble together software faster, to write less + ‘glue code.’ + +There’s so much good writing about Rails + + Even if you don’t write Ruby, you should pay attention to [29]Sandi + Metz. She’s incredibly wise and has so many incredible ideas to share. + + And then there’s [30]arkency, [31]ThoughtBot, and so many other + thoughtful writers with years of experience in Rails. Sometimes it’s a + little shocking to google for some obscure problem and see a decade of + discussion about it. + + The best practices are also formalized into tools like [32]Code Climate + and [33]reek. I’ve never seen so many actually-useful suggestions come + out of automated systems as I did in the world of Ruby and Rails. + +Ruby + + Ruby is a pretty pleasant language to work in. Sure, it has a lot of + syntax and a sprawling standard library, but you don’t have to use all + of that if you don’t want to. It took me a while to adjust to the + object-oriented way of doing things - in particular, the idea that you + can’t just have a free-range function floating out there, unassociated + with a class or module, like you can in JavaScript. And you can’t just + create an arbitrary one-off object - you either need to define a class + to create an object, or use a Hash to store data. + + But Ruby’s standard library isn’t that huge. I’ve seen JavaScript’s + ‘standard library’ grow a lot too, and frankly it’s nice to have + methods like [34]String.prototype.padStart instead of having every + little thing in userspace. The only part that felt actively weird was + [35]activesupport - a gem that extends Ruby’s core objects, but is part + of Rails. It felt weird to have string methods that would only work if + your environment was Rails. + + The [36]Dash app for documentation rocketed from my pile of unused + tools to an absolute must-have. In the world of Ruby and Rails, with + most gems having pretty good, semi-standard documentation, you can + search for, and get answers, super fast. The Ruby language + documentation and the Rails documentation is absolutely great. The + JavaScript equivalent - [37]MDN - pales in comparison. + +The bad + +The asset pipeline + + Remember SASS and the YUI Compressor? These are, unfortunately, + defaults in the [38]asset pipeline. There’s [39]Webpacker too, which + has a parallel approach to CSS and images as the asset pipeline. It has + [40]opinionated integrations with stuff like React. Ah, and I should + mention that Rails’s [41]JavaScript utilities are written in… + CoffeeScript. + + I get it - it’s hard to keep up with the latest trends in frontend. But + this is one area where Rails’s strong backwards compatibility feels + iffy. I wish that Rails was more opinionated about the frontend, and + that it had better opinions. + +Best practice churn + + In Smalltalk, everything happens somewhere else. - [42]Adele + Goldberg + + Ruby, as today’s Smalltalk, has the same issue. The community venerates + small - that methods should be short, files should be small, complexity + should be controlled. This begs the question of where it all goes - + certainly not in controllers, which should be skinny, and not in views, + which should have very little logic at all, and maybe [43]not in models + either. Maybe in [44]Service Objects, or policies, or decorators? + + I found myself falling victim to this. I’d try to win CodeClimate’s + approval by moving code around, perfecting the art of making everything + small or at most medium-sized, extracting concerns until most files + looked okay. This was time well-spent on learning, but I have to admit + that it doesn’t actually matter for an early-stage startup’s product. + + In stark contrast to the folks who say that Rails is for prototypes, + there’s a lot of attention paid to long-lived engineering efforts - + adopting patterns that let many team work on the same ‘monolith’, + identifying [45]shotgun surgery - a term I first heard from Sandi Metz. + +ActiveRecord is great, except when it isn’t + + One of the hardest bugs we encountered happened with ActiveRecord. We + were creating a set of changes to apply to a model, using their + in-memory instances to do some stuff, and then finally applying them. + This broke because one of the ActiveRecord methods automatically + ‘committed’ those changes, quietly. + + ActiveRecord is kind of like this - a lot of the times it’s pleasantly + implicit, letting you just assign a value and automatically saving that + to the database. But then it’ll do something implicitly that you don’t + want to happen, and figuring out why this happened and how to stop it + from happening is a real challenge. + + Most of the time, to be clear - it’s a really great system. It provides + lots of ways to generate efficient-enough queries, knowing full well + that SQL performance is often the bottleneck of web applications. Most + of the time it’s really nice that it automatically casts and + deserializes query results. But when it goes bad, the diagnosis and the + cure can be pretty ugly. + + The other issue with ActiveRecord is that it has efficient methods and + inefficient methods right next to each other, because it automatically + turns your ‘query builder’ into an array when you call array-like + methods. So, for example: +Dogs.all.max_by(&:height) + + Is wildly inefficient. It might fetch and deserialized a million + records just to sort them and give you the first. On the other hand, +Dogs.order(height: :desc).first + + Is fast - it sorts in the database and fetches a single record. Rails + is both offering smart and easy ways to write optimized code, but also + making it really easy to write inefficient code. + __________________________________________________________________ + + A Rails-like framework is a really good thing to have in your toolbox, + and there’s a lot to learn from the Ruby community. My hope is that we + see these sorts of abstractions in new languages and frameworks, and + see more of the Ruby community’s culture filter into the programming + world. + + February 18, 2021 [46]@tmcw + +References + + 1. https://macwright.com/rss.xml + 2. https://macwright.com/atom.xml + 3. file:/// + 4. file:///reading/ + 5. file:///photos/ + 6. file:///projects/ + 7. file:///drawings/ + 8. file:///about/ + 9. https://rubyonrails.org/ + 10. https://nextjs.org/ + 11. https://www.rust-lang.org/ + 12. https://macwright.com/2020/05/10/spa-fatigue.html + 13. http://boringtechnology.club/ + 14. https://macwright.com/2020/10/28/if-not-spas.html + 15. https://twitter.com/tmcw/status/1321133460501585922 + 16. https://developers.google.com/web/updates/2015/05/automatically-pause-on-any-exception + 17. https://www.html5rocks.com/en/tutorials/developertools/sourcemaps/ + 18. https://github.com/facebook/regenerator + 19. https://github.com/deivid-rodriguez/byebug + 20. https://github.com/fxn/zeitwerk + 21. https://weblog.rubyonrails.org/2005/8/25/10-reasons-rails-does-pluralization/ + 22. https://nightwatchjs.org/ + 23. https://jestjs.io/ + 24. https://enzymejs.github.io/enzyme/ + 25. https://www.cypress.io/ + 26. https://rspec.info/ + 27. https://github.com/heartcombo/devise + 28. http://www.passportjs.org/ + 29. https://sandimetz.com/ + 30. https://blog.arkency.com/ + 31. https://thoughtbot.com/blog/ + 32. https://codeclimate.com/ + 33. https://github.com/troessner/reek + 34. https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String/padStart + 35. https://rubygems.org/gems/activesupport/versions/6.1.1 + 36. https://kapeli.com/dash + 37. https://developer.mozilla.org/en-US/ + 38. https://guides.rubyonrails.org/asset_pipeline.html + 39. https://edgeguides.rubyonrails.org/webpacker.html + 40. https://github.com/rails/webpacker#integrations + 41. https://github.com/rails/rails/tree/main/actionview/app/assets/javascripts + 42. https://en.wikipedia.org/wiki/Adele_Goldberg_(computer_scientist) + 43. https://thoughtbot.com/blog/skinny-controllers-skinny-models + 44. https://codeclimate.com/blog/7-ways-to-decompose-fat-activerecord-models/ + 45. https://en.wikipedia.org/wiki/Shotgun_surgery + 46. https://twitter.com/intent/follow?screen_name=tmcw&user_id=1458271 diff --git a/static/archive/maggieappleton-com-7am49k.txt b/static/archive/maggieappleton-com-7am49k.txt new file mode 100644 index 0000000..c99bfc5 --- /dev/null +++ b/static/archive/maggieappleton-com-7am49k.txt @@ -0,0 +1,150 @@ + #[1]Main RSS Feed + + [2]Home + The Garden (BUTTON) + [3]Now + [4]About + (BUTTON) + + notes + + evergreen + +What App is That? + + A guide to the apps and tools I use to create illustrations + * [5]How to Illustrate + + Planted about 3 years agoLast tended about 2 years ago + + (BUTTON) Back To Top + + "What app is that?" + + [6] + +I'm a Promiscuous Polytooler + + I use wide variety of different tools and apps for different kinds of + visual creations. I'm not wedded to any one tool in particular – they + all have their strengths and weaknesses. I'll use whatever fits the + task at hand and move work between them liberally. + + Here's all the apps and hardware that might be involved in a particular + creation... + + None of these are affiliate links - I'm just pointing you to official + sites for more context + [7] + +Workflows + + And here's a couple of my common workflows for different styles of + illustrations and visuals... + +1. Illustrated notes + + Anything I make that has a painterly and loose hand-drawn feel was made + in Procreate on the iPad or Photoshop on the Wacom Cintiq. Or probably + a combination – it's easy to move files back and forth between the two + and the tools they offer are very similar. + + Illustrations like these... + + Both of these applications allow you to draw in “raster” graphics, + meaning you paint pixels onto a canvas. They require a decent level of + hand-skills to make sure your lines aren't wobbly, although both + applications have smoothing features to help with that. + + When I'm in Procreate I use a small selection of brushes I've gathered + over the years. It's hard for me to remember where they're all from, + and I've customised the majority of them to suit my personal prefs. + Most of them were originally from Max Ulichney's brushes. I have the + essentials set ($2), the painters set ($8), and the comics set ($15), + and can vouch they're all great. + + I move these pieces to Photoshop if I want to work on a larger screen, + or have accidentally enlarged the canvas to a 14000px wide sprawling + set of sketches that Procreate can't open without crashing. + +2. Polished vector illustrations + + Illustrations that look more “polished” are made primarily in Adobe + Illustrator, with a touch of Photoshop at the end for lighting effects + and texture. + + Pieces like these... + + These illustrations are all vector-based, meaning we use mathematical + curves to define their shapes, rather than painted pixels. Vectors are + great for create hard, crisp edges and working with perfect geometric + forms. + + While I love vectors for laying down the foundation shapes of these, + I'll move them over the Photoshop once they're 90% done to adjust the + colors, add more subtlety to the lighting and shadows, and chuck a bit + of texture on the top so they feel more tangible. + + Want to share? (BUTTON) Tell Twitter About It + +3 Backlinks + +Why You Own an iPad and Still Can't Draw + + The failure of drawing materials without mediums and meat + +Frequently Asked Questions + + Questions I am often asked to answer + +The Best Illustration Books and Courses + + My favourite resources for learning to draw and developing your visual + thinking skills + +Mentions around the web + + Tomiwa 😃 + Maggie Appleton - indieweb.social/@maggie + 2 Likes and Retweets + +Want to stay up to date? + + (BUTTON) Subscribe via RSS Feed + © 2023 Maggie Appleton + * [8]The Garden + * [9]Essays + * [10]About + * [11]Notes + * [12]Now + * [13]Patterns + * [14]Library + * [15]Projects + * [16]Colophon + +References + + Visible links: + 1. file:///rss.xml + 2. file:/// + 3. file:///now + 4. file:///about + 5. file:///topics/how-to-illustrate + 6. file:///var/folders/q9/qlz2w5251kzdfgn0np7z2s4c0000gn/T/L71674-9587TMP.html#im-a-promiscuous-polytooler + 7. file:///var/folders/q9/qlz2w5251kzdfgn0np7z2s4c0000gn/T/L71674-9587TMP.html#workflows + 8. file:///garden + 9. file:///essays + 10. file:///about + 11. file:///notes + 12. file:///now + 13. file:///patterns + 14. file:///library + 15. file:///projects + 16. file:///colophon + + Hidden links: + 18. https://github.com/MaggieAppleton + 19. https://uk.linkedin.com/in/maggieappleton + 20. https://dribbble.com/mappleton + 21. https://twitter.com/Mappletons + 22. https://indieweb.social/@maggie diff --git a/static/archive/maggieappleton-com-fube9k.txt b/static/archive/maggieappleton-com-fube9k.txt new file mode 100644 index 0000000..98f5697 --- /dev/null +++ b/static/archive/maggieappleton-com-fube9k.txt @@ -0,0 +1,135 @@ + #[1]Main RSS Feed + + [2]Home + The Garden (BUTTON) + [3]Now + [4]About + (BUTTON) + + Essays + + budding + +Why You Own an iPad and Still Can't Draw + + The failure of drawing materials without mediums and meat + * [5]How to Illustrate + + Planted almost 3 years agoLast tended almost 3 years ago + + (BUTTON) Back To Top + + Assumed Audience + + Anyone who thinks they can't draw, but would like to learn + + They message me a lot. + + Which iPad should I buy? What app do you use? What brush is that? + What size should my canvas be? + + These questions aren't wrong. In fact they're perfectly reasonable. + + I'm vocal about the fact many of my illustrations are made on in an app + called . I have a full post about my drawing equipment and workflows + over at + [6]What App is That? + + How are you supposed to draw if you don't also have these fancy tools? + + This is the tricky bit. + + If you go out and buy yourself these same things, you'll have all the + right materials to draw. But that's only the dressing on the drawing + dish. + [7] + +What you have is Material without the Medium or the Meat + + What on earth do I mean by material, medium, and meat? + __________________________________________________________________ + + [8] + +Moving past materials + + Worrying about the materials should take up - at most - 10% of your + attention and concern. Focus 70% of your attention on learning the + medium while you're just starting out. + + You can keep 20% of your focus on the Meat. But I wouldn't worry too + much about communicating original, profound ideas at first. Doing so in + addition to learning a whole new language is going to be overwhelming. + + In the same way it's a bad idea to learn Spanish while simultaneously + trying to write a philosophy dissertation in it. + + Once you get more comfortable “speaking" in visual language, you'll be + able to shift a much higher percentage of your attention onto the Meat. + You'll get to focus on The Thing You Want to Say, and know enough + visual language to say it well. + + That's the ideal I'm currently striving for. To reach a point where the + Material is irrelevant, the Medium is a baked into my subconscious, and + I'm all about the Meat. + + That's the goal. Don't let the shiny iPad reflection blind you. + + Get past picking the Material. Focus on the Medium. Aim for the Meat. + + Want to share? (BUTTON) Tell Twitter About It + +1 Backlinks + +The Best Illustration Books and Courses + + My favourite resources for learning to draw and developing your visual + thinking skills + +Mentions around the web + + Tomiwa 😃 + Maggie Appleton - indieweb.social/@maggie + 2 Likes and Retweets + +Want to stay up to date? + + (BUTTON) Subscribe via RSS Feed + © 2023 Maggie Appleton + * [9]The Garden + * [10]Essays + * [11]About + * [12]Notes + * [13]Now + * [14]Patterns + * [15]Library + * [16]Projects + * [17]Colophon + +References + + Visible links: + 1. file:///rss.xml + 2. file:/// + 3. file:///now + 4. file:///about + 5. file:///topics/how-to-illustrate + 6. file:///apps + 7. file:///var/folders/q9/qlz2w5251kzdfgn0np7z2s4c0000gn/T/L84552-9249TMP.html#what-you-have-is-material-without-the-medium-or-the-meat + 8. file:///var/folders/q9/qlz2w5251kzdfgn0np7z2s4c0000gn/T/L84552-9249TMP.html#moving-past-materials + 9. file:///garden + 10. file:///essays + 11. file:///about + 12. file:///notes + 13. file:///now + 14. file:///patterns + 15. file:///library + 16. file:///projects + 17. file:///colophon + + Hidden links: + 19. https://github.com/MaggieAppleton + 20. https://uk.linkedin.com/in/maggieappleton + 21. https://dribbble.com/mappleton + 22. https://twitter.com/Mappletons + 23. https://indieweb.social/@maggie diff --git a/static/archive/softwarecrisis-dev-7c7z9g.txt b/static/archive/softwarecrisis-dev-7c7z9g.txt new file mode 100644 index 0000000..33c48d4 --- /dev/null +++ b/static/archive/softwarecrisis-dev-7c7z9g.txt @@ -0,0 +1,1069 @@ + #[1]Out of the Software Crisis (Newsletter) [2]Out of the Software + Crisis (Newsletter) + + [3]Out of the Software Crisis + + Bird flying logo [4]Newsletter [5]Book [6]AI Book [7]Archive [8]Author + +Modern software quality, or why I think using language models for programming is + a bad idea + + By Baldur Bjarnason + + This essay is based on a talk I gave at [9]Hakkavélin, a hackerspace in + Reykjavík. I had a wonderful time presenting to a lovely crowd, full of + inquisitive and critically-minded people. Their questions and the + discussion afterwards led to a number of improvements and + clarifications as I turned my notes into this letter. This resulted in + a substantial expansion of this essay. Many of the expanded points, + such as the ones surrounding language model security, come directly + from these discussions. + + Many thanks to all of those who attended. The references for the + presentation are also the references for this essay, which you can find + all the way down in the footnotes section. + + The best way to support this newsletter or my blog is to buy one of my + books, [10]The Intelligence Illusion: a practical guide to the business + risks of Generative AI or [11]Out of the Software Crisis. Or, you can + buy them both [12]as a bundle. + +The software industry is very bad at software + + Here’s a true story. Names withheld to protect the innocent. + + A chain of stores here in Iceland recently upgraded their point-of-sale + terminals to use new software. + + Disaster, obviously, ensued. The barcode scanner stopped working + properly, leading customer to be either overcharged or undercharged. + Everything was extremely slow. The terminals started to lock up + regularly. The new invoice printer sucked. A process that had been + working smoothly was now harder and took more time. + + The store, where my “informant” is a manager, deals with a lot of + businesses, many of them stores. When they explain to their customers + why everything is taking so long, their answer is generally the same: + + Ah, software upgrade. The same happened to us when we upgraded our + terminals. + + This is the norm. + + The new software is worse in every way than what it’s replacing. + Despite having a more cluttered UI, it seems to have omitted a bunch of + important features. Despite being new and “optimised”, it’s + considerably slower than what it’s replacing. + + This is also the norm. + + Switching costs are, more often than not, massive for business + software, and purchases are not decided by anybody who actually uses + it. The quality of the software disconnects from sales performance very + quickly in a growing software company. The company ends up “owning” the + customer and no longer has any incentive to improve the software. In + fact, because adding features is a key marketing and sales tactic, the + software development cycle becomes an act of intentional, controlled + deterioration. + + Enormous engineering resources go into finding new ways to minimise the + deterioration—witness Microsoft’s “ribbon menu”, a widget invented + entirely to manage the feature escalation mandated by marketing. + + This is the norm. + + This has always been the norm, from the early days of software. + + The software industry is bad at software. Great at shipping features + and selling software. Bad at the software itself. + +Why I started researching “AI” for programming + + In most sectors of the software industry, sales performance and product + quality are disconnected. + + By its nature software has enormous margins which further cushion it + from the effect of delivering bad products. + + The objective impact of poor software quality on the bottom lines of + companies like Microsoft, Google, Apple, Facebook, or the retail side + of Amazon is a rounding error. The rest only need to deliver usable + early versions, but once you have an established customer base and an + experienced sales team, you can coast for a long, long time without + improving your product in any meaningful way. + + You only need to show change. Improvements don’t sell, it’s freshness + that moves product. It’s like store tomatoes. Needs to look good and be + fresh. They’re only going to taste it after they’ve paid, so who cares + about the actual quality. + + Uptime reliability is the only quality measurement with a real impact + on ad revenue or the success of enterprise contracts, so that’s the + only quality measurement that ultimately matters to them. + + Bugs, shoddy UX, poor accessibility—even when accessibility is required + by law—are non-factors in modern software management, especially at + larger software companies. + + The rest of us in the industry then copy their practices, and we mostly + get away with it. Our margins may not be as enormous as Google’s, but + they are still quite good compared to non-software industries. + + We have an industry that’s largely disconnected from the consequences + of making bad products, which means that we have a lot of successful + but bad products. + + The software crisis + + Research bears this out. I pointed out in my 2021 essay [13]Software + Crisis 2.0 that very few non-trivial software projects are successful, + even when your benchmarks are fundamentally conservative and short + term. + + For example, the following table is from [14]a 2015 report by the + Standish Group on their long term study in software project success: + + SUCCESSFUL CHALLENGED FAILED TOTAL + Grand 6% 51% 43% 100% + Large 11% 59% 30% 100% + Medium 12% 62% 26% 100% + Moderate 24% 64% 12% 100% + Small 61% 32% 7% 100% + + The Chaos Report 2015 resolution by project size + + This is based on data that’s collected and anonymised from a number of + organisations in a variety of industries. You’ll note that very few + projects outright succeed. Most of them go over budget or don’t deliver + the functionality they were supposed to. A frightening number of large + projects outright fail to ship anything usable. + + In my book [15]Out of the Software Crisis, I expanded on this by + pointing out that there are many classes and types of bugs and defects + that we don’t measure at all, many of them catastrophic, which means + that these estimates are conservative. Software project failure is + substantially higher than commonly estimated, and success if much rarer + than the numbers would indicate. + + The true percentage of large software projects that are genuinely + successful in the long term—that don’t have any catastrophic bugs, + don’t suffer from UX deterioration, don’t end up having core issues + that degrade their business value—is probably closer to 1–3%. + + The management crisis + + We also have a management crisis. + + The methods of top-down-control taught to managers are + counterproductive for software development. + * Managers think design is about decoration when it’s the key to + making software that generates value. + * Trying to prevent projects that are likely to fail is harmful for + your career, even if the potential failure is wide-ranging and + potentially catastrophic. + * When projects fail, it’s the critics who tried to prevent disaster + who are blamed, not the people who ran it into the ground. + * Supporting a project that is guaranteed to fail is likely to + benefit your career, establish you as a “team player”, and protects + you from harmful consequences when the project crashes. + * Teams and staff management in the software industry commonly + ignores every innovation and discovery in organisational + psychology, management, and systems-thinking since the early + sixties and operate mostly on management ideas that Henry Ford + considered outdated in the 1920s. + + We are a mismanaged industry that habitually fails to deliver usable + software that actually solves the problems it’s supposed to. + + Thus, [16]Weinberg’s Law: + + If builders built buildings the way programmers wrote programs, then + the first woodpecker that came along would destroy civilization. + + It’s into this environment that “AI” software development tools appear. + + The punditry presented it as a revolutionary improvement in how we make + software. It’s supposed to fix everything. + + —This time the silver bullet will work! + + Because, of course, we have had such a great track record with + [17]silver bullets. + + So, I had to dive into it, research it, and figure out how it really + worked. I needed to understand how generative AI works, as a system. I + haven’t researched any single topic to this degree since I finished my + PhD in 2006. + + This research led me to write my book [18]The Intelligence Illusion: a + practical guide to the business risks of Generative AI. In it, I take a + broader view and go over the risks I discovered that come with business + use of generative AI. + + But, ultimately, all that work was to answer the one question that I + was ultimately interested in: + + Is generative AI good or bad for software development? + + To even have a hope of answering this, we first need to define our + terms, because the conclusion is likely to vary a lot depending on how + you define “AI” or even "software development. + + A theory of software development as an inclusive system + + Software development is the entire system of creating, delivering, and + using a software project, from idea to end-user. + + That includes the entire process on the development side—the idea, + planning, management, design, collaboration, programming, testing, + prototyping—as well as the value created by the system when it has been + shipped and is being used. + + My model is that of [19]theory-building. From my essay on + theory-building, which itself is an excerpt from [20]Out of the + Software Crisis: + + Beyond that, software is a theory. It’s a theory about a particular + solution to a problem. Like the proverbial garden, it is composed of + a microscopic ecosystem of artefacts, each of whom has to be treated + like a living thing. The gardener develops a sense of how the parts + connect and affect each other, what makes them thrive, what kills + them off, and how you prompt them to grow. The software project and + its programmers are an indivisible and organic entity that our + industry treats like a toy model made of easily replaceable lego + blocks. They believe a software project and its developers can be + broken apart and reassembled without dying. + + What keeps the software alive are the programmers who have an + accurate mental model (theory) of how it is built and works. That + mental model can only be learned by having worked on the project + while it grew or by working alongside somebody who did, who can help + you absorb the theory. Replace enough of the programmers, and their + mental models become disconnected from the reality of the code, and + the code dies. That dead code can only be replaced by new code that + has been ‘grown’ by the current programmers. + + Design and user research is an integral part of the mental model the + programmer needs to build, because none of the software components + ultimately make sense without the end-user. + + But, design is also vital because it is, to reuse Donald G. + Reinertsen’s definition from Managing the Design Factory (p. 11), + design is economically useful information that generally only becomes + useful information through validation of some sort. Otherwise it’s just + a guess. + + The economic part usually comes from the end-user in some way. + + This systemic view is inclusive by design as you can’t accurately + measure the productivity or quality of a software project unless you + look at it end to end, from idea to end-user. + * If it doesn’t work for the end-user, then it’s a failure. + * If the management is dysfunctional, then the entire system is + dysfunctional. + * If you keep starting projects based on unworkable ideas, then your + programmer productivity doesn’t matter. + + Lines of code isn’t software development. Working software, + productively used, understood by the developers, is software + development. + +A high-level crash course in language models + + Language models, small or large, are today either used as autocomplete + copilots or as chatbots. Some of these language model tools would be + used by the developer, some by the manager or other staff. + + I’m treating generative media and image models as a separate topic, + even when they’re used by people in the software industry to generate + icons, graphics, or even UIs. They matter as well, but don’t have the + same direct impact on software quality. + + To understand the role these systems could play in software + development, we need a little bit more detail on what language models + are, how they are made, and how they work. + + Most modern machine learning models are layered networks of parameters, + each representing its connection to its neighbouring parameters. In a + modern transformer-based language model most of these parameters are + floating point numbers—weights—that describe the connection. Positive + numbers are an excitatory connection. Negative numbers are inhibitory. + + These models are built by feeding data through a tokeniser that breaks + text into tokens—often one word per token—that are ultimately fed into + an algorithm. That algorithm constructs the network, node by node, + layer by layer, based on the relationships it calculates between the + tokens/words. This is done in several runs and, usually, the developer + of the model will evaluate after each run that the model is progressing + in the right direction, with some doing more thorough evaluation at + specific checkpoints. + + The network is, in a very fundamental way, a mathematical derivation of + the language in the data. + + A language model is constructed from the data. The transformer code + regulates and guides the process, but the distributions within the data + set are what defines the network. + + This process takes time—both collecting and managing the data set and + the build process itself—which inevitably introduces a cut-off point + for the data set. For OpenAI and Anthropic, that cut-off point is in + 2021. For Google’s PaLM2 it’s early 2023. + __________________________________________________________________ + + Aside: not a brain + + This is very, very different from how a biological neural network + interacts with data. A biological brain is modified by input and + data—its environment—but its construction is derived from nutrition, + its chemical environment, and genetics. + + The data set, conversely, is a deep and fundamental part of the + language model. The algorithm’s code provides the process while the + weights themselves are derived from the data, and the model itself is + dead and static during input and output. + + The construction process of a neural network is called “training”, + which is yet another incredibly inaccurate term used by the industry. + * A pregnant mother isn’t “training” the fetus. + * A language model isn’t “trained” from the data, but constructed. + + This is nonsense. + + But this is the term that the AI industry uses, so we’re stuck with it. + + A language model is a mathematical model built as a derivation of its + training data. There is no actual training, only construction. + + This is also why it’s inaccurate to say that these systems are inspired + by their training data. Even though genes and nutrition make an + artist’s mind they are not in what any reasonable person would call + “their inspiration”. Even when they are sought out for study and + genuine inspiration, it’s our representations of our understanding of + the genes that are the true source of inspiration. Nobody sticks their + hand in a gelatinous puddle of DNA and spontaneously gets inspired by + the data it encodes. + + Training data are construction materials for a language models. A + language model can never be inspired. It is itself a cultural artefact + derived from other cultural artefacts. + + The machine learning process is loosely based on decades-old grossly + simplified models of how brains work. + + A biological neuron is a complex system in its own right—one of the + more complex cells in an animal’s body. In a living brain, a biological + neuron will use electricity, multiple different classes of + neurotransmitters, and timing to accomplish its function in ways that + we still don’t fully understand. It even has its own [21]built-in + engine for chemical energy. + + The brain as a whole is composed of not just a massive neural network, + but also layers of hormonal chemical networks that dynamically modify + its function, both granularly and as a whole. + + The digital neuron—a single signed floating point number—is to a + biological neuron what a flat-head screwdriver is to a Tesla. + + They both contain metal and that’s about the extent of their + similarity. + + The human brain contains roughly 100 billion neuron cells, a layered + chemical network, and a cerebrovascular system that all integrate as a + whole to create a functioning, self-aware system capable of general + reasoning and autonomous behaviour. This system is multiple orders of + magnitude more complex than even the largest language model to date, + both in terms of individual neuron structure, and taken as a whole. + + It’s important to remember this so that we don’t fall for marketing + claims that constantly imply that these tools are fully functioning + assistants. + __________________________________________________________________ + + The prompt + + After all of this, we have a data set which can be used to generate + text in response to prompts. + + Prompts such as: + + Who was the first man on the moon? + + The input phrase, or prompt, has no structure beyond the linguistic. + It’s just a blob of text. You can’t give the model commands or + parameters separately from other input. Because of this, if your model + lets a third party enter text, an attacker will always be able to + bypass whatever restrictions you put on it. Control prompts or prefixes + will be discovered and countermanded. Delimiters don’t work. + Fine-tuning the model only limits the harm, but doesn’t prevent it. + + This is called a prompt injection and what it means is that model input + can’t be secured. You have to assume that anybody that can send text to + the model has full access to it. + + Language models need to be treated like an unsecured client and only + very carefully integrated into other systems. + + The response + + What you’re likely to get back from that prompt would be something + like: + + On July 20, 1969, Neil Armstrong became the first human to step on + the moon. + + This is NASA’s own phrasing. Most answers on the web are likely to be + variations on this, so the answer from a language model is likely to be + so too. + * The moon landing happens to be a fact, but the language model only + knows it as a text. + + The prompt we provided is strongly associated in the training data set + with other sentences that are all variations of NASA’s phrasing of the + answer. The model won’t answer with just “Neil Armstrong” because it + isn’t actually answering the question, it’s responding with the text + that correlates with the question. It doesn’t “know” anything. + * The language model is fabricating a mathematically plausible + response, based on word distributions in the training data. + * There are no facts in a language model or its output. Only + memorised text. + + It only fabricates. It’s all “hallucinations” all the way down. + + Occasionally those fabrications correlate with facts, but that is a + mathematical quirk resulting from the fact that, on average, what + people write roughly correlates with their understanding of a factual + reality, which in turn roughly correlates with a factual reality. + + A knowledge system? + + To be able to answer that question and pass as a knowledge system, the + model needs to memorise the answer, or at least parts of the phrase. + + Because “AI” vendors are performing a sleight-of-hand here and + presenting statistical language synthesis engines as knowledge + retrieval systems, their focus in training and testing is on “facts” + and minimising “falsehoods”. The model has no notion of either, as it’s + entirely a language model, so the only way to square this circle is for + the model to memorise it all. + * To be able to answer a question factually, not “hallucinate”, and + pass as a knowledge system, the model needs to memorise the answer. + * The model doesn’t know facts, only text. + * If you want a fact from it, the model will need to memorise text + that correlates with that fact. + + “Dr. AI”? + + Vendors then compound this by using human exams as benchmarks for + reasoning performance. The problem is that bar exams, medical exams, + and diagnosis tests are specifically designed to mostly test rote + memorisation. That’s what they’re for. + + The human brain is bad at rote memorisation and generally it only + happens with intensive work and practice. If you want to design a test + that’s specifically intended to verify that somebody has spent a large + amount of time studying a subject, you test for rote memorisation. + + Many other benchmarks they use, such as those related to programming + languages also require memorisation, otherwise the systems would just + constantly make up APIs. + * Vendors use human exams as benchmarks. + * These are specifically designed to test rote memorisation, because + that’s hard for humans. + * Programming benchmarks also require memorisation. Otherwise, you’d + only get pseudocode. + + Between the tailoring of these systems for knowledge retrieval, and the + use of rote memorisation exams and code generation as benchmarks, the + tech industry has created systems where memorisation is a core part of + how they function. In all research to date, memorisation has been key + to language model performance in a range of benchmarks.^[22][1] + + If you’re familiar with storytelling devices, this here would be a + [23]Chekhov’s gun. Observe! The gun is above the mantelpiece: + + 👉🏻👉🏻 memorisation! + + Make a note of it, because those finger guns are going to be fired + later. + + Biases + + Beyond question and answer, these systems are great at generating the + averagely plausible text for a given prompt. In prose, current system + output smells vaguely of sweaty-but-quiet LinkedIn desperation and + over-enthusiastic social media. The general style will vary, but it’s + always going to be the most plausible style and response based on the + training data. + + One consequence of how these systems are made is that they are + constantly backwards-facing. Where brains are focused on the present, + often to their detriment, “AI” models are built using historical data. + + The training data encompasses thousands of diverse voices, styles, + structures, and tones, but some word distributions will be more common + in the set than others and those will end up dominating the output. As + a result, language models tend to lean towards the “racist grandpa who + has learned to speak fluent LinkedIn” end of the spectrum.^[24][2] + + This has implications for a whole host of use cases: + * Generated text is going to skew conservative in content and + marketing copy in structure and vocabulary. (Bigoted, prejudiced, + but polite and inoffensively phrased.) + * Even when the cut-off date for the data set is recent, it’s still + going to skew historical because what’s new is also comparatively + smaller than the old. + * Language models will always skew towards the more common, middling, + mediocre, and predictable. + * Because most of these models are trained on the web, much of which + is unhinged, violent, pornographic, and abusive, some of that + language will be represented in the output. + + Modify, summarise, and “reason” + + The superpower that these systems provide is conversion or + modification. They can, generally, take text and convert it to another + style or structure. Take this note and turn it into a formal prose, and + it will! That’s amazing. I don’t think that’s a trillion-dollar + industry, but it’s a neat feature that will definitely be useful. + + They can summarise text too, but that’s much less reliable than you’d + expect. It unsurprisingly works best with text that already provides + its own summary, such as a newspaper article (first paragraphs always + summarise the story), academic paper (the abstract), or corporate + writing (executive summary). Anything that’s a mix of styles, voices, + or has an unusual structure won’t work as well. + + What little reasoning they do is entirely based on finding through + correlation and re-enacting prior textual descriptions of reasoning. + They fail utterly when confronted with adversarial or novel examples. + They also fail if you rephrase the question so that it no longer + correlates with the phrasing in the data set.^[25][3] + + So, not actual reasoning. “Reasoning”, if you will. In other “AI” model + genres these correlations are often called “shortcuts”, which feels + apt. + + To summarise: + * Language models are a mathematical expression of the training data + set. + * Have very little in common with human brains. + * Rely on inputs that can’t be secured. + * Lie. Everything they output is a fabrication. + * Memorise heavily. + * Great for modifying text. No sarcasm. Genuinely good at this. + * Occasionally useful for summarisation if you don’t mind being lied + to regularly. + * Don’t actually reason. + +Why I believe “AI” for programming is a bad idea + + If you recall from the start of this essay, I began my research into + machine learning and language models because I was curious to see if + they could help fix or improve the mess that is modern software + development. + + There was reason to be hopeful. Programming languages are more uniform + and structured than prose, so it’s not too unreasonable to expect that + they might lend themselves to language models. Programming language + output can often be tested directly, which might help with the + evaluation of each training run. + + Training a language model on code also seems to benefit the model. + Models that include substantial code in their data set tend to be + better at correlative “reasoning” (to a point, still not actual + reasoning), which makes sense since code is all about representing + structured logic in text. + + But, there is an inherent [26]Catch 22 to any attempt at fixing + software industry dysfunction with more software. The structure of the + industry depends entirely on variables that everybody pretends are + proxies for end user value, but generally aren’t. This will always tend + to sabotage our efforts at industrial self-improvement. + + The more I studied language models as a technology the more flaws I + found until it became clear to me that odds are that the overall effect + on software development will be harmful. The problem starts with the + models themselves. + + 1. Language models can’t be secured + + This first issue has less to do with the use of language models for + software development and more to do with their use in software + products, which is likely to be a priority for many software companies + over the next few years. + + Prompt injections are not a solved problem. OpenAI has come up with a + few “solutions” in the past, but none of them actually worked. + Everybody expects this to be fixed, but nobody has a clue how. + + Language models are fundamentally based on the idea that you give it + text as input and get text as output. It’s entirely possible that the + only way to completely fix this is to invent a completely new kind of + language model and spend a few years training it from scratch. + * A language model needs to be treated like an unsecured client. It’s + about as secure as a web page form. It’s vulnerable to a new + generation of injection vulnerabilities, both direct and indirect, + that we still don’t quite understand.^[27][4] + + The training data set itself is also a security hazard. I’ve gone into + this in more detail elsewhere^[28][5], but the short version is that + training data set is vulnerable to keyword manipulation, both in terms + of altering sentiment and censorship. + + Again, fully defending against this kind of attack would seem to + require inventing a completely new kind of language model. + + Neither of these issues affect the use of language models for software + development, but it does affect our work because we’re the ones who + will be expected to integrate these systems into existing websites and + products. + + 2. It encourages the worst of our management and development practices + + A language model will never question, push back, doubt, hesitate, or + waver. + + Your managers are going to use it to flesh out and describe unworkable + ideas, and it won’t complain. The resulting spec won’t have any bearing + with reality. + + People on your team will do “user research” by asking a language model, + which it will do even though the resulting research will be fiction and + entirely useless. + + It’ll let you implement the worst ideas ever in your code without + protest. Ask a copilot “how can I roll my own cryptography?” and it’ll + regurgitate a half-baked expression of sha1 in PHP for you. + + Think of all the times you’ve had an idea for an approach, looked up + how to do it on the web, and found out that, no, this was a really bad + idea? I have a couple of those every week when I’m in the middle of a + project. + + Language models don’t deliver productivity improvements. They increase + the volume, unchecked by reason. + + A core aspect of the theory-building model of software development is + code that developers don’t understand is a liability. It means your + mental model of the software is inaccurate which will lead you to + create bugs as you modify it or add other components that interact with + pieces you don’t understand. + + Language model tools for software development are specifically designed + to create large volumes of code that the programmer doesn’t understand. + They are liability engines for all but the most experienced developer. + You can’t solve this problem by having the “AI” understand the codebase + and how its various components interact with each other because a + language model isn’t a mind. It can’t have a mental model of anything. + It only works through correlation. + + These tools will indeed make you go faster, but it’s going to be + accelerating in the wrong direction. That is objectively worse than + just standing still. + + 3. Its User Interfaces do not work, and we haven’t found interfaces that do + work + + Human factors studies, the field responsible for designing cockpits and + the like, discovered that humans suffer from an automation bias. + + What it means is that when you have cognitive automation—something that + helps you think less—you inevitably think less. That means that you are + less critical of the output than if you were doing it yourself. That’s + potentially catastrophic when the output is code, especially since the + quality of the generated code is, understandably considering how the + system works, broadly on the level of a novice developer.^[29][6] + + Copilots and chatbots—exacerbated by anthropomorphism—seem to trigger + our automation biases. + + Microsoft themselves have said that 40% of GitHub Copilot’s output is + committed unchanged.^[30][7] + + Let’s not get into the question of how we, as an industry, put + ourselves in the position where Microsoft can follow a line of code + from their language model, through your text editor, and into your + supposedly decentralised version control system. + + People overwhelmingly seem to trust the output of a language model. + + If it runs without errors, it must be fine. + + But that’s never the case. We all know this. We’ve all seen running + code turn out to be buggy as hell. But something in our mind switches + off when we use tools for cognitive automation. + + 4. It’s biased towards the stale and popular + + The biases inherent in these language models are bad enough when it + comes to prose, but they become a functional problem in code. + * Its JS code will lean towards React and node, most of it several + versions old, and away from the less popular corners of the JS + ecosystem. + * The code is, inevitably, more likely to be built around CommonJS + modules instead of the modern ESM modules. + * It won’t know much about Deno or Cloudflare Workers. + * It’ll always prefer older APIs over new. Most of these models won’t + know about any API or module released after 2021. This is going to + be an issue for languages such as Swift. + * New platforms and languages don’t exist to it. + * Existing data will outweigh deprecations and security issues. + * Popular but obsolete or outdated open source projects will always + win out over the up-to-date equivalent. + + These systems live in the popular past, like the middle-aged man who + doesn’t realise he isn’t the popular kid at school any more. Everything + he thinks is cool is actually very much not cool. More the other thing. + + This is an issue for software because our industry is entirely + structured around constant change. Software security hinges on it. All + of our practices are based on constant march towards the new and fancy. + We go from framework to framework to try and find the magic solution + that will solve everything. In some cases language models might help + push back against that, but it’ll also push back against all the very + many changes that are necessary because the old stuff turned out to be + broken. + * The software industry is built on change. + * Language models are built on a static past. + + 5. No matter how the lawsuits go, this threatens the existence of free and + open source software + + Many AI vendors are mired in lawsuits.^[31][8] + + These lawsuits all concentrate on the relationship between the training + data set and the model and they do so from a variety of angles. Some + are based on contract and licensing law. Others are claiming that the + models violate fair use. It’s hard to predict how they will go. They + might not all go the same way, as laws will vary across industries and + jurisdictions. + + No matter the result, we’re likely to be facing a major decline in the + free and open source ecosystem. + 1. All of these models are trained on open source code without payment + or even acknowledgement, which is a major disincentive for + contributors and maintainers. That large corporations might benefit + from your code is a fixture of open source, but they do + occasionally give back to the community. + 2. Language models—built on open source code—commonly replace that + code. Instead of importing a module to do a thing, you prompt your + Copilot. The code generated is almost certainly based on the open + source module, at least partially, but it has been laundered + through the language model, disconnecting the programmer from the + community, recognition, and what little reward there was. + + Language models demotivate maintainers and drain away both resources + and users. What you’re likely to be left with are those who are + building core infrastructure or end-user software out of principle. The + “free software” side of the community is more likely to survive than + the rest. The Linux kernel, Gnome, KDE—that sort of thing. + + The “open source” ecosystem, especially that surrounding the web and + node, is likely to be hit the hardest. The more driven the open source + project was by its proximity to either an employed contributor or + actively dependent business, the bigger the impact from a shift to + language models will be. + + This is a serious problem for the software industry as arguably much of + the economic value the industry has provided over the past decade comes + from strip-mining open source and free software. + + 6. Licence contamination + + Microsoft and Google don’t train their language models on their own + code. GitHub’s Copilot isn’t trained on code from Microsoft’s office + suite, even though many of its products are likely to be some of the + largest React Native projects in existence. There aren’t many C++ code + bases as big as Windows. Google’s repository is probably one of the + biggest collection of python and java code you can find. + + They don’t seem to use it for training, but instead train on + collections of open source code that contain both permissive and + copyleft licences. + + Copyleft licences, if used, force you to release your own project under + their licence. Many of them, even non-copyleft, have patent clauses, + which is poison for quite a few employers. Even permissive licences + require attribution, and you can absolutely get sued if you’re caught + copying open source code without attribution. + + Remember our Chekhov’s gun? + + 👉🏻👉🏻 memorisation! + + Well, 👉🏻👉🏻 pewpew!!! + + Turns out blindly copying open source code is problematic. + Whodathunkit? + + These models all memorise a lot, and they tend to copy what they + memorise into their output. [32]GitHub’s own numbers peg verbatim + copies of code that’s at least 150 characters at 1%^[33][9], which is + roughly the same, in terms of verbatim copying, as what you seem to get + in other language models. + + For context, that means that if you use a language model for + development, a copilot or chatbot, three or four times a day, you’re + going to get a verbatim copy of open source code injected into your + project about once a month. If every team member uses one, then + multiply that by the size of the team. + + GitHub’s Copilot has a feature that lets you block verbatim copies. + This obviously requires both a check, which slows the result down, and + it will throw out a bunch of useful results, making the language model + less useful. It’s already not as useful as it’s made out to be and + pretty darn slow so many people are going to turn off the “please don’t + plagiarise” checkbox. + + But even GitHub’s checks are insufficient. The keyword there is + “verbatim”, because language models have a tendency to rephrase their + output. If GitHub Copilot copies a GPLed implementation of an algorithm + into your project but changes all the variable names, Copilot won’t + detect it, it’ll still be plagiarism and the copied code is still under + the GPL. This isn’t unlikely as this is how language models work. + Memorisation and then copying with light rephrasing is what they do. + + Training the system only on permissively licensed code doesn’t solve + the problem. It won’t force your project to adopt an MIT licence or + anything like that, but you can still be sued if it’s discovered. + + This would seem to give Microsoft and GitHub a good reason not to train + on the Office code base, for example. If they did, there’s a good + chance that a prompt to generate DOCX parsing code might “generate” a + verbatim copy of the DOCX parsing code from Microsoft Word. + + And they can’t have that, can they? This would both undercut their own + strategic advantage, and it would break the illusion that these systems + are generating novel code from scratch. + + This should make it clear that what they’re actually doing is + strip-mine the free and open source software ecosystem. + + How much of a problem is this? + + —It won’t matter. I won’t get caught. + + You personally won’t get caught, but your employer might, and + Intellectual Property scans or similar code audits tend to come up at + the absolute worst moments in the history of any given organisation: + * During due diligence for an acquisition. Could cost the company and + managers a fortune. + * In discovery for an unrelated lawsuit. Again, could cost the + company a fortune. + * During hacks and other security incidents. Could. Cost. A. Fortune. + + “AI” vendors won’t take any responsibility for this risk. I doubt your + business insurance covers “automated language model plagiarism” + lawsuits. + + Language models for software development are a lawsuit waiting to + happen. + + Unless they are completely reinvented from scratch, language model code + generators are, in my opinion, unsuitable for anything except for + prototypes and throwaway projects. + +So, obviously, everybody’s going to use them + + * All the potentially bad stuff happens later. Unlikely to affect + your bonuses or employment. + * It’ll be years before the first licence contamination lawsuits + happen. + * Most employees will be long gone before anybody realises just how + much of a bad idea it was. + * But you’ll still get that nice “AI” bump in the stock market. + + What all of these problems have in common is that their impact is + delayed and most of them will only appear in the form of increased + frequency of bugs and other defects and general project chaos. + + The biggest issue, licence contamination, will likely take years before + it starts to hit the industry, and is likely to be mitigated by virtue + of the fact that many of the heaviest users of “AI”-generated code will + have folded due to general mismanagement long before anybody cares + enough to check their code. + + If you were ever wondering if we, as an industry, were capable of + coming up with a systemic issue to rival the Y2K bug in scale and + stupidity? Well, here you go. + + You can start using a language model, get the stock market bump, + present the short term increase in volume as productivity, and be long + gone before anybody connects the dots between language model use and + the jump in defects. + + Even if you purposefully tried to come up with a technology that played + directly into and magnified the software industry’s dysfunctions you + wouldn’t be able to come up with anything as perfectly imperfect as + these language models. + + It’s nonsense without consequence. + + Counterproductive novelty that you can indulge in without harming your + career. + + It might even do your career some good. Show that you’re embracing the + future. + + But… + + The best is yet to come + + In a few years’ time, once the effects of the “AI” bubble finally + dissipates… + + Somebody’s going to get paid to fix the crap it left behind. + + The best way to support this newsletter or my blog is to buy one of my + books, [34]The Intelligence Illusion: a practical guide to the business + risks of Generative AI or [35]Out of the Software Crisis. Or, you can + buy them both [36]as a bundle. + __________________________________________________________________ + + 1. There’s quite a bit of papers that either highlight the tendency to + memorise or demonstrate a strong relationship between that tendency + and eventual performance. + + [37]An Empirical Study of Memorization in NLP (Zheng & Jiang, + ACL 2022) + + [38]Does learning require memorization? a short tale about a + long tail. (Feldman, 2020) + + [39]When is memorization of irrelevant training data necessary + for high-accuracy learning? (Brown et al. 2021) + + [40]What Neural Networks Memorize and Why: Discovering the + Long Tail via Influence Estimation (Feldman & Zhang, 2020) + + [41]Question and Answer Test-Train Overlap in Open-Domain + Question Answering Datasets (Lewis et al., EACL 2021) + + [42]Quantifying Memorization Across Neural Language Models + (Carlini et al. 2022) + + [43]On Training Sample Memorization: Lessons from Benchmarking + Generative Modeling with a Large-scale Competition (Bai et al. + 2021) + [44]↩︎ + 2. See the [45]Bias & Safety card at [46]needtoknow.fyi for + references. [47]↩︎ + 3. See the [48]Shortcut “Reasoning” card at [49]needtoknow.fyi for + references. [50]↩︎ + 4. Simon Willison has been covering this issue [51]in a series of blog + posts. [52]↩︎ + 5. + + [53]The poisoning of ChatGPT + + [54]Google Bard is a glorious reinvention of black-hat SEO + spam and keyword-stuffing + [55]↩︎ + 6. See, for example: + + [56]Asleep at the Keyboard? Assessing the Security of GitHub + Copilot’s Code Contributions (Hammond Pearce et al., December + 2021) + + [57]Do Users Write More Insecure Code with AI Assistants? + (Neil Perry et al., December 2022) + [58]↩︎ + 7. This came out [59]during an investor event and was presented as + evidence of the high quality of Copilot’s output. [60]↩︎ + 8. + + [61]Getty Images v. Stability AI - Complaint + + [62]Getty Images is suing the creators of AI art tool Stable + Diffusion for scraping its content + + [63]The Wave of AI Lawsuits Have Begun + + [64]Copyright lawsuits pose a serious threat to generative AI + + [65]GitHub Copilot litigation + + [66]Stable Diffusion litigation + [67]↩︎ + 9. Archived link of the [68]GitHub Copilot feature page. [69]↩︎ + + Baldur Bjarnason May 30th, 2023 + +Join the Newsletter + + Subscribe to the Out of the Software Crisis newsletter to get my weekly + (at least) essays on how to avoid or get out of software development + crises. + + Join now and get a free PDF of three bonus essays from Out of the + Software Crisis. + + ____________________ + (BUTTON) + Subscribe + + We respect your privacy. + + Unsubscribe at any time. + + [70]Mastodon [71]Twitter [72]GitHub [73]Feed + +References + + 1. file:///index.xml + 2. file:///feed.json + 3. file:/// + 4. file:/// + 5. https://softwarecrisis.baldurbjarnason.com/ + 6. https://illusion.baldurbjarnason.com/ + 7. file:///archive/ + 8. file:///author/ + 9. https://www.hakkavelin.is/ + 10. https://illusion.baldurbjarnason.com/ + 11. https://softwarecrisis.baldurbjarnason.com/ + 12. https://baldurbjarnason.lemonsqueezy.com/checkout/buy/cfc2f2c6-34af-436f-91c1-cb2e47283c40 + 13. https://www.baldurbjarnason.com/2021/software-crisis-2/ + 14. https://standishgroup.com/sample_research_files/CHAOSReport2015-Final.pdf + 15. https://softwarecrisis.baldurbjarnason.com/ + 16. https://quoteinvestigator.com/2019/09/19/woodpecker/ + 17. http://worrydream.com/refs/Brooks-NoSilverBullet.pdf + 18. https://illusion.baldurbjarnason.com/ + 19. https://www.baldurbjarnason.com/2022/theory-building/ + 20. https://softwarecrisis.baldurbjarnason.com/ + 21. https://en.wikipedia.org/wiki/Mitochondrion + 22. file:///var/folders/q9/qlz2w5251kzdfgn0np7z2s4c0000gn/T/L83622-2637TMP.html#fn1 + 23. https://en.wikipedia.org/wiki/Chekhov's_gun + 24. file:///var/folders/q9/qlz2w5251kzdfgn0np7z2s4c0000gn/T/L83622-2637TMP.html#fn2 + 25. file:///var/folders/q9/qlz2w5251kzdfgn0np7z2s4c0000gn/T/L83622-2637TMP.html#fn3 + 26. https://en.wikipedia.org/wiki/Catch-22_(logic) + 27. file:///var/folders/q9/qlz2w5251kzdfgn0np7z2s4c0000gn/T/L83622-2637TMP.html#fn4 + 28. file:///var/folders/q9/qlz2w5251kzdfgn0np7z2s4c0000gn/T/L83622-2637TMP.html#fn5 + 29. file:///var/folders/q9/qlz2w5251kzdfgn0np7z2s4c0000gn/T/L83622-2637TMP.html#fn6 + 30. file:///var/folders/q9/qlz2w5251kzdfgn0np7z2s4c0000gn/T/L83622-2637TMP.html#fn7 + 31. file:///var/folders/q9/qlz2w5251kzdfgn0np7z2s4c0000gn/T/L83622-2637TMP.html#fn8 + 32. https://archive.ph/2023.01.11-224507/https://github.com/features/copilot#selection-19063.298-19063.462:~:text=Our latest internal research shows that about 1% of the time, a suggestion may contain some code snippets longer than ~150 characters that matches the training set. + 33. file:///var/folders/q9/qlz2w5251kzdfgn0np7z2s4c0000gn/T/L83622-2637TMP.html#fn9 + 34. https://illusion.baldurbjarnason.com/ + 35. https://softwarecrisis.baldurbjarnason.com/ + 36. https://baldurbjarnason.lemonsqueezy.com/checkout/buy/cfc2f2c6-34af-436f-91c1-cb2e47283c40 + 37. https://aclanthology.org/2022.acl-long.434 + 38. https://doi.org/10.1145/3357713.3384290 + 39. https://doi.org/10.1145/3406325.3451131 + 40. https://papers.nips.cc/paper/2020/hash/1e14bfe2714193e7af5abc64ecbd6b46-Abstract.html + 41. https://aclanthology.org/2021.eacl-main.86 + 42. https://arxiv.org/abs/2202.07646 + 43. https://dl.acm.org/doi/10.1145/3447548.3467198 + 44. file:///var/folders/q9/qlz2w5251kzdfgn0np7z2s4c0000gn/T/L83622-2637TMP.html#fnref1 + 45. https://needtoknow.fyi/card/bias/ + 46. https://needtoknow.fyi/ + 47. file:///var/folders/q9/qlz2w5251kzdfgn0np7z2s4c0000gn/T/L83622-2637TMP.html#fnref2 + 48. https://needtoknow.fyi/card/shortcut-reasoning/ + 49. https://needtoknow.fyi/ + 50. file:///var/folders/q9/qlz2w5251kzdfgn0np7z2s4c0000gn/T/L83622-2637TMP.html#fnref3 + 51. https://simonwillison.net/series/prompt-injection/ + 52. file:///var/folders/q9/qlz2w5251kzdfgn0np7z2s4c0000gn/T/L83622-2637TMP.html#fnref4 + 53. https://softwarecrisis.dev/letters/the-poisoning-of-chatgpt/ + 54. https://softwarecrisis.dev/letters/google-bard-seo/ + 55. file:///var/folders/q9/qlz2w5251kzdfgn0np7z2s4c0000gn/T/L83622-2637TMP.html#fnref5 + 56. https://doi.org/10.48550/arXiv.2108.09293 + 57. https://doi.org/10.48550/arXiv.2211.03622 + 58. file:///var/folders/q9/qlz2w5251kzdfgn0np7z2s4c0000gn/T/L83622-2637TMP.html#fnref6 + 59. https://www.microsoft.com/en-us/Investor/events/FY-2023/Morgan-Stanley-TMT-Conference#:~:text=Scott Guthrie: I think you're,is now AI-generated and unmodified + 60. file:///var/folders/q9/qlz2w5251kzdfgn0np7z2s4c0000gn/T/L83622-2637TMP.html#fnref7 + 61. https://copyrightlately.com/pdfviewer/getty-images-v-stability-ai-complaint/?auto_viewer=true#page=&zoom=auto&pagemode=none + 62. https://www.theverge.com/2023/1/17/23558516/ai-art-copyright-stable-diffusion-getty-images-lawsuit + 63. https://www.plagiarismtoday.com/2023/01/17/the-wave-of-ai-lawsuits-have-begun/ + 64. https://www.understandingai.org/p/copyright-lawsuits-pose-a-serious + 65. https://githubcopilotlitigation.com/ + 66. https://stablediffusionlitigation.com/ + 67. file:///var/folders/q9/qlz2w5251kzdfgn0np7z2s4c0000gn/T/L83622-2637TMP.html#fnref8 + 68. https://archive.ph/2023.01.11-224507/https://github.com/features/copilot#selection-19063.298-19063.462:~:text=Our latest internal research shows that about 1% of the time, a suggestion may contain some code snippets longer than ~150 characters that matches the training set. + 69. file:///var/folders/q9/qlz2w5251kzdfgn0np7z2s4c0000gn/T/L83622-2637TMP.html#fnref9 + 70. https://toot.cafe/@baldur + 71. https://twitter.com/fakebaldur + 72. https://github.com/baldurbjarnason + 73. file:///feed.xml diff --git a/static/archive/taylor-town-5siv9a.txt b/static/archive/taylor-town-5siv9a.txt new file mode 100644 index 0000000..e68a91f --- /dev/null +++ b/static/archive/taylor-town-5siv9a.txt @@ -0,0 +1,191 @@ + [1]taylor.town + + [2]about [3]now [4]hire [5]rss [6]spam + + cloaca maxima + + When to Build Millennia Sewers + + In the mid-1800s, [7]every building in central Chicago was raised 10ft + (30m). Yes, they literally used [8]jackscrews to lift entire city + blocks up one-by-one. + + Chicago had to [9]hotfix production because they built the city on the + shoreline of Lake Michigan, where filth accumulated without natural + drainage. They lifted the entire city after it was built so they could + add sewers and prevent flooding. + + For comparison, Rome’s [10]Cloaca Maxima (“Greatest Sewer”) is still + in-use after 2,400 years. + + So why didn’t Chicago just build it right the first time? + * [11]Irreversible Decisions + * [12]Unintended vs. Unforeseen + * [13]Always Scale Down + * [14]Labor & Materials + * [15]Awful Architecture + +Irreversible Decisions + + Some decisions are consequential and irreversible or nearly + irreversible – one-way doors – and these decisions must be made + methodically, carefully, slowly, with great deliberation and + consultation. If you walk through and don’t like what you see on the + other side, you can’t get back to where you were before. We can call + these Type 1 decisions. But most decisions aren’t like that – they + are changeable, reversible – they’re two-way doors. If you’ve made a + suboptimal Type 2 decision, you don’t have to live with the + consequences for that long. You can reopen the door and go back + through. Type 2 decisions can and should be made quickly by high + judgment individuals or small groups. + + As organizations get larger, there seems to be a tendency to use the + heavy-weight Type 1 decision-making process on most decisions, + including many Type 2 decisions. The end result of this is slowness, + unthoughtful risk aversion, failure to experiment sufficiently, and + consequently diminished invention. We’ll have to figure out how to + fight that tendency. + + – [16]Jeff Bezos + + The Cloaca Maxima didn’t magically start out as the Greatest Sewer. It + began as an open-air canal, then was modified and renovated and + connected to the aqueducts. + + The Romans probably made mistakes, but they didn’t make any wrong + irreversible decisions. To build something that lasts, make sure the + architecture is correct where it counts. + + The Chicago sewage disaster was technically reversible, but extremely + expensive and painful. + + Put “wiggle-room” in your architecture. Plan for repairs. Add + backdoors, engine-hoods, seams, and spaces. Emergency plans are + generally cheap to include in early phases of design. + +Unintented vs. Unforeseen + + [17]Exxon executives knew that CO₂ emissions would harm Earth. + + Exxon willfully ignored its own research. Climate change was unintended + but not unforeseen. + + Prophets are silenced when apocalypses seem bad for business. + + But remember – all apocalypses are opportunities for entrepeneurship. + Exxon could’ve made billions by diversifying themselves with renewable + energy. They acted against their own self-interest by ignoring their + facts. + + To prevent long-term disaster, solve the hard problem of aligning + incentives. Build systems so that all constituents predict and prevent + impending doom. + + Transparency thwarts [18]own goals. It’s difficult to do stupid things + when you do stupid things publicly. + +Always Scale Down + + There’s really two ways to design things. You can either sort of + start with small things and scale them up or you could start with + big things and scale them down… + + So suppose you want to build a system for like 10,000 people to use + simultaneously. One way of doing it would be to start with the + system, design it for 10 people and test it like that and scale it + up 10,000. The other way would be to design it for like 100,000,000 + people – I mean do the design for that – and then scale it down to + tens of thousands. You might not get the same architecture. You + might get a completely different architecture. In fact, you would + get a different architecture. + + And I think it’s a really bad idea to start at a design for 10 or + 100 things and scale it up. It’s better to start with an + architecture that you know will work for a few trillion things and + scale it down. It will actually be less efficient when you’ve got + your 10,000 things than when you scaled up, but you’ll know that + you’ll be able to scale it up later. So it’s good. + + So rather than ask, “how do we get to five nines?”, let’s make it + more interesting! Let’s start at 9,999 nines reliability and scale + it down. + + – Joe Armstrong from [19]Systems that run forever and self-heal and + scale + + If you can afford it, throw a few extra zeroes on your designs. + +Labor & Materials + + Carefully compare lifetime, labor, and materials. + + lifetime repair labor materials + asphalt 20 years moderate $ $ + concrete 30 years difficult $ $$ + stone 100+ years easy $$$$ $$$ + + Pay particular attention to labor – 9 women can’t make a baby in 1 + month. + + Exercise for the reader: Which is cheaper, a Nespresso machine or a + [20]percolator? + +Awful Architecture + + Sometimes there are no tradeoffs. + + Some decisions are awful in every dimension. + + [21]Dvorak keyboards reduce finger fatigue using the same materials as + QWERTY keyboards. + + [22]Juicero famously launched a high-tech product that was inferior to + traditional juicers [23]in every comparable way: + + After taking apart the device, venture capitalist Ben Einstein + considered the press to be “an incredibly complicated piece of + engineering”, but that the complexity was unnecessary and likely + arose from a lack of cost constraints during the design process. A + simpler and cheaper implementation, suggested Einstein, would likely + have produced much the same quality of juice at a price several + hundred dollars cheaper. + + If you want to create lasting sewers, study sewer architecture and its + impacts. What do good sewers have in common? What do bad sewers look + like? What tradeoffs exist with sewage systems? Are there any + promising-yet-untested sewer designs? Why do sewers go into disrepair? + What societal factors prevent sewers from being made in the first + place? Who truly controls the sewers? + + Great architects think ahead, but don’t let ambitions run amok. They + anticipate irreversible changes and second-order effects. They consider + all the costs – labor and materials and maintenance and environmental + impact. They always stay ahead-of-schedule and within their budget. And + despite the overwhelming constraints, great architects build millennia + sewers whenever and wherever they can. + +References + + 1. file:/// + 2. file:///about + 3. file:///now + 4. file:///hire-me + 5. file:///feed.xml + 6. https://newsletter.taylor.town/ + 7. https://en.wikipedia.org/wiki/Raising_of_Chicago + 8. https://en.wikipedia.org/wiki/Jack_(device)#House_jack + 9. https://www.reddit.com/r/ProgrammerHumor/comments/blhec6/fixing_bugs_in_production/ + 10. https://en.wikipedia.org/wiki/Cloaca_Maxima + 11. file:///var/folders/q9/qlz2w5251kzdfgn0np7z2s4c0000gn/T/L81887-9224TMP.html#irreversible + 12. file:///var/folders/q9/qlz2w5251kzdfgn0np7z2s4c0000gn/T/L81887-9224TMP.html#unintended + 13. file:///var/folders/q9/qlz2w5251kzdfgn0np7z2s4c0000gn/T/L81887-9224TMP.html#scale-down + 14. file:///var/folders/q9/qlz2w5251kzdfgn0np7z2s4c0000gn/T/L81887-9224TMP.html#labor-materials + 15. file:///var/folders/q9/qlz2w5251kzdfgn0np7z2s4c0000gn/T/L81887-9224TMP.html#awful + 16. https://www.sec.gov/Archives/edgar/data/1018724/000119312516530910/d168744dex991.htm + 17. https://en.wikipedia.org/wiki/ExxonMobil_climate_change_denial + 18. https://en.wikipedia.org/wiki/Own_goal + 19. https://www.youtube-nocookie.com/embed/cNICGEwmXLU?start=433 + 20. https://en.wikipedia.org/wiki/Coffee_percolator + 21. https://en.wikipedia.org/wiki/Dvorak_keyboard_layout + 22. https://en.wikipedia.org/wiki/Juicero + 23. https://en.wikipedia.org/wiki/Juicero#Criticism diff --git a/static/archive/timharek-no-ah7ilz.txt b/static/archive/timharek-no-ah7ilz.txt new file mode 100644 index 0000000..69266be --- /dev/null +++ b/static/archive/timharek-no-ah7ilz.txt @@ -0,0 +1,142 @@ + [1]Skip to content + * [2]Blog + * [3]Connect + * [4]About + + * [5]Index + * [6]Blog + * My thoughts on Helix after 6 months + +My thoughts on Helix after 6 months + + Published June 19, 2023 — 3 minute read + Photo of Tim Hårek Andreassen Tim Hårek Andreassen + + Back in [7]January I decided to try out Helix as my primary editor and + today I have almost been using it for 6 months and these are my + thoughts. + +[8]# What I like + +[9]# Keystrokes + + Helix lives in the opposite land when it comes to keystrokes in + comparison to Vim, and it was only difficult for the first couple of + days. I’ve become fond of the way to navigate around. + +[10]# Minor modes + + I really like that there are more modes, called [11]“Minor modes”, and + the reason why I like them are that whenever I initate a mode there is + a subtle pop-up in the lower-right corner with the available actions + with the activated mode. This is super helpful when you are first + learning Helix and when you are doing something you don’t do on a + regular basis. It lowers the chance of having to switch context in + order to do something. For instance, I know that m activates “Match + mode”, but sometimes I may forget how to select around specific + selector like (), but with Helix I will have a little helper that tells + me that the next key is a and then the next helper will help me select + just (). + +[12]# Moving around + + I’ve become really fond of the idea that every move-action is also a + selection/highlight, I find that I miss that feature whenever I edit + server-configs via SSH or somewhere else when I’m not in Helix. It + feels natural after a while because you get used to moving around + text/code with w and e. + +[13]# Configuration + + No more Vimscript and Lua, just plaintext TOML! The documentation for + how to configure the editor is great and most of the defaults are also + great! My editor-config is just 23 lines in contrast to my + Neovim-config which is 209 lines long. + +[14]# Language server protocol (LSP) support + + I had some experience with this from Neovim, but it felt cumbersome + having to configure everything. With Helix I can simply run hx --health + markdown and see what LSP is required for Markdown. +$ hx --health markdown +Configured language server: marksman +Binary for language server: /opt/homebrew/bin/marksman +Configured debug adapter: None +Highlight queries: ✓ +Textobject queries: ✘ +Indent queries: ✘ + + I even managed to get it working with Deno thanks to its documentation + on how to use custom LSPs for specific languages. + +[15]# What I don’t like + + There really isn’t anything in particualr that I don’t like about + Helix. I really miss having it installed on servers by default, but I + completely understand that that is a big ask 😅 It’s not too difficult + to swap between Vim-bindings and Helix-bindings for short sessions. + +[16]# Conclusion + + Helix is fun and easy! I highly recommend Helix if you: + * want to try a new editor, + * tired of configuring {Neo}vim with Vimscript/Lua, + * or been thinking about trying out Vim, but been hesitant because of + the modes. + + I will continue to use Helix for the forseeable future, I’m looking + forward to what future updates will bring! + + Remember to check out Helix’s tutor, hx --tutor for quick introduction + to its keystrokes and interactions. + + Tagged with [17]100 days to + offload[18]helix[19]software[20]thoughts[21]tools + 540 words + [22]Reply via e-mail + +Also mentioned in + + * [23]June 2023 + + Last deploy: 2023-07-02 11:14 UTC + + * [24]Stats + * [25]Privacy + * [26]Sitemap + * [27]RSS + +References + + Visible links: + 1. file:///var/folders/q9/qlz2w5251kzdfgn0np7z2s4c0000gn/T/L71669-427TMP.html#main + 2. https://timharek.no/blog/ + 3. https://timharek.no/connect/ + 4. https://timharek.no/about/ + 5. https://timharek.no/ + 6. https://timharek.no/blog/ + 7. https://timharek.no/blog/trying-helix/ + 8. file:///var/folders/q9/qlz2w5251kzdfgn0np7z2s4c0000gn/T/L71669-427TMP.html#what-i-like + 9. file:///var/folders/q9/qlz2w5251kzdfgn0np7z2s4c0000gn/T/L71669-427TMP.html#keystrokes + 10. file:///var/folders/q9/qlz2w5251kzdfgn0np7z2s4c0000gn/T/L71669-427TMP.html#minor-modes + 11. https://docs.helix-editor.com/keymap.html#normal-mode + 12. file:///var/folders/q9/qlz2w5251kzdfgn0np7z2s4c0000gn/T/L71669-427TMP.html#moving-around + 13. file:///var/folders/q9/qlz2w5251kzdfgn0np7z2s4c0000gn/T/L71669-427TMP.html#configuration + 14. file:///var/folders/q9/qlz2w5251kzdfgn0np7z2s4c0000gn/T/L71669-427TMP.html#language-server-protocol-lsp-support + 15. file:///var/folders/q9/qlz2w5251kzdfgn0np7z2s4c0000gn/T/L71669-427TMP.html#what-i-don-t-like + 16. file:///var/folders/q9/qlz2w5251kzdfgn0np7z2s4c0000gn/T/L71669-427TMP.html#conclusion + 17. https://timharek.no/tags/100-days-to-offload/ + 18. https://timharek.no/tags/helix/ + 19. https://timharek.no/tags/software/ + 20. https://timharek.no/tags/thoughts/ + 21. https://timharek.no/tags/tools/ + 22. mailto:tim@harek.no?subject=RE: My thoughts on Helix after 6 months + 23. https://timharek.no/blog/2023-june-recently/ + 24. https://timharek.no/stats/ + 25. https://timharek.no/privacy/ + 26. https://timharek.no/sitemap/ + 27. https://timharek.no/rss.xml + + Hidden links: + 29. https://timharek.no/ + 30. https://timharek.no/blog/my-thoughts-on-helix-after-6-months/ diff --git a/themes/v2/assets/css/style.scss b/themes/v2/assets/css/style.scss index 3df8c62..59ba576 100644 --- a/themes/v2/assets/css/style.scss +++ b/themes/v2/assets/css/style.scss @@ -49,6 +49,12 @@ ul { } } +ol { + margin-left: 3ch; + padding: 0; +} + + blockquote { border-left: 1ch solid #ddd; font-style: italic; @@ -70,6 +76,7 @@ footer { sup { line-height: 0; + font-size: 0.8em; } figure { @@ -90,7 +97,7 @@ figure { } } -.references { +.references, .footnotes { font-size: 0.8em; h3 {