Skip to content

Latest commit

 

History

History
248 lines (192 loc) · 5.7 KB

File metadata and controls

248 lines (192 loc) · 5.7 KB


License: Apache 2.0 Twitter

Straal JavaScript / Functional Programming Style Guide

This style guide is also available as an article called "Lexical functional programming - jargon and naming convention" on Straal.com, medium.com and dev.to.

Table of contents:

Constants and keys

Boolean values describing a state of something:

const hasFoo: Boolean
const shouldFoo: Boolean

const barDisabled: Boolean
const barEnabled: Boolean

const isDisabled: Boolean

Functions with a specific role

const fooChecker: Function
const fooValidator: Function
const fooExtractor: Function
const fooHandler: Function

const fooCallback: Function
const fooFallback: Function

Operator functions

const fooReducer = (result: Any, current: Any) => Any
const fooReduced = reduce(
   collection: Any,
   fooReducer,
   result,
)
const fooMapper = () => Any
const fooMapped = map(
   collection: Any,
   fooMapper,
)

For filter(), some(), find() and similar operations:

const fooChecker = () => Any
const fooFiltered = filter(
   collection: Any,
   fooChecker,
)

Pipelines

Functional way:

const fooFlow = pipe(
   bar: Function,
   baz: Function,
   qux: Function,
)

With RxJS:

const foo$ = bar$.pipe(
   filter(barComparator: () => Boolean),
   pluck('bar'),
)

Setters and getters

Setters:

const fooSetter = curry((obj: Object, value: Any) => {...fooObject, ...{value}})
const barSetter = (obj: Object, value: Any) => {...barObject, ...{value}}

const setFooToObj = fooSetter(fooObject: Object)
const setBarToObj = partial(barSetter: Function, barObject: Object)

Getters:

const fooGetter = curry((fooObject: Object, value: Any) => fooFormatter(get(fooObject, 'value', {})))
const barGetter = (barObject: Object, value: Any) => barFormatter(get(barObject, 'value', {}))

const getFooFromObj = fooGetter(fooObject: Object)
const getBarFromObj = partial(barGetter: Function, barObject: Object)

Avoid if/else

Conditional (ternary) operators:

return foo(value)
  ? bar(value)
    ? qux()
    : quux()
  : baz()

A better choice for more complicated cases:

import L from 'lodash'

const bar = (value) => value ? qux() : quux()
const sthCond = L.cond([
  [foo, bar],
  [L.stubTrue, baz]
])

return sthCond(value)

Dictionaries

const getValue (type) {
    const fooMap = {
        bar: 'bar value',
        baz: 'baz value',
        qux: 'qux value',
    }

    return fooMap[type]
}

Switches

Dictionaries with getters:

const fooGetter = curry((fooObject: Object, value: Any) => fooFormatter(get(fooObject, value, {})))
const barGetter = (barObject: Object, value: Any) => barFormatter(get(barObject, value, {}))

const makeAction = (action: Any) => {
    const bazSwitch = {
        foo: fooGetter(fooObject: Object),
        bar: partial(barGetter: Function, barObject: Object),
    }
    const actionGetter = get(bazSwitch, action, constant(null))
    return actionGetter()
}

Factories

Functions returning instances with functions:

const someFactory = function({store, fetcher}, watcher){
   const fetch = fetcher(store)
   const watch = watcher(store)
   return {
      fetch,
      watch
   }
}
const store: Object
const fooWatcher: Function
const barWatcher: Function
const someFetcher: Function
const someMiddleware = curry(someFactory)({store, fetcher: someFetcher})
const foo = someMiddleware(fooWatcher)
const bar = someMiddleware(barWatcher)
const { watch: fooWatch, fetch: fooFetch} = foo
const fooPipe = pipe(fooWatch, fooFetch)
const { watch: barWatch, fetch: barFetch} = bar
const barPipe = pipe(barWatch, barFetch)

Reactive streams

Cold observables:

const fooObserver = => Any
const fooSubscription = subscribe(
    foo$: Observable$,
    fooObserver,
)
fooSubscription.unsubscribe()

Hot observables:

export const fooDispatcher$ = fromEvent(window, 'foo')

Stream creators

export const fooStreamCreator = (): Observable<TBar | never> => {
  return condition
    ? throwError(new Error('Foo error'))
    : bar$
}

Resources

Support

Any suggestions or reports of technical issues are welcome! Contact us via email.

License

This library is released under Apache License 2.0. See LICENSE for more info.