Skip to content

Instantly share code, notes, and snippets.

View crdrost's full-sized avatar

CR Drost crdrost

View GitHub Profile
@crdrost
crdrost / Readme.md
Created November 27, 2024 19:33
Sum Types in Other Languages

Just a quick blog about how to represent discriminated unions, also called sum types.

What are they?

A union type allows you to store one of N distinct types in the same variable. What makes it discriminated is that, if the types overlap, you should still be able to tell the cases apart.

So for example maybe we want to define a variable context which might store either a FooContext or a BarContext or a BazContext, all of which are nullable types (for other reasons in our code, let's say). When we store a null FooContext in context, we want context to still be able to tell us that it's holding a FooContext, just the null version of that. That makes it a discriminated union.

These are called "sum types" because this lack of overlap means that if there were two valid values for FooContext (the null one and some global one, say), three for BarContext, and four for BazContext, the number of valid values for context would be 2+3+4. It could have been less than this if they were allowed to "overlap

package parse_argo
import (
"io"
"regexp"
"github.com/go-logfmt/logfmt"
"github.com/msoap/byline"
)
@crdrost
crdrost / musical-notes-description.md
Last active September 4, 2019 22:15
Good numbers of musical notes

I wanted to know what sorts of equal temperament systems were objectively better than others as 12-TET occupies a very distinctive place in music theory right now.

More description to come later.

Feel free to use/modify the below code under the MPLv2 license.

@crdrost
crdrost / basics.md
Created August 1, 2019 16:49
Buda notation

The Privilege of Buda united Hungary and Poland, similarly Buda notation unites Hungarian notation (name variables after their type) with Polish notation (use prefixes of known arity to process things without ambiguity).

Operators: the character ' is reserved for functions, and it accepts two types. Following Joel Spolsky the first type is the output and the second type is the input. So 'yx is a segment of a variable name identifying a function variable of type x -> y.

Leading ' characters are inferred at the beginning of the variable name to make the name make sense.

@crdrost
crdrost / README.md
Last active June 10, 2019 20:32
best rational approximations, incrementally

Calculating best rational approximations incrementally

So best rational approximations come from a continued fraction expansion.

A continued fraction expansion comes from the loop,

function* continuedFraction(x: number): Iterable<number> {
  let n = Math.floor(x)
  yield n
@crdrost
crdrost / hughes-lists.hs
Created July 13, 2018 19:51
Paper of the day: Hughes Lists
-- paper of the day
-- RJM Hughes, A Novel Representation of Lists and its Application to the Function "Reverse"
-- Information Processing Letters 22:141-144 (1986)
-- https://www.cs.tufts.edu/~nr/cs257/archive/john-hughes/lists.pdf
{-# LANGUAGE DeriveFunctor, DeriveFoldable #-}
module HughesLists where
import Data.Monoid
import Data.Foldable
@crdrost
crdrost / description.md
Last active December 18, 2021 12:35
Itero-recursive algorithms.

Iterorecursive algorithms

Picture the following scene: you are in a job interview, and the interviewer defines a tree-based data structure and asks you to traverse it. You do a good quick job, maybe using recursion:

// provided by the interviewer: nonempty rose trees carrying the values on the internal nodes
interface ITree<x> {
  value: x;
  children: Array<ITree<x>>;
@crdrost
crdrost / test-validateRoutePath.js
Last active May 24, 2018 13:30
Tester for a validateRoutePath function that I released to nestjs/swagger.
const isUndefined = obj => typeof obj === 'undefined'
const validatePath = path => path.charAt(0) !== '/' ? '/' + path : path;
const pathToRegexp = require('path-to-regexp');
function validateRoutePathNew(path) {
if (isUndefined(path)) {
return '';
}
let pathWithParams = '';
for (const item of pathToRegexp.parse(path)) {
@crdrost
crdrost / bidir-streams.js
Created January 12, 2018 13:12
Bidirectional streams inspired by @andrestaltz
//json interpolation for string subs. Just used in shape().
const in_json = (strs, ...vals) =>
strs[0] + vals.map((v, i) => JSON.stringify(v) + strs[i + 1]).join("");
// validate shape of an object having appropriate methods.
// PLEASE do this, using if() makes this sort of "that fn doesn't handle this particular event"
// unassertable, and that means that you have whole undebuggable pipelines where "somewhere in
// this pipeline that information gets lost, I don't know where!"
const shape = (obj, ...method_names) => {
const missing_methods = method_names.some(m => typeof obj[m] !== "function");
@crdrost
crdrost / dirtree.js
Last active May 8, 2017 21:45
dirtree - shows you where you are in a filesystem tree and some of what's around
#!/usr/bin/env node
/* Copyright 2017 CR Drost.
*
* This Source Code Form is subject to the terms of the Mozilla Public License, v. 2.0. If a copy of
* the MPL was not distributed with this file, uou can obtain one at https://mozilla.org/MPL/2.0/.
*/
const fs = require('fs'),
bold = text => '\u001b[1m' + text + '\u001b[22m',