Technology

Functional Reactive Programming AntiPatterns and Recipes


I’ve been working on a project that’ll be used throughout my client’s entire organization. That means the code needs to be extraordinarily understandable. Here’s a few observations (ok, one anti-pattern and one recipe)—more may come in the future:

An anti-pattern

FRP can be all about transforming streams (via map, reduce, etc).

Don’t write a long chain of complex transformations using anonymous functions.

Instead, prefer function names that make sense and comments. I tend to use self-documenting variables and function names.

Example

Bad (this is ES6 by the way):

 readdir(path)
    .map(filename => filename.replace(`${path}/`, ''))
    .map(filename => {
        const ext = filepath.replace(/^.*\.(.*)$/, '$1');
        switch (ext) {
         case 'html':
         case 'htm':
         case 'css' :
          return filepath + '!text';
        default:
          return filepath;
        }
     })

Better:

readdir(path)
     //Strip out path from filenames (add comments)
    .map(filename => filename.replace(`${path}/`, ''))
    .map(_addBundlerExtension) // (move complex transform to own function)

It’s now clearer from a glance that this snippet reads a directory, strips out the directory name from the list of files, then adds a “bundler extension”.

A short recipe

You frequently find yourself trying to combine and wait for the results of two or more streams. With some FRP libraries (like BaconJS), this is super easy. For example,

//This waits for two events in stream1 and stream2
Bacon.combineTemplate({stream1, stream2})
   .map(template => console.log(template.stream1, template.stream2);

With other libraries (highlandJS), you’ll have to use zip or all (bluebirdJS). This isn’t as convenient because you end up working with array indexes as opposed to object properties.

stream1.zip(stream2).map(template => console.log(template[0], template[1]);
Advertisements

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s