Elf M. Sternberg

Full Stack Web Developer

Where one teaches, two learn.

Tag: #programming

To all tags

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."

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.

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:

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.

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.

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.

Using Git Secrets

In my Using PDM posts, I mentioned that I was rebuilding the backup tools for my blog. Using such tools requires that I keep a couple of my passwords, the ones I use for databases, in plain text, which is clearly not ideal, especially not if I want to use GIT to manage them. I decided to try using git secret to store my credentials. Here's how it works.

Using PDM: The Python Dependency Manager

Since it looks as if Twitter's days are numbered, I've been looking at what it would take to move most of my on-line presence into my personal blog space and off of the various sites where I make various comments and such. One thing I haven't been doing well is backing up this site right here; my last backup was over two years ago. That's... not good.

Code Archeology: The Unix Locate Program, 1994, and the Squozen Database Format

I've been conducting a bit of code archaeology, and this week I've been researching the original Locate program, the one written in 1983 and which persisted until the release of FreeBSD in 1994, at least. In this post, I'm going to describe the original Locate database format, which was called Squozen 1.0 Here's what I've learned.

TypeScript Or Be Damned

I recently had a chance to finish up a major refactor of the codebase for BFDLang (Bureaucratic Form Design Language), a hefty (and now Turing-complete) language for describing, well, bureacratic forms to web documents. I work at an insurance company, and BFDLang gives the administrative staff the power to describe a form in a spreadsheet and immediately see what it would look like as a web document; it's a powerful, in-house no-code solution for them backed by a ton of code, mostly written by myself and two junior developers. The refactor was huge, and complicated, and I couldn't have done it with JavaScript. TypeScript saved me weeks of work.

Still Got It

Yesterday, after a long day of my day job, in which I spend all of my time either hacking in Typescript and React or doing a lot of dev-ops, I decided that I was finally gonna sit down and write a little Rust. I picked a project off my stack: "Rewrite the Unix locate program in Rust." The last time I had tried this, my brain didn't work at all.

Your Company Needs Only Five Programming Languages, No More, No Less

If you've worked in this business for a long time, you've definitely encountered that mid-size company where every team has their own favorite language. And while this might work for awhile, it's a long-term disaster waiting to happen within your company. Eventually, every company that grows to a certain size and survives realizes that you need to clamp down and have at most four computer languages allowed inside your build process.

Here are the four languages:

Is Agile compatible with Clean Code?

I’ve been through Agile training several times before at different jobs, and the current job is no different. June is Agile Training Month, and since I started last September I’m obliged to go through this again. Previously, we had a Clean Code Training period that lasted two months, and I realized today why I’m having such a hard time with the Clean Code part of the training.

The Agile process says that the product should have value to the customer at the end of the first month, and that the value to the customer grows as the development team puts more intellectual work into building out its functionality.

Review: Clean Code, by Robert Martin

It might seem like I’ve been harsh on Robert Martin’s Clean Code for the past couple of posts, and that’s valid. I have been. It’s such a good book, full of strong advice on any number of topics.

It’s just that it feels old. Programming is a young discipline in the world, probably one of the youngest, and one of the most consequential. It changes with absurd speed, and everyone in it struggles to keep up. Clean Code came out in 2006 and already there are dusty corners within that feel out of date, even irresponsible.

If you're a senior developer, you have to accept some WET code.

In some programming languages there is an essential, powerful tension between two common pieces of advice: Don’t Repeat Yourself and Meaningful Names over Code Comments. Both are really good pieces of advice.

“Don’t Repeat Yourself” (DRY) means that if you can find an abstraction that allows you to avoid repetition in your code, you can remove the need to debug multiple code blocks if you find an error, and you can test the abstraction more reliably and more efficiently. The opposite of DRY is, of course, WET, “Written-out Every Time.”

“Meaningful Names over Code Comments” means that if you have strong, descriptive names for classes, functions, and variables, then code comments are often not merely unnecessary but possibly harmful as they drift out-of-date with the actual content of the code.

At my ${DAY_JOB}, I ran into this conflict in a big way. This example is in Python, but it applies to any language with metalanguage capabilities, which includes Ruby, Lisp, Rust, and even C++.

Lab Notes, First Two Weeks of January: Pamseam w/Lattice Experiments

Lab notes for the first two weeks of January.

I’ve been fiddling with a branch of the PamSeam project named Lattice in an effort to streamline the base and speed up the runtime. There are three algorithms enabled and all of them have similar processes. The basic engine is also very slow, with lots of large allocations and copying the image over and over.

Great chess players don't see the pieces, they see the board. Great programmers need to learn from that.

The Psychology of The Psychology of Computer Programming, Chapter 1

Hitting the math-vs-engineering speedbump with the Regex project

I'm starting to understand why Mathematicians love Perl.

Today's Lesson in Implementing Theoretical CS: Divide And Conquer

Notes on using the Rust image library

Designing Algorithms On Paper, and Why Not Needing To Is a Warning Sign

What I've been reading this past week or so... SICP, Parsing, and Build Tools

The Death's Head Semantic In Python: Is It Really Necessary?

Parsing with derivatives, naive Python edition!

New work: Autorotate for the MS Surface Pro 3 running Linux & Krita

How we talk when we talk about programming languages

The missing conversation about anti-if patterns.

PacMan doesn't need AI

Post-mortem: What I learned writing git-linter

What comes next?

Analysis Paralysis

Pattern Matching And Lisp

Lisp In Small Pieces vs Essentials of Programming Languages: Which should you own?

It's Not About Your Simplicity, It's About Your Audience's Capability

The Key To Coding is Re-Coding

"Why you should never interrupt your programmer" deals with the wrong question

Software development needs copy editors

What A Bunch of Greybeards, And That's A Good Thing...

Paying my dues, Studying the masters...

I used to write Python, but then I got Hy

I hate (commercial, retrograde, dilatory) puzzles, too.

I should have added these years ago to me .emacs file!

Extending the Mocha tests into Jenkins (or Hudson):

Working Notes: Jenkins, Git, Grunt, Mocha, Zombie, Coffee, Require

Two releases. What have I learned?

REST is not SOA is not JSON

Boarding the "Anti-if" bus

Right Now 0.5

A new little software toy: Right Now!

Beating my head against the monad wall...

Thinking In Haskell is harder than Thinking In Portals

I used to joke that, sometimes, when someone in my family comes down and sees a mess of code up in Emacs on my screen that "No, really, I'm playing a video game. It just looks like work." Because I find coding fun. But the fact is that I also play games, and Portal 2 was definitely a brain-bender.

But not as brain-bending as Haskell.

That said, I just finished the first exercise in Seven Languages in Seven Weeks, although really I'd think it's more like Seven Languages in Seven Days, given my ferocious language consumption-- I just skipped right to the Haskell part, because I have a project that requires Haskell at the moment. Still, this was pretty cool. Don't read further if you don't want the answer.

Lifestreams and Gamification

The Backbone Store, version 2.0, regular edition.

Dead-simple progressive state handler.

Kanso to bootstrap, Couch-docs to learn how to write CouchDB applications.

Playing with Raphael, Canvas, and animation

How to get the Ruby 'lessc -w' option under Node for LessCss

Backbone Store v 0.2 released

Using django_uni_form and CSRF

Backbone.js: Introducing The Backbone Store!

Django Gotchas: Django's request.GET dictionary and 'in'


Props to the Digg developers...

Followup: The Onion switches to Django

Git Giggle

Pro Git (Apress) vs Version Control with Git (O'Reilly)

What went wrong at ${Job Sept'09-Oct'09}

Rails re-affirms my love for Django...

Remote Authentication Between Cooperating Websites

Quite possibly the most important Java post I've ever read...

"And to think... I hesitated."

Node.js is genuinely exciting!

Django SocialAuth component, now with some Elfin goodness...

Continual Integration Testing for Web Applications: Remote testing with Celerity, Watir, and Cucumber

Python: Decorators With Arguments (with bonus Django goodness)

Unicorn chaser... not!

Brief side-experiments: Google Go versus Stackless Python

Continual Integration Testing for Web Applications: Hooking up our application to Hudson

Pro-am tip: Wildcard DNS and You!

Continual Integration Testing for Web Applications: A Sample Application in Django

Continual Integration Testing for Web Applications: Setting up Hudson behind Nginx

Automatic Testing of Facebook Applications

Are Test-Driven Development and Literate Programming the Same Discipline?

Probably my most annoying coding blind spot...

I have Cucumber working with FacebookConnect!

JQuery: A dock at the bottom of the viewport!

Figlets From Hell

Django: Generating static javascript and CSS with reversed URLs via Templates

Perl is not Python, and other painfully obvious musings...

Python: What the Hell is a Slot?

Installing Django's ugettext absolutely everywhere

Dynamic names as first-level URL path objects in Django

Bog-stupid Ajax round trips with Prototype and Django

Underwhelmed by the Symfony install documentation

Fixing an omission from Django's simplejson: iterators, generators, functors and closures

The three stages of mastery...

I am much better at C++ than I recall

Followup to don't live with a broken IDE: Not the smallest broken thing.

Don't live with a broken IDE