Typescript Retrospective

As part of trying out Svelte, I’ve also stepped into the modern web development ecosystem. I previously worked primarily in Clojurescript, so my reference point is based on being away from conventional web dev for many years. The Good Parts Getting Started is Easy Having not have to build anything yourself is can be nice if you want to deliver something quickly. This is doubly true when Svelte allows you to pull a library that doesn’t have explicit view framework support (eg - ReactJS). Need auth? Use AuthJS. Everything is so easy. ...

October 1, 2024 · 4 min

Svelte 5 for ReactJS Users

Disclaimer: I didn’t learn Svelte before v5, so this is an experience report on translating Svelte 4 code to 5. This is a blind jump into Svelte. The Basics Svelte components end in .svelte like .jsx or .tsx. They look more HTML-like than JavaScript. In comparison, ReactJS is more JavaScript-like than HTML. <script> let { name } = $props(); </script> <h1>Hello, {name}!</h1> Typescript To use TypeScript, add lang=”ts” to the script tag: ...

September 23, 2024 · 3 min

Toml Crash Course

Background Since migrating this site to Hugo, I felt like it was finally time to avoid learning TOML. This assumes you don’t know TOML but know other data formats? Time to speedrun through. The 30-second Start You can think of toml as key value file format with namespace prefixes that translate to JSON: # this is a comment key = "value" [my-key-prefix] key2 = "value2" person.name = "John" Conceptually produces { "key": "value", "my-key-prefix": { "key2": "value2" }, "person": { "name": "John" } } Dot-notation indicates a nested object. In the spec, TOML calls objects tables. ...

September 19, 2024 · 2 min

check.statem: Generating Test Programs

One of the most interesting parts of generative testing (aka QuickCheck). Is state machine testing. The original purpose I built Fox was to explore state machine testing. In particular, the talk from John Hughes video was inspirational to exploring this further: In short, John makes a case: dynamically generating state machines to detect errors that is more effective and economical than traditional example based tests. There’s lots of work managing example based tests that can be better solved with generative testing. ...

January 5, 2020 · 6 min

Reading Code – Assertions & Assumptions

I’m fascinated by how engineers read and interpret code that they work on a daily basis. It’s no doubt different for everyone, but few explain how they go about and understand a unfamiliar codebase. For me, being comfortable in a codebase usually means two things: Being able to jump to relevant, related parts of the code. Understand the implications of changing a piece of code Inside the system – impact of code quality. How does the code influence code in the same project? Outside the system – implications for human and program collaborators. How does the code influence other projects, teams, or users? Both can be addressed by following the data flow of the code. I refer to my strategy as assertions and assumptions. Take this arbitrary code snippet from Django: ...

August 31, 2016 · 5 min

What's Your Engineering Culture?

When evaluating companies, its utmostly important to learn about the engineering culture. Culture for a company is simular to scope for code – culture provides a context for getting work done. Companies advertise their culture, but note that each company has a different culture. There’s plenty of articles about culture, so I won’t bother covering that. Just remember they aren’t necessarily the same. Companies tend not to be explicit about making sure their process matches what you expect. Be suspicious for a company that can’t explain it’s culture because that just means they’re not activitely trying to cultivate one. And that means it’s implicitly defined by the leaders of the company. Even if they choose not to define it. ...

July 31, 2016 · 4 min

TLDR Programming Concepts

Trying to concisely describe concepts is an interesting exercise. The ideal goal is to build upon existing concepts, but as you add more concepts you run the risk of being inconsistent. So with at most two sentences, I present a list of common programming concepts. This goes without warning that lossy compression is inevitable. Data: Ones and zeros. Values: Meaningful data. Types / Encodings: Interpretations of values. State: A value that changes over time. Usually also considered a Value. Variables: Names for values over time. Collections: A value that’s a a group of values of same type. Structs: A value that’s a group of values with possibly differing types. Classes: Structs with functions that have itself as the first argument. Inheritance: A concise way to implement a class by referring to part of its implementation from one class. Multiple Inheritance: A class that inherits from multiple other classes. Extensions: Adding methods to a previously defined type. Mixins: Adding (Multiple) Inheritance to a previously defined type. Interface / Protocols: Inheritance of a class that has only functions that should be implemented by the class that inherits it. Traits: Interfaces that may have function implementations. Generics: Treating a type as a variable. Allows algorithms independent of specific types. Type Classes: Generic Interfaces. Monad: An interface defining the expected behavior for map. Functor: An interface defining the expected behavior for apply. Pointers: A value that indicates where to find another value. An home address is a pointer to a home. Big-O Notation: A method to estimate the number of main-memory operations Slice: A value that is a pointer and length into an existing collection Value Objects: An struct / class with equality and hashCode semantics. Object-Oriented Programming: The concept of classes talking to each other using value objects. Procedure: A sequence of operations to execute. Most programming languages mean procedure when they say function. Function: Vaguely defined / blurred by current norms. See Procedure. Pure Function: A procedure that returns the same output for the same inputs. Side Effects: Any observable state that occurs besides a return value. Functional Programming: The practice of using less state and more pure functions. Code: A value that is a series of operations AST (Abstract Syntax Tree): Hierarchy of typed code Program: A collection of code that a computer that can execute. Compiler: Program that take code and produce programs. Interpreter: A program that executes code without producing a program. Emulator: A program that mimics the behavior of hardware. Virtual Machine: A computer emulator where the hardware may not actually exist (eg - Java Virtual Machine). Static: Known at compile-time. Dynamic: Known at execution-time. Type Checker: A program that validates what types flowing through your code. Type Inference: A compiler or interpreter feature can that deduce types without always explicitly specifying it in code. Optimization: Writing code for the computer first, instead of humans. Performance: Turning memory operations for lower frequency, and higher throughput. Reference Counting: Counting number of owners of a piece of memory to know when to free it. Garbage Collection: An embedded program that frees another program’s memory that is no longer being used. Reflection: Code that can inspect and/or modify itself as it’s executing. Macros: An operation that can be translated to a sequence of operations before program execution. JIT (Just-In-Time) Compilation: A feature of interpreters or emulators that compiles code during its execution. The last concept pushes the limits of definitions this concise. Some interesting implications result from these definitions: ...

June 30, 2016 · 4 min

Two Kinds of Abstractions

When someone talks about abstractions, they’re usually trying to make the software more flexible. But that’s usually one of two kinds of abstractions. Build an abstraction to hide an implementation Abstractions that hide implementations are more commonly touted as good designs. Ruby’s Faraday abstracts the specific HTTP library implementation. Rails’ ActiveRecord abstracts the SQL you need to write to interface with a relational database. The Data Mapper Pattern abstracts the persistent storage from your application. ...

May 31, 2016 · 6 min

Design of Software Solutions

What’s the best way to model a solution? In software, there’s several common ways of building solutions that solve specific problems. It’s worth trying to identify their characteristics and the tradeoffs they make. Architect the Software After the Current Problem The easiest is way to model software. There’s no need to take in consideration of future solutions the user made want. Sometimes this is what you need. If you’re writing a throw-away program, the fastest possible way to implement it is to codify for the exact problem you’re trying to solve. An example are most shell scripts. They tend to not be abstracted and usually automate a very specific task. ...

April 30, 2016 · 5 min

Editing Text (Basics)

Background The problem seems simple: open, edit, and save text files. This can range from JSON files to source code like every other editor. Turns out, this is a relatively difficult problem. The rise of javascript text editors surfaces the performance problem of editing large text. It’s a non-trivial problem. There are several desirable characteristics that editors want: Editors need to optimize for edits. Having immediate feedback for changes is paramount to text editing. This includes editing large files. Editors need to optimize for reads. This is implied for optimized edits so that users can see immediate feedback to their edit. This also includes support for large files. Editors should minimize memory usage. Reduced overhead for storage of text leaves more memory for more text buffers. This is useful for developers editing multiple projects at once (eg - microservices). Different data structures support these requirements in varying degrees of success. For the sake of this article, I’m ignoring many other features editors usually have: ...

March 31, 2016 · 5 min