lotus.dev

the seed

Every program begins the way a lotus begins: buried in mud, in darkness, with nothing visible above the surface. The first line of code is an act of faith -- a commitment to something unseen. You do not plant a lotus and then dig it up to check on it. You write the function, trust the logic, and wait.

In the old traditions, they called this shoshin -- beginner's mind. The terminal prompt blinks, empty and infinite. The blank file is not nothing. It is potential, coiled tight as a seed casing, waiting for the warmth of your attention to crack it open.

// the first teaching:
// a function is a container for intention

function seed(intention) {
  return new Promise(resolve => {
    // patience is the only argument
    setTimeout(() => resolve(intention), season);
  });
}

A promise is a seed that knows its own flowering time.

the stem

The stem rises through murky water without becoming murky itself. This is the nature of good abstraction: it passes through complexity and arrives at the surface clean. Each layer of your architecture is a node on the stem -- root, data, logic, interface -- and each must be distinct, each must be itself, even as they serve the whole.

Consider the middleware: it sits between request and response the way a stem sits between root and flower. It transforms. It carries. It does not originate and it does not conclude. The best middleware, like the best stem, is invisible in the final presentation.

// the second teaching:
// abstraction is not hiding, it is distilling

const stem = layers => {
  return layers.reduce((water, node) => {
    return node.transform(water);
  }, muddy_input);
};

// what emerges at the surface
// remembers nothing of the mud

Abstraction is an act of kindness toward future understanding.

the leaf

A lotus leaf repels water -- droplets bead and roll off its surface like mercury on glass. In materials science, they call this the lotus effect. Your components should exhibit the same property: let external state roll off them. Accept only what you need through explicit interfaces. Return only what is asked for.

The leaf is also the site of photosynthesis -- where raw sunlight becomes usable energy. Your pure functions are leaves: they take input (light) and produce output (sugar) without side effects, without mutation, without reaching into the darkness below the water line for something they were not given.

// the third teaching:
// purity is not rigidity, it is clarity

const leaf = sunlight => ({
  energy: sunlight.wavelength * efficiency,
  waste: null,
  sideEffects: []
});

// a pure function is a leaf
// that has never touched the mud

Purity in a function, like purity in water, is the absence of the unnecessary.

the flower

The lotus flower opens at dawn and closes at dusk. It does not stay open to prove a point. Your interfaces should exhibit the same temporal wisdom: expose what is needed, when it is needed, and then fold gracefully closed. An API that never closes is a door that never locks -- not generosity, but negligence.

The flower is also where the lotus reproduces. Inside each bloom sits a seed pod -- the next generation of the pattern. Recursive structures understand this instinctively: the function that calls itself carries within its body the template for its continuation. Every recursion is a flowering.

// the fourth teaching:
// recursion is the pattern remembering itself

function bloom(depth = 0) {
  if (depth >= season.length) {
    return seed();  // the cycle completes
  }
  return petal(
    bloom(depth + 1)  // each petal contains a bloom
  );
}

A recursive function is a flower that dreams of flowers.