Skip to content

Instantly share code, notes, and snippets.

Quick explanation of why the "control inversion" trick in this explanation of existential types on StackOverflow is actually currying:

  • the type of the original for-loop body was (∃B:VirtualMachine<B>) -> IO void
    • (where IO void represents that vm.run() had side-effects and a void return type)
  • the type of VMHandler.handle() is ∀B:(VirtualMachine<B> -> IO void)

If you interpret an existential type as describing a pair of a type and a value, and interpret a universal type as describing a function from a type to a value (see footnote), then those can be interpreted as:

  • the original for-loop body: (B, VirtualMachine<B>) -> IO void
  • VMHandler.handle(): B -&gt; VirtualMachine<b> -&gt; IO void

Extensible functions in Mechanical

Extensible functions are like Java interface, Rust trait, or Haskell typeclass methods, except the interface name is optional, you can define a standalone method signature (basically an anonymous one-method interface), or if you want you can define an interface which is a set of method signatures.

To implement an extensible function on a tag (or a pattern of multiple tagged variants), you have to either be the module that defined the extensible function, or the module that defined one of the tags that your implementation is restricted to. This is so you can't have like, two independent dependencies providing conflicting implementations of the method for the same tag. (Should it be relaxed to, you have to be the package that owns the extensible function or a tag, instead of the specific module?) This is called coherence by Rust and Haskell.

Like Rust trait/Haskell typeclass methods, and also like function overloading in C++ and Java, dispatch is static and can be based

Thoughts about how to do (minimal-ish) perfect hashing of Mechanical/EffectScript tag IDs for branch tables for pattern-matching:

  • the goal is to minimize CPU clock cycles to jump to the correct branch; the classic minimal perfect hashing algorithm is a 2-level hashing scheme which is undesirable overhead. We should be able to get it down to at worst one integer multiply, bitmask, and bitshift
  • for actual minimal perfect hashing would have to do integer modulo, which is a slow instruction, instead hash to range from 0 to nearest power-of-2 (eg for 5 items, has to 0-7) which only requires bitmasking, call that DESIRED_RANGE
  • tag IDs aren't randomly distributed across 0-INT_MAX, they're small-ish numbers maxing out in like thousands for big codebases presumably
  • find min and max tag ID; if max - min ≤ DESIRED_RANGE then we can just hash by subtracting min tag ID; otherwise let MAX_BIT_SIZE = ceil(log2(max tag ID))
  • if we can get by with just bitmask and bitshift that'd be great. Let MAX_BIT_POSITION = MAX

Text and Unicode in Blossom Notebook

The Absolute Bare Minimum You Need To Know

Consider the text:

Sent in my résumé! 😮‍💨

Computers represent that as zeroes and ones:

Minimalist Layout System

This super simple, fast, flexible layout system operates in a single pass (no reflow or constraint solving) and is probably <100 lines of non-comment, non-duplicate logic (there's a lot of duplicate logic between the top/left/right/bottom directional code that's not worth de-duplicating).

To layout PinLayout's Example 1:

pinlayout example 1

The code is much simpler than PinLayout's:

Simpler Stack Switching for Wasm

To me, #1360 "First-Class Stacks" seems like it started out great, in particular primitive stack-switching seems like a great low-level building block for everything you'd want to do including algebraic effects (#1359); but then it seems to me like it ended up both overly complex and yet also underspecified. In particular, stack extension and redirection seem like they should be extensions to stack-switching added later; whereas creating stacks seems like it would be immediately necessary for priority use cases like the Go and Erlang runtimes, and it seems like it would be a simple win to be able to send normal, non-exception values and thus remove the dependency on the exception-handling work.

Just like the TinyGo author suggested, it seems to me like it would be simplest to just have 3 instructions for creating, using, and destroying stack continuations, respectively:

  • (for brevity, `(cont X … -
// https://jsbin.com/xirefor/edit?js,output
var paper = Raphael("paper", 600, 600)
var n = 7 // number of boolean variables
var C1 = function(x1, x2, x3, x4, x5, x6, x7) {
return !x2 || !x3 || !x4 || x5
}
var C2 = function(x1, x2, x3, x4, x5, x6, x7) {
return !x1 || !x5 || x6
<?xml version="1.0" encoding="utf-8"?><VisioDocument xml:space="preserve"><FaceNames><FaceName CharSets="1614742015 -65536" Flags="357" ID="1" Name="Arial Unicode MS" Panos="2 11 6 4 2 2 2 2 2 4" UnicodeRanges="-1 -369098753 63 0"/><FaceName CharSets="-2147483648 0" Flags="261" ID="2" Name="Symbol" Panos="5 5 1 2 1 7 6 2 5 7" UnicodeRanges="0 0 0 0"/><FaceName CharSets="-2147483648 0" Flags="261" ID="3" Name="Wingdings" Panos="5 0 0 0 0 0 0 0 0 0" UnicodeRanges="0 0 0 0"/><FaceName CharSets="1073742335 -65536" Flags="325" ID="4" Name="Arial" Panos="2 11 6 4 2 2 2 2 2 4" UnicodeRanges="-536859905 -1073711037 9 0"/><FaceName CharSets="262145 0" Flags="421" ID="5" Name="SimSun" Panos="2 1 6 0 3 1 1 1 1 1" UnicodeRanges="3 680460288 6 0"/><FaceName CharSets="1048577 0" Flags="421" ID="6" Name="PMingLiU" Panos="2 2 5 0 0 0 0 0 0 0" UnicodeRanges="-1610611969 684719354 22 0"/><FaceName CharSets="1073873055 -539557888" Flags="421" ID="7" Name="MS PGothic" Panos="2 11 6 0 7 2 5 8 2 4" UnicodeRanges="-536870145 179149

PackSec: Package-level capability-based security

What: A capability-secure version of Node.js, and an ecosystem of capability-secure repackaged versions of existing NPM packages, community-contributed and hosted on GitHub like Homebrew & DefinitelyTyped.

Why: Immediately, this provides strong defense against malicious dependencies (supply chain attacks) like event-stream, electron-native-notify, typosquatting like crossenv, and thousands more; as well as vulnerable dependencies like JS-YAML, [`express-fileupl