Who

Path Toward Enlightenment

Ever wonder how to write good code?  Or how to make a good abstraction? 

Zen code makes it remarkably easy.  Its quality comes from its clarity which comes from precision.  Good abstractions are inherent to this process. 

This is the first part in a series on zen code, so I’ll start with an example from which you can develop your intuition and finish with a definition that is inherently lacking but a good place to start. 


For this humble segment of code I present
its path toward enlightenment

interface WidgetPart {
  name: string;
  // ...
}
type WidgetPartData = WidgetPart[]
type Widget = WidgetPartData[]

function createWidgetsFromParts(widgetParts: WidgetPartData): Widget {
  const widgets = widgetParts.reduce((acc, widgetPart) => {
    if (!acc[widgetPart.name]) {
      acc[widgetPart.name] = []
    }
    acc[widgetPart.name].push(widgetPart)
    return acc
  }, {})

  return widgets.values()
}

Breathe, without judgement, notice how it is. 

It seems WidgetPartData and WidgetPart[] are, by definition, the same.  Are they the same if they have different names?  Or is one thing with two names actually two things? 

Let go of immaterial things. 

interface WidgetPart {
  name: string;
  // ...
}
type WidgetPartData = WidgetPart[]
type Widget = WidgetPart[][]

function createWidgetsFromParts(widgetParts: WidgetPart[]): Widget {
  const widgets = widgetParts.reduce((acc, widgetPart) => {
    if (!acc[widgetPart.name]) {
      acc[widgetPart.name] = []
    }
    acc[widgetPart.name].push(widgetPart)
    return acc
  }, {})

  return widgets.values()
}

Something is distracting about a function called createWidgetsFromParts and returns a Widget[], but the code says to return widgets.values() and all of that is typed as a singular Widget. 

Be honest with yourself. 

interface WidgetPart {
  name: string;
  // ...
}
type Widget = WidgetPart[][]

function createWidgetsFromParts(widgetParts: WidgetPart[]): Widget {
  const namesToArraysOfWidgetParts = widgetParts.reduce((acc, widgetPart) => {
    if (!acc[widgetPart.name]) {
      acc[widgetPart.name] = []
    }
    acc[widgetPart.name].push(widgetPart)
    return acc
  }, {})

  return namesToArraysOfWidgetParts.values()
}

With honesty comes insight.  The code says it returns a Widget[] and then it returns namesToArraysOfWidgetParts.values(), so Widgets must then be arrays of WidgetParts. 

Declutter your mind, focus on the essence. 

interface WidgetPart {
  name: string;
  // ...
}
type Widget = WidgetPart[]

function createWidgetsFromParts(widgetParts: WidgetPart[]): Widget[] {
  const arraysOfWidgetParts = widgetParts.reduce((acc, widgetPart) => {
    if (!acc[widgetPart.name]) {
      acc[widgetPart.name] = []
    }
    acc[widgetPart.name].push(widgetPart)
    return acc
  }, {}).values()

  return arraysOfWidgetParts
}

What feels out-of-place?  Put it somewhere.  Reflect on its purpose, its function.  Give it a name and see how it feels. 

interface WidgetPart {
  name: string;
  // ...
}
type Widget = WidgetPart[]

function createWidgetsFromParts(widgetParts: WidgetPart[]): Widget[] {
  const arraysOfWidgetParts = groupWidgetPartsByName(widgetParts)
  return arraysOfWidgetParts
}

groupWidgetPartsByName(widgetParts: WidgetPart[]): Widget[][] {
  return widgetParts.reduce((acc, widgetPart) => {
    if (!acc[widgetPart.name]) {
      acc[widgetPart.name] = []
    }
    acc[widgetPart.name].push(widgetPart)
    return acc
  }, {}).values()
}

Release thoughts from the past to examine the nature of the code. 

interface WidgetPart {
  name: string;
  // ...
}
type Widget = WidgetPart[]

function createWidgetsFromParts(widgetParts: WidgetPart[]): Widget[] {
  return groupByName(widgetParts)
}

groupByName<T>(array: T[]): T[][] {
  return array.reduce((acc, item) => {
    if (!acc[item.name]) {
      acc[item.name] = []
    }
    acc[item.name].push(item)
    return acc
  }, {}).values()
}

This code is the same as all code.  There’s nothing special about “name” when grouping objects. 

Everything we type is an abstraction whether intentional or not. 

Be one with everything. 

interface WidgetPart {
  name: string;
  // ...
}
type Widget = WidgetPart[]

function createWidgetsFromParts(widgetParts: WidgetPart[]): Widget[] {
  return group(widgetParts, { by: 'name' })
}

group<T>(array: T[], { by: property }: { by: string }): T[][] {
  return array.reduce((acc, item) => {
    const key = item[property]
    acc[key] ??= []
    acc[key].push(item)
    return acc
  }, {}).values()
}

Those keys aren’t always safe as object properties - they’ll be safe in a Map instead. It’s a corner case now; it might be a data breach later. 

All things are connected. Taking care of this code is improving all code. 

interface WidgetPart {
  name: string;
  // ...
}
type Widget = WidgetPart[]

function createWidgetsFromParts(widgetParts: WidgetPart[]): Widget[] {
  return group(widgetParts, { by: 'name' })
}

group<T>(array: T[], { by: property }: { by: string }): T[][] {
  return array.reduce((acc, item) => {
    const key = item[property]
    const value = map.get(key) ?? []
    value.push(item)
    map.set(key, [item])
    return acc
  }, new Map()).values()
}

Seek simplicity.  Reuse.  Give back. 

import { group } from 'community-library'

interface WidgetPart {
  name: string;
  // ...
}
type Widget = WidgetPart[]

function createWidgetsFromParts(widgetParts: WidgetPart[]): Widget[] {
  return group(widgetParts, { by: 'name' })
}

group<T>(array: T[], { by: property }: { by: string }): T[][] {
  return array.reduce((acc, item) => {
    const key = item[property]
    const value = map.get(key) ?? []
    value.push(item)
    map.set(key, [item])
    return acc
  }, new Map()).values()
}

Reflect - is it any better than how it started? 

original new
interface WidgetPart {
  name: string;
  // ...
}
type WidgetPartData = WidgetPart[]
type Widget = WidgetPartData[]

function createWidgetsFromParts(widgetParts: WidgetPartData): Widget[] {
  const widgets = widgetParts.reduce((acc, widgetPart) => {
    if (!acc[widgetPart.name]) {
      acc[widgetPart.name] = []
    }
    acc[widgetPart.name].push(widgetPart)
    return acc
  }, {})

  return widgets.values()
}
import { group } from 'community-library'

interface WidgetPart {
  name: string;
  // ...
}
type Widget = WidgetPart[]

function createWidgetsFromParts(widgetParts: WidgetPart[]): Widget[] {
  return group(widgetParts, { by: 'name' })
}

Zen code says what it is trying to say.