Functional Programming — The Examples Series — Mixing Arrays and Non-Arrays Via the Ternary Operator

Paul Galvin
3 min readApr 4, 2016

--

This is the 4th article in my “examples series” for functional programming. Read about the series here, including links to previous and future examples.

Today’s example uses the JavaScript ternary operator and does not rely upon underscore.js.

The Setup

Consider this JSON structure:

Delicious, yummy JSON

Logically, we’re setting up a structure here that says “I have a ‘bundle.’ The bundle has a single minified file and some associated unminified files. If I want, the unminified files, they are available via the “unmifiedSourcefiles” array. Note that both the “bundleSourceFile” and each of the “unminfiedSourceFile[s]” follow the same structure. This structure is mapped to a set of TypeScript interfaces thusly:

Note that the IBundle.bundleSourceFile and individual unminifiedSourceFile[s] are both ISourceFiles.

A client (in this case, a SharePoint web part) will declare that it needs one of these bundles via a call:

Gimme a bundle!

The RequestBundle knows all of the available bundles in the world. It looks up the requested bundle and adds it to its big list of every bundle that’s been requested by someone. If multiple people ask for the same bundle, it only adds to the big list once. (It’s not relevant to the this blog post, but this list is then processed at the end of a page load and all the bundles are emitted as JS <script> tags. Yes, this is yet another asynchronous JS script loader. The world just didn’t have enough of them. Until now, that is. Now it has enough.)

Here’s the original largely imperative logic that I wrote to do this:

Back when I was your age, I didn’t use any your “functional” techniques

This is simple and straightforward. It uses filter on all of the bundles that have already been requested to get an array of those already-requested bundles. Filter returns an array and if the array has anything, I know that it was already added. In this case, I can return an empty bundle which allows the caller to do what it needs to do. If the length *is* zero, then it hasn’t been added. So, find it and return it to the caller by filtering over the the “_allBundleDefinitions” and returning any matches. It happens that there should only be one match, but if there are actually multple matching bundles, then that’s not my problem :).

This can be refactored into a one line mini-monster:

Marge! We need some garlic!

Rather than having an if/then check explicitly lined out as in previous example, it’s all been merged using a ternary operator. The caller wants back an array of bundle definitions and the way I do it is using the ternary operator to return “this._emptyBundle” if the filter failed. Otherwise, I return the result from filtering over _allBundleDefinitions.

As I do this more and more, my eyes are quickly seeing what’s going on. But when I share this with some of my colleagues, they voice a strong preference for the first approach.

I think that straight-forward JavaScript syntax might be getting in the way and a more functionally oriented language would read more cleanly. I don’t know that for sure.

Hope this was edifying!

</end>

--

--

Paul Galvin

Author and Practice Director @ Neudesic/IBM. Father, Not-Great-But-Always-Trying Zen Buddhist. “Yet Another TypeScript Book” (https://amzn.to/2ABntAX).