Elf M. Sternberg

Full Stack Web Developer

Where one teaches, two learn.

Blog

A quarter-century of code experience

Programming

UNDERSTANDING CONTINUATIONS: JAVASCRIPT TRY/CATCH AND RUST RESULT

"You are responsible for explicitly understanding the rest of the program." A sentence like this appears in every tutorial explaining first-class continuations, a programming language construct that appears in Lisp, Scheme, and Haskell, and if you look at people discussing them they find such constructs "scary."

One of the things I did many, many moons ago was write a couple of small Lisp interpreters. (It was long enough ago that I'm sorry to say they were written in CoffeeScript.) One thing that I did finally understand while building these was how continuations could be used to replace almost all flow control, that if, while, and even function calls were all just specialized versions of continuations.

The problem with continuations is that they do look scary. But while watching Alexis King's awesome presentation Demystifying Delimited Continuations, I'm glad to say that I finally wrapped my head around the notation for continuations in a way that clarifies that terrifying sentence you find in every explanation of continuations, "A continuation is the code you write that will handle the rest of the program."

Continue Reading

Monorepo

MONOREPOS WITH MICROSOFT LAGE: LEARNINGS THIS WEEK

I recently chose Lage to help refactor a monolith web application into a monorepo. Here's what I learned.

In my day job, I'm responsible for a fairly large web application of about 52,600 lines of TypeScript. In reality, that one web application is four independent major single-page applications and two minor ones, all of which rest on a classic collection of component library, server interface, and localization. It's getting a bit unwieldy to work in, and any edit cycle now takes about 25 seconds to rebuild the whole thing while working on it.

That's just a little too long in the era of hot module reloading. Plus it's hard to know where the boundaries are, and the guy I inherited it from cut a few corners here and there, stealing useful code across the hierarchy rather than re-arranging the hierarchy. I managed to disentangle the first-level dependencies a few months ago, so that no SPA is dependent upon something within another, and now the time has come to break it up into multiple workspaces. After looking through the list of possible tools, I picked Lage.

Continue Reading

Javascript

NOTIFICATION WEB COMPONENT WITH INTRINSIC SCALING

I set out to reproduce the effect from "The CSS Hack You Need To Know", which is all about using the attr() CSS function to extract an attribute's value from the tag being styled so you can apply it to a ::after entry that will display the attribute. The idea is that one could then set:

<div class="notification-bell-container" current-count=5><svg ...></svg> </div>

And get back something that looks like this:

Image of the Bell Icon

As I was playing with the source code, I realized that it had one major shortcoming: it didn't scale well. For every different size, if you wanted the notification circle to be even approximately in the right place you would need to hand-code the location of the counter and have breakpoint-oriented versions for phone, tablet, desktop, extra-wide, and ten-foot displays.

Can we do better than that? With web components we can do anything.

Continue Reading

Programming

AND THEN IT ENDS: THE IMPORTANCE OF UNDERSTANDING SUBROUTINES IN MODERN WEB DEVELOPMENT

One of the most important lessons I've ever learned about Javascript is that no Javascript application is, by itself, actually a single program. Every Javascript application of even modest size is several different programs standing together in a trench coat and trying very hard to look like a single thing.

Let's look at the single most simple web application, the classic "push a button to increment a counter" that is the centerpiece of every "introduction to React / Vue / Angular / Lit / Svelte / etc." blogpost you've ever read. This application is just a button and a number, and every time you click the button the number increments. And let's talk about how it's very different from classical programming.

Continue Reading

Programming

TABLE DRIVEN WEB DEVELOPMENT

I've occasionally made reference, in the course of my blogging about Web Component development (and this applies to React as well), to "table driven development," and I had an opportunity to explain it in more detail this week. Table Driven Development is nothing more than identifying what is the minimum amount of syntax you need to express the data you use in your web page?

Let's start with a real-life example. This is a tab-based control from the Patternfly library, taken from a real project:

Continue Reading

Programming

MOST CONVERSATION ABOUT ABSTRACTION IS REALLY ABOUT LEGIBILITY

In my previous post, I talked about how using a CSS library cluttered the semantics of what a web component does, and after another week of living in this codebase I realized that there's a conversation to be had about the difference between abstraction and legibility. Because most of the time when we're talking about abstraction? We're actually talking about legibility. For example, I recently read the introduction to an OCaml textbook that said, "You will improve at abstraction, which is the practice of avoiding repetition by factoring out commonality."

That is absolutely not abstraction. That is legibility.

To quote James Koppel, an abstraction is an encapsulation of an idea, such as "sanitized" or "authorized" or "connected to a server," and locking the details behind an abstraction barrier so than not only don't you have to worry about the details, you shouldn't. That's not what my previous example did. Instead, it made the code's purpose and function legible.

So let's talk about legibility with another example.

Continue Reading

Web components

WEB COMPONENTS AND CSS LIBRARIES: AN AWKWARD FIT

In my new job, I've been working a lot with an existing codebase that uses web components (via Lit) for the HTML and Patternfly for the CSS, and I've discovered that Patternfly, as well as other CSS Libraries such as Tailwind or Bootstrap, are awkward fits for developing web components. You usually end up importing too much per component or sacrificing code readability on the altar of code size.

Let me give you an example:

Continue Reading

Web components

MOVING FROM REACT TO LIT REQUIRES A SHIFT IN ATTITUDE

React is the number one most popular web application development framework, hands down, with twice the user base of its next competitor, Angular. My framework of choice is LitElement, which doesn't even appear on some of these charts.

According to Stack Overflow, 55% of developer "admire" Lit, and less than 1% get to work in it. I, fortunately, get to work in Lit, but after four years of React experience I've discovered that Lit is so very different from React, Angular, and the rest that it takes a heavy mental shift to work in it.

I work professionally on a medium-sized web application written in Lit that orchestrates and administers single-sign-on for small-to-medium businesses. I really like Lit, and working on this thing has been like being thrown into the deep end of the pool. There are two aspects of Lit that make it really different from the others and can make it hard for some developers to make the mental shift.

Continue Reading

Job search

STARTUP FOUNDERS: PLEASE DO YOUR F*#!ING HOMEWORK.

I recently had a job interview that, frankly, baffled the hell out of me. It started out well enough: he had a VC backing his new "spreadsheets as a service" software model, had $2 million in seed money, and was looking for developers to help turn his prototype into a product.

I worried a bit. I'd interviewed at Airtable three year prior and gotten turned down because of my patents. I designed the prototype for what is now Splunk's dynamic dashboards with dataflow subdisplays; it was an application of the Fundamental Algorithm of Spreadsheets to a dashboard (the relationship of the spreadsheet's grid/cell system to the directed acyclic graph underlying how data gets updated). Airtable didn't want to piss off Splunk, despite the patent being wholly defensive and probably defeatable with a prior art argument.

But as we talked I started to wonder just how much he knew about the field he was stepping into. Not financially, but technically. Because this guy had just not done his homework.

Continue Reading

Open source

APPLE'S PARASITIC STANCE TOWARD OPEN SOURCE

Apple's always had this passive-aggressive, parasitic relationship with open source. Darwin, the OS at the bottom of all modern Macs, is an offshoot of FreeBSD, and a lot of what Apple presents to you is derived from other open source projects. But Apple has always downplayed, neglected, ignored, or otherwise distracted most of its consumers from knowing anything about their use of open source. Let's discuss two recent examples.

Continue Reading

Programming

WEB COMPONENTS: A CAUTIONARY TALE ABOUT THE SHADOW DOM AND INNERHTML

After six years of writing React professionally, I have decided that I really prefer Web Components to React, Angular, Vue, or any of their ilk. Web Components are the browser's native model for defining components; they don't need huge libraries to "route around" deficiencies in the browser nor do they need special context or event types; they just use the browser's own event dispatcher, and context is managed by putting stopPropogation on the context handler's DOM Node.

I recently spent some time trying to port my old jQuery/Backbone demo, Fridgemagnets, to a Web Component model.

I started out by using Lit-Element. Lit is a very small toolkit from Google which creates a bundle of only 5KB, much smaller than React's 40. I had good reasons: due to the history of Web Components, the API is awkward with very long method names and an annoyingly complex dance to convert text to a DOM Node. Lit streamlines a lot of that, but it also adds something that I usually find annoying: all your events that cause a state change in a component are batched and propagated at once, debounced to prevent refresh pauses. Lit wants to make web components "reactive," so your state is stored in monitored attributes.

For the most part, I can live with that. But in the conversion to FridgeMagnets, I hit a headache.

Continue Reading

Programming

SERIALIZING SQLALCHEMY TO JSON

During a recent "take-home exam" for a job interview, I was confronted with the common challenge of extracting information via SQLAlchemy, a popular ORM layer for Python, and converting it to JSON. The most popular answer on Stack Overflow involves writing some code to do a conversion that ought to be present natively in the SQLAlchemy library but apparently not.

After looking through the various answers, I was dissatisfied with all of them, so I fired up a Python REPL and started digging into SQLAlchemy itself from the outside. I dislike this sort of "empirical" software development but I dislike a raft of code when there must be a simpler solution.

There was.

Continue Reading

Functional programming

PROGRAMMABLE SEMICOLONS

What does this Javascript do?

let x = "Hello";
let x = x + ", World!";
console.log(x);

It prints "Hello, World!", right? So how about this?

new Promise((resolve, reject) => resolve("Hello"))
    .then((a) => (a + ", World))
    .then((a) => console.log(a));

It does the same thing, right?

Okay, so let me ask you an important question: in the second code sample, where are the semicolons?

That's one of the most interesting questions in functional programming. Let me explain why:

Continue Reading

Career

THE KINKY USER STORY PATTERN

A user story is a pattern of communication commonplace in software development teams. The idea of a user story is simple: nobody cares about your software and your job isn't to write code, it's to solve user's problems, and the pattern is often a way of articulating a user's problem and the proposed solution. The most common pattern, as explained the software management company Atlassian, is:

As a [user persona], I [want to be able to do this task], so that I can [achieve this goal].

I find this pattern a little passive-aggressive, since it never identifies who is going to be providing the solution.

Continue Reading

Web development

THE WEB ASSEMBLY COMPONENT MODEL: WYVERN 2.0, OR A BRIGHT NEW FUTURE?

Many years ago, there was a programming language experiment named Wyvern that promised the polyglot developer he could, in the same file, write each function in a different language, and it would all work. It was a crazy idea at the time, but now? Now we write this way all the time. The Web Assembly Component Model is only going to make that all the more true.

Continue Reading

Web development

STATIC SITE GENERATION IS NOT A 'REACTION' TO CLIENT-SIDE RENDERING

JavaScript developer Katharine Angelopoulos recently wrote an article titled Emerging Paradigms for Delivering Content Faster, and while there's much good in her article there was a line in there that stopped me in my tracks. She wrote:

Static Site Generation came about as a solution to the maladies of SSR and CSR.

As someone who's website literally reads, Created: October 14, 1994 by Elf M. Sternberg, that line made me blink three times. I write stories, and there's no way I was going to convert them all to HTML by hand. From 1994 through to today, a total of 29 years, the story site has been statically generated from something resembling Markdown (for a while it was a format called Muse, which almost nobody remembers, and before that it was just called "Usenet emphasis style"), so static site generation can hardly be called "a reaction to server-side or client-side rendering."

It was literally the first thing we did. But the Eternal Amnesia means most people don't know that.

Continue Reading

Web development

THEY LIED. THEY LIED TO US.

As I mentioned in my last post, I really wanted to find a Web Component library that builds, you know, Web Components. Each component should be a standalone, loadable file ending in .js that instantiated the constructor of a fully-realized web component. I wanted a few bells and whistles, like HTML and CSS auto-templating, Typescript is a must but Sass is a nice-to-have.

Stencil promised that. It's promise reads "Stencil is a library for generating small, blazing fast Web Components that run everywhere." I'm took them at their word.

They lied.

Continue Reading

Web development

LIT IS TAKING HOSTAGES

I dislike "magical thinking" in software development and React has become too magical.

I've been a React developer since 2015 so I went through the "class-based to function-based" revolution in React Development. I've gone through the iterations of learning about Hooks, and Memos, and Callbacks, and I have to say that modern React requires a daunting amount of experience to write with any competence as well as a deeper understanding of JavaScript's call-by-value vs call-by-reference nature to avoid re-renders.

So it was with the typical glee of confirmation bias that I read Nudge's React is Holding Me Hostage in which he outlines the problems with modern React, including the illusion that state in React is a part of the component when, in fact, it is an input to the component.

Unfortunately it looks like the Lit team is making the same mistake.

Continue Reading

Web development

ADDING SEARCH TO MY STORIES

One of the things I've always wanted for my website is a search engine that wasn't beholden to Google. I've considered using Solr or one of those, but I really wanted something local. Something that ran on my laptop. Something that wasn't "in the cloud."

I had helped developed a library science application back at university, but that was over 30 years ago, and while I actually still have that textbook the techniques in it are outdated. I thought about using Tantivvy or something along those lines, but each was a complicated mess.

Then I discovered Meilisearch, and I fell immediately in love. It's a typo-friendly, incredibly fast, and (for searches) lightweight search engine that you can run locally.

Here's how I built it:

Continue Reading

Professionalism

STARTUPS: THE SECRET SAUCE, THE SCHLEP, AND EVERYTHING ELSE

Since I'm looking for work, let me tell you what I look for in a project. I don't look too hard at the languages, platform, or libraries being used; I know the most important ones and can learn their relatives and competitors without too much effort.

What I want to know about a start-up is this: do you have a secret sauce, and do you know how long the schlep will be?

Continue Reading