Skip to content

Instantly share code, notes, and snippets.

View bcherny's full-sized avatar

Boris Cherny bcherny

View GitHub Profile

The range of the mind's eye is restricted by the skill of the hand. The castles in the air must conform to the possibilities of material things -- border-line possibilities perhaps; or, if something beyond the known border is required, the plan must wait until other dreams come true.

Harry Brearley, inventor of stainless steel, from his memoir (reprinted in Nautilus, May/June 2016, p. 35)

In corporate religions as in others, the heretic must be cast out not because of the probability that he is wrong but because of the possibility that he is right.

Antony Jay (reprinted in https://www.cs.utexas.edu/users/EWD/transcriptions/EWD08xx/EWD831.html)

The Stone Age did not end for lack of stone, and the Oil Age will end long before the world runs out of oil.

Proposal: @flow strict-readonly

Motivation

Much of our product code uses immutable data structures. This is largely because when working with React (particularly: props and Hooks), accidental mutation is a common source of errors ("why won't this re-render?").

Today, enforcing this immutability is something that happens via a mix of Flow types, ESLint rules, and code review. It results in hard-to-read types like:

type Props = $ReadOnly<{

Proposal: Mirrored syntax at the type and value-levels

Motivation

Make it easier to express the operations we work with most often:

  • When modeling GraphQL types with Flow: Looking up the type of a field in a nested object type, where every field along the way is nullable and optional
  • When authoring React components: Looking up the type of a prop on another component that we compose, to directly expose it on our component too

Proposed features

Proposal: Mirrored syntax at the type and value-levels

Motivation

Make it easier to express the operations we work with most often:

  • When modeling GraphQL types with Flow: Looking up the type of a field in a nested object type, where every field along the way is nullable and optional
  • When authoring React components: Looking up the type of a prop on another component that we compose, to directly expose it on our component too

Proposed Features

import * as t from '@babel/types'
const rawQuery = astql`
node {
...on Function {
__typename
}
}
`;
function longestSeq(arr, of) {
let lengths = {}
let max = 0
arr.forEach(n => {
if (lengths[n - of]) {
lengths[n] = lengths[n - of] + 1
delete lengths[n - of]
} else {
lengths[n] = 1
}

On Contagion

If you have a tree with a node that has a property P, and all of its parents also need to have property P, then P is contagious.

When can that happen?

  • Exceptions bubble up through the call tree
  • State has to be lifted up to the root of a call tree
  • If a function is async, its ancestors must be too
  • In a physical system, if you know the position and momentum of an object A and it collides with another object B that you don't know one of those quantities for, then you no longer know them about A. (caveat: I'm no physicist)
/////////////// 1ST CODE SAMPLE (PAGE 140) ///////////////
type Unit = 'EUR' | 'GBP' | 'JPY' | 'USD'
type Currency = {
unit: Unit
value: number
}
let Currency = {
@bcherny
bcherny / Option.ts
Last active July 9, 2019 22:52
Draft: Reference Option implementation for Programming TypeScript
function Option<T>(value?: null | undefined): None
function Option<T>(value: T): Some<T>
function Option<T>(value?: T): Option<T> {
if (value == null) {
return new None
}
return new Some(value)
}
interface Option<T> {
@bcherny
bcherny / $arguments.flow.js
Created June 10, 2019 00:03
Flow: $Arguments
type $Arguments<F> = $Call<<A: $ReadOnlyArray<mixed>>((...A) => mixed) => A, F>;
type $MethodArguments<O: {}, F: $Keys<O>> = $Arguments<
$NonMaybeType<$ElementType<O, F>>,
>;