Skip to content

Instantly share code, notes, and snippets.

@brekk
Last active December 27, 2017 16:35
Show Gist options
  • Save brekk/c4e2867c7902a06f8d0f94ae917d48d7 to your computer and use it in GitHub Desktop.
Save brekk/c4e2867c7902a06f8d0f94ae917d48d7 to your computer and use it in GitHub Desktop.
10 rules for a better FP-in-JS
  1. Prefer functions to other forms of expression.
    1. Unary functions (with a single parameter) are best.
      const unary = (x) => x
    2. If not a unary function, use curry when adding parameters.
      const binary = curry((a, b) => a + b)
    3. Prefer functional composition to inline complexity.
      const prop = curry((property, o) => o[property])
      const length = (x) => (
         pipe(
           (
             typeof x === `object` ?
             Object.keys : 
             I // I is the identity function: (i) => i
           )
           prop('length')
         )(x) 
      )
      const add = curry((b, a) => a + b)
      const lastIndex = pipe(
        length,
        add(-1)
      )
      // instead of:
      const lastIndexInline = (x) => (
        typeof === `object` ?
          Object.keys(x).length - 1 :
          x.length - 1
      )
    4. Prefer pipe to compose (top-down) when composing functions.
      const piped = pipe(
        f,
        g,
        h
      )(x)
      // instead of
      const composed = compose(
        h,
        g,
        f
      )(x)
    5. The order of parameters is important. Ideally the last parameter is the one being passed directly to the pipe.
      const ternaryPipe = curry(
        (a, b, c) => pipe(
          binaryCurriedFn(a),
          binaryCurriedFn(b),
          unaryFn
        )(c)
      )
  2. Keep all definitions as D.R.Y. (don't repeat yourself) as possible. (FP is DRY AF!)
    1. A single copy of existing code is the beginning of copypasta (a codesmell).
    2. Favor named function morphs over partially-applied parameters inline when possible.
    const join = curry((delim, arr) => arr.join(delim))
    const joinNewlines = join(`\n`)
    // re-use joinNewlines elsewhere, instead of writing join(`\n`) again
  3. Use Eithers to encapsulate logical disjunction. (Recommend fantasy-eithers)
  4. Use Futures to encapsulate asynchronous operations. (Recommend fluture)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment