Archive
-
Emacs for Python and Poetry Using
basedpyright emacs poetry-for-python pythonbasedpyright-langserver
I am very pleased with my current emacs setup for Python, but I found setup to be a little tricky. I will document my setup here for my future self and for any other Pythonistas looking for a solid emacs config.
-
A Font Family Choice for Pragmatism and Disability Allyship
accessibility css design frontendThere's no need for this to be a full length article, but I've had a couple occasions recently to evangelize my favorite non-monospace font, and it occurs to me this might be a good time to collect and share my thoughts about the font choice I've made for my blog.
-
Iced for Desktop Development in Rust
desktop iced rustAs someone who loves Elm and has recently fallen in love with Rust, I was delighted to learn there are not just one but two Rust frameworks modeled on the Elm Architecture. If you're not familiar, the Elm Architecture is a pain-free way of developing fast, responsive, asynchronous-by-default front-ends. Let's see it in action by developing a simple "Hello, world" app.
-
Setting and Reading Session Cookies in Rust with Actix Web
actix-web rustIn case it's not readily apparent, I've been having some trouble picking a backend stack recently, but, at the risk of jinxing it, I really think Rust is the backend for me, and Actix Web is a blindingly fast MVC framework for Rust with an elegant and functional middleware system. As with all web apps, my first challenge is persisting and managing state between requests, so let's get into user session management in Actix Web.
-
Writing a (Nix-Friendly) Hello World Web App in Haskell with Scotty
haskell scotty nixosOkay, so this article has been written before, and I don't have a lot new to add, but some of these tutorials are getting pretty old, and the ones that aren't use
stack
, which I personally am avoiding as it doesn't play well with NixOS, so at least for me, for future reference, this tutorial will be useful. -
Running and Connecting to Postgres Using Docker Compose
database docker postgresSetting up a new development environment from scratch can feel like a slog. This is a quick copy-paste recipe for getting up and running quickly with Postgres in
docker compose
. -
Idris FizzBuzz Part IV: Main and .ipkg Files
idris nixosThis is the fourth and final part of a walkthrough of FizzBuzz, a common interview problem, in Idris. If you haven't read the other parts, you can start with Part I. To show how to import and use libraries, we're going to divide this project into a library and an executable. Along the way, we will create .ipkg packages for both.
-
Idris FizzBuzz Part III: Defining Types and Importing Modules
idris variantThis is Part III of my attempt to explain how to use the Idris programming language through a tutorial on FizzBuzz, the common software development hiring interview problem. If you're new to Idris and haven't read Part I and Part II, I recommend doing that now. This article will go over defining our own types and importing our own modules as well as recap what we've learned about case-matching and basic syntax.
-
Idris FizzBuzz Part II: Maybes, Infix Notation, and Idris Holes
idris monadLet's conntinue on our journey of writing FizzBuzz in the Idris programming language. If you haven't already, I encourage you to read Part I for an introduction to the problem as well as some basic syntax, and, importantly, information on totality checking.
-
Idris FizzBuzz Part I: Monads, Comments, and
idris monad totalityassert_smaller
My journey of learning the Idris programming language continues! This article will start a tutorial series detailing how to write FizzBuzz in Idris. As before, my goal is to write without the assumption that all Idris learners already know Haskell. We will start by implementing
modulo
in Idris, and toward that goal we will go painfully slow because frankly this stuff is hard. -
Hello, Idris World! and Why I'm Excited for a Total Programming Language
idris totalityThis article represents my first attempt to get up and running with the Idris programming language. It will document not only how to make an executable Idris package but also the basics of what Idris is and why it's not like any other programming language you're likely to have used before. From a practical perspective, it will cover some basic syntax as well as how to compile and run an Idris 2 program, including .ipkg usage.
-
Why Every Programming Language is Terrible
clean-code commentary languages productivityTell me you've never hated your programming language. Tell me it doesn't have any features you wouldn't be caught dead actually using. Tell me there's a programming language so dear to you that you not only enjoy writing it in the moment but enjoy reading what you've written in the somewhat distant past. Tell me—and this is key—that you not only enjoy reading what you've written, but what others have written.
-
Running Play Framework on NixOS using JDK 11
nixos play-framework sbt scalaGood morning! First, some personal news: I'm switching to NixOS, and I'm kind of excited about it, so expect some articles to that effect. Today, I'm celebrating the ease with which I got a Play Framework environment up and running, including installing sbt and downgrading to JDK 11.
-
De-Microsofting Your Development Environment
commentary javascript rescript toolingAnyone who has been following the web ecosystem over the last few years knows it has been rapidly consolidating under Microsoft. That consolidation economically threatens the open web. Diversifying your tooling could protect you as much as diversifying any investment, and it's much more convenient than you might think.
-
Continuously Deploying to GitLab's NPM Package Registry
devops gitlab javascript npm rescriptIn a previous article, we explored how to continuously deploy to the npmjs.com package registry. This is all well and good, but an advantage of CI/CD is that we can easily deploy wherever we want. This article will explore how to deploy an npm package to both npmjs.com and GitLab's own package registry, including how to change package names when necessary.
-
The Second Best Way to Pick Your Next Programming Language
commentary growth languages object-orientationExperienced developers often say that the best way to pick your next language to learn is to pick a project you want to ship and pick the best language for the job. This isn't wrong, but beginning developers often respond that the only "project" they have in mind for now is to learn more about programming generally and become a better developer overall. If this is your goal (and it's a good one!), then the "best way" to pick your next programming language just isn't applicable. But I think you'll appreciate the second best way.
-
Writing Elm Ports in ReScript - 0.3
documentation elm rescriptThis is an update to a previous article following a breaking change in the
res-elm
binding. In short, theinit
function has been broken up intoinit
andinitWithOptions
to allow for Elm initialization flags and Elm web applications. Recently I've published an npm package called res-elm and put it into production on a couple of projects. It's documented briefly by its README, but I think it deserves a full post. This post will walk through how to set up ports both into and out of an Elm 0.19 project using ReScript. -
Why I'm Not Writing about Myself for SheCoded
commentary feminismFirst: I do get the irony of this article; there's no way around the idea that I am, actually, writing a post for the Dev.to #shecoded tag. But there are so many things that bother me so much about this annual event as a feminist, so instead of writing about my own experiences, I want to offer some ways to make the annual #shecoded event better.
-
Better Continuous Deployment with GitLab CI/CD
devops gitlab npmThis article follows up with a previous article, which details the bare minimum for a CI/CD pipeline from GitLab to the npmjs.com package repository. It's not a bad start for learning how to deploy to npmjs.com from a pipeline, but as a pipeline itself, it's... well, it was my first attempt. This article will detail a better pipeline in terms of maintainability, build-safety, and testing. (NPM will still be used as an example, but the broader concepts will be applicable to other stacks.)
-
Containerizing your CLI tools for a clean development experience
containers devops npm productivitySome platforms are more delicate than others. Once, in college, I ended up with a Scala installation that used a different version of Java than my version of Eclipse. It was a lot like trying to maintain a particularly aggressive aquarium. How do I keep these feisty little guys from trying to murder each other? Headaches like this are one reason I try to keep my dev environment as clean as possible with a stock installation of Ubuntu, a handful of programs, and precious few customizations. It makes it a little harder to foul up and a lot easier to nuke and pave with a fresh installation if needed. Recently, I've decided to embrace the logical conclusion to this method by avoiding installing any extra command line tools at all. No node, no javac, no competing for my
$PATH
; just me, emacs, and docker. -
Binding to a JavaScript Function that Returns a Variant in ReScript
javascript indexeddb rescript variantNote from the future: In the current year, none of this article is relevant anymore. Use Rescript's
@unboxed
attribute instead. It solves the whole problem I was trying to solve with this article, but much more cleanly. I will leave this article here as a historical record. ReScript provides easy ways to bind to most JavaScript functions in a way that feels both native and safe. Conveniently, it even provides an@unwrap
decorator for parametric polymorphism. However, there are a few places where we still have to fill in the gaps. This article documents how to bind to a JavaScript function that can return any one of several different types using ReScript variants. -
Styling for Internet Explorer Using Progressive Enhancement
css legacy progressive-enhancementInternet Explorer 11 accounts for less than one percent of total Internet usage globally and less than half a percent in the United States. Even Microsoft's own web apps have stopped supporting it. But on the off chance someone does use Internet Explorer, what do you want them to see? This article explains how to employ the concept of progressive enhancement to provide a moderately acceptable experience to users of a decaying platform without taking on all of the legacy burden of formally targeting it.
-
Writing Service Workers in ReScript
bucklescript documentation progressive-web-app reasonml rescript service-workerDoes your SPA work fully offline? Would you like to define a caching strategy in an exhaustively type-safe way? If so, you might be interested in this Service Worker binding for ReScript (formerly BuckleScript / ReasonML). This article documents the binding by example, including two different caching strategies and a service worker registration example.
-
Setting Up Webpack for ReScript
bucklescript progressive-web-app reasonml rescript webpackAs much as I strongly prefer ES6 modules, using them with ReScript (formerly BuckleScript / ReasonML) and ServiceWorkers just isn't practical right now. I'm writing this article so that I can easily grab the configuration the next time I need it. This is a beginner's guide because I am a webpack beginner, and, well, everyone is a ReScript beginner right now.
-
Displaying Notifications in ReScript
documentation progressive-web-app rescriptThis article will serve to document and demonstrate the
rescript-notifications
npm package, a complete set of bindings for the JavaScript-compiling ReScript language (formerly BuckleScript/ReasonML). At the close of this article, the reader should be able to enable and display notifications in an entirely type-safe and functional way. -
Writing Elm Ports in ReScript
bucklescript documentation elm reasonml rescriptThis is a post-rebrand update to my previous post, "How to Write Elm Ports in ReasonML." I rewrote the package in the new ReScript syntax so that people who aren't familiar with the old syntax can still read it. Recently I've published an npm package called res-elm and put it into production on a couple of projects. It's documented briefly by its README, but I think it deserves a full post. This post will walk through how to set up ports both into and out of an elm 0.19 project using ReScript.
-
Tracking COVID-19 Vaccinations in Chicago: Release Notes
documentation data-visualizationHappy New Year, and thank you for reading! I am delighted to announce that the City of Chicago has started reporting daily statistics on COVID-19 vaccinations, and so am I. This article will detail recent changes as well as changes to come in the near future.
-
Designers and front-end folks! How do you name colors?
clean-code css frontend helpIn my back-end life, naming values that get reused is important to maintaining clean code, but somehow I keep turning my CSS variables into spaghetti. I've tried three basic strategies, none of which seem to work quite right for me.
-
Continuously Deploying an NPM Package with GitLab CI/CD
devops gitlab npmSetting up continuous deployment is important to me, even when publishing is as simple as it is on npm. The official GitLab documentation, though, is a little more than I need and geared toward their own npm repository, so I'd like to gather the information I need here in a brief article.
-
Parsing JSON in ReScript Part III: Getting to the Point
bucklescript rescript reasonml monadAfter having established some requirements and some basic utilities, we're ready for the fun part: putting the pieces together. At the end of this post, we will have our working parser.
-
Parsing JSON in ReScript Part II: Building Blocks
bucklescript rescript reasonml monadThis is the second in a series of articles on how to build one's own, general-purpose parsing library. After having established a few expectations in the previous post, we are ready to begin building our utilities for our library. Let's start with some highly generalized utilities for functional programming.
-
Parsing JSON in ReScript Part I: Prerequisites and Requirements
bucklescript monad rescript reasonmlThere are few things more satisfying than a slick, readable, and safe JSON parser. It's one of the joys of functional programming. Using a good JSON parsing pipeline can feel like magic. This series seeks to lift the veil and empower readers (and, importantly, my future self) to build their own customizable and extensible parsing libraries. This article, the first of several, will be a skimmable introduction to the subject as I see it.
-
How to Upgrade from BuckleScript to ReScript
bucklescript emacs rescript reasonmlI have a weakness: I have never seen an update I didn't want to adopt immediately. Betas? No thanks. Give me the nightly build. New major version of the Linux kernel? I'll just run the installation without stopping to grab my charger. So when BuckleScript announced a whole new language syntax (along with a rebrand to "ReScript"), I got excited and immediately wanted to transpile everything. This post will document the simple process step-by-step.
-
Tracking COVID-19 in Chicago: Release Notes
data-visualization documentationChicago Test Out is a project that use the same datasets as the city data Daily Dashboard but features more detailed line charts, mobile compatibility, and much faster load times. This week, the project is undergoing several major changes, and I want to take the opportunity to explain these changes for users.
-
Safer Data Parsing with Try Monads
csharp monadI have written previously on maybe monads and how to use them with lists to eliminate the possibility of null references in an object-oriented programming language. This standalone post walks through how to use a more generalized kind of monad to prevent all other kinds of unhandled exceptions, using data parsing exceptions as an example.
-
Error-Free C# Part II: Functional Data Processing
csharp monadMutability bugs and thread-unsafety are big problems in data processing. Fortunately, the .NET Framework has strong support for immutable collections, eliminating entire categories of bugs. This post will show how to use extension methods to create even safer ways to interact with with lists in C# by building on the IMaybe monad type we created in the previous post in this series.
-
Error-Free C# Part I: The Maybe Monad
csharp monadMost people would probably be surprised to find that I consider myself both a professional C# developer and a professional functional programmer. C# is mainly an object-oriented language. The syntax isn't optimized for functional programming. This is entirely true, but just because Microsoft is behind the curve in supporting the new best practices in programming doesn't mean I have to be. This series will walk through how to build and use C# code that is guaranteed to run without any runtime errors.
-
ReScript: The Module or File Can't Be Found, Unabridged
rescript bucklescript reasonmlIf you work with BuckleScript, now ReScript, you'll likely come across the common build error message, "The module or file $name can't be found" followed by a few helpful suggestions for how to properly install a ReScript module. It's a good error message, but I've found it underestimates me in my ability to get things wrong, especially if I'm the one who wrote the missing module to begin with. I'm going to write a guide while one of these problems is still fresh in my mind so that I have a checklist to go through the next time I get frustrated.
-
How to Write Elm Ports in ReasonML
bs-elm-es6 bucklescript documentation elm reasonmlRecently I've published an npm package called bs-elm-es6 and put it into production on a couple of projects. It's documented briefly by its README, but I think it deserves a full post. This post will walk through how to set up ports both into and out of an elm 0.19 project using BuckleScript 7. (If you're curious, I'm deferring decisions about the rebrand/new syntax until we get the new npm package.)
-
How to Use Excerpts in Eleventy
eleventy javascriptRecently, I added first-paragraph post excerpts to this Eleventy blog's homepage post list. I found it wasn't easy. It wasn't all documented all in one place. Further, in order to use Markdown excerpts in HTML, I had to write a simple custom filter. I'd like to document the process here from end to end.
-
Issues and Contribution
documentationI've pushed out a few packages recently, and I'd like to take the opportunity to publish a catch-all document on contribution and issues for each of these. This post will walk the user through my current thinking on how to engage these projects, and I'll keep it up to date as my thinking evolves.
-
Elm Line Charts Part III: Lines and the Chart
data-visualization elmThis is the last installment of a series describing how to configure an Elm LineChart. In the previous post I used a viewmodel to configure an axis, so this post will cover how to use lists of those viewmodels to plot the rest of the chart.
-
Elm Line Charts Part II: Imports and Axes
data-visualization elmThis is the second in a series of blog posts dealing with LineChart in Elm. In the previous post, I outlined how to grab the timezone as a prerequisite for time-based linecharts. In this post, I will begin to write the chart module I'm trying to use in Chicago Test Out by defining my imports and creating a custom axis.
-
Elm Line Charts Part I: Times and Timezones
data-visualization elmElm has a very fine third-party line chart library which I've enjoyed using in my passion project, Chicago Test Out. It's well-documented as a library, but if I haven't used it in a while, I find myself struggling to get started with it. I end up starting at the middle or near the end and then clumsily working backwards from where I want to end up. For this reason, I'm working on writing a step-by-step guide for working with
terezka/line-charts
based on my own preferences and assuming a high-degree of customization apart from the defaults, using Chicago Test Out as a model. -
Dynamic Options and Optional Parameters in ReasonML
bucklescript monad reasonmlThe next type I want to bind from the JavaScript ServiceWorker API is Cache. At first glance,
Cache
doesn't have any dependencies on any JavaScript interfaces we don't already have access to, but its methods do use dynamic JavaScriptoptions
parameters, and the way we deal with this in typed languages is to name and create new specialized types. In this post, I will implement types for theseoptions
and the functions that use them. -
Binding FetchEvent Using Properties and Constructors
Having successfully bound ExtendableEvent, I can now work on inheriting this interface for FetchEvent. Along the way, I'll install bs-fetch as a BuckleScript dependency and bind to JavaScript properties.
-
ReasonML Journey Part IV: Publishing BuckleScript Packages on NPM
bucklescript npm reasonmlIn the previous post, we finished wrapping ExtendableEvent in ReasonML. In this post I will publish our type on npm.
-
ReasonML Journey Part III: Generics, Promises, and ExtendableEvent.waitUntil()
bucklescript promise reasonmlThis post continues the quest of trying to recreate the JavaScript service worker class ExtendableEvent in ReasonML. In this post I will show how to extend the subtype of
event
to includeExtendableEvent
's waitUntil method, which takes a generic Promise as a parameter. -
ReasonML Journey Part II: Subtyping and ExtendableEvent
The first stop on my quest to wrap a JavaScript library in ReasonML is a small, simple JavaScript interface ExtendableEvent, a class with no properties and only one method on top of what it inherits from Event. In this brief blog post I will set out a simple template for subtyping in ReasonML.
-
ReasonML Journey Part I: Getting Started with BuckleScript
bucklescript reasonmlReasonML is, at the time of this post, a very young language and, as such, very much underdocumented. It's also missing a lot of the JavaScript standard libraries. I see both of these things as an opportunity to contribute both to the foundational documentation and to the libraries that haven't been written yet. This blog series will serve mainly as a resource to me as an absolute beginner trying to retrace my steps, but I hope that someone else may someday find it useful as well.