Some Thoughts On Functional JavaScript

Just for fun I decided to put together a quick sample of some functional JavaScript – as in, functional programming done with JavaScript. I’m not really very familiar with functional languages other than playing with Haskell a bit and doing some functional-style stuff in C# and Ruby. I wanted to see what a functional JavaScript code base might look like.

A Functional Calculator

To keep things simple, I created a calculator using nothing but functions. Each function takes other functions as parameters and returns a function. The only exception to this is the simple `value` function which takes a value and returns a function that itself will return the original value.

Here’s the basic code I wrote for my calculator, including the aforementioned `value` function:

// A raw value, represented as a function
var value = function(val){
  return function(){
    return val;
  }
}

// A function to add two functions together
var add = function(x, y){
  return function(){
   return x() + y();
  }
}

// A function to subtract one function from another
var subtract = function(x, y){
  return function(){
    return x() - y();
  }
}

// A function to multiply two functions
var multiply = function(x, y){
  return function(){
    return x() * y();
  }
}

I wrote all this through the use of some Jasmine tests, but as a quick example of how it can work, here’s a simple formula and result:

var one = value(1);
var two = value(2);
var three = value(3);
var four = value(4);

// (1 + 2) * 3 - 4 == 5
var resultFunc = subtract(multiply(add(one, two), three), four);

// but it's still a function right now, so evaluate it
var result = resultFunc();
consol.log(result); // => 5

My Thoughts And Reactions

These are the interesting points that stand out in my head. I’m not sure if these are “correct” or not… it’s just what pops out in my mind.

If anyone has any corrections and additional thoughts or notes, I’d love to hear them – just drop me a line in the comments, below.

Functions And Functions As State

I’ve represented everything as a function – even the simple values of 1 through 4. And every function returns a function, except for the simple values, which return a function that returns the actual value.

FunctionAllTheThings

In the process of returning functions from functions, I’m representing the state of the application as a series of functions.

This one is a bit odd for me to wrap my head around. I’m not sure if this is really correct, or if it’s just an oversimplification of what’s really happening here. There are no data-structures, though, only functions. So it stands to reason that the state is stored as a series of functions that can be evaluated to produce a result.

Update: The Wikipedia article on functional programming says that fp “avoids state”. So… am I wrong in thinking that I’ve represented the state with functions instead of data structures?

Funcional Command Pattern

The result isn’t actually evaluated until I invoke the`resultFunc` in the above example. But I have the `resultFunc`available as a variable and I can pass it around anywhere I want. This basically turns it into a command pattern implementation, only in a functional manner instead of an object manner.

Compose-able And DSL Functions

All of these functions are side effect free. None of them actually mutates any existing application state. Of course this is a really simple implementation, but that was one of my goals. I’ll need to play with some more complex ideas in order to really see how side effect free would play out.

One of the benefits of side effect free functions is that the code in the sample is far more declarative and compose-able than most code I write. Since each function does one very small and very simple thing, taking in other functions as parameters, it’s easy to build things.

var one = value(1);
var two = value(2);
var three = value(3);
var four = value(4);

// (1 + 2) * 3 - 4 == 5
var added = add(one, two)
var multiplied = multiply(added, three)
var resultFunc = subtract(multiplied, four);

// the result is the same. 
// it's been composed the same, functionally
// it was just put together with more variables in the mix
var result = resultFunc();
consol.log(result); // => 5

This is something that I’ve played with in other languages, and I like this aspect of functional programming. It’s a great way to build DSLs for example.

Compared To Object / Prototypal

Oscar Godson posted a version of my code alongside a prototypal version for a comparison.

/**
 Prototypal
 from Oscar Godson: http://jsbin.com/atopek/edit#javascript
*/

var Calc = function(){
  this.sum = 0; //could be a param
  return this;
}

Calc.prototype.add = function(x){
  this.sum = this.sum + x;
  return this;
}

Calc.prototype.multiply = function(x){
  this.sum = this.sum * x
  return this;
}
  
Calc.prototype.subtract = function(x){
  this.sum = this.sum - x;
  return this
}

Calc.prototype.result = function(){
  return this.sum;
}

console.log(new Calc().add(1).add(2).multiply(3).subtract(4).result())

I like seeing them side by side. It’s interesting the see all of the different ways that JavaScript can do the same thing. It also shows me just how ugly I think the functional version is. When you compare the actual formula in the comments to the functional JS code, the code is inside-out-backwards. The prototypal code with it’s method chaining is closer to the formula, though it’s still a bit off.

I think it’s easier to read and understand the chaining, though. It also reminds me of LINQ and monads – pipes and filters with a single result coming from the end of it.

More Fun Functional Stuff To Try

I haven’t done anything like memoizing or currying for these simple examples, but those are ideas I want to play with, too. I’ve written a currying function in JavaScript once or twice, and there’s plenty of examples in the good JS books. Memoizing is also available in Underscore.js but should be trivial to implement a naive version of it. I’m sure there are plenty of other things that would be fun to try, as well.

Code And Continuing Thoughts (Maybe)

If you’re interested in seeing this code, it’s on Github.

I’m thinking about taking this a little further over time, just for fun. I’ve posted these comments in the read me (actually – they started there…) and I’ll continue to update the read me as I progress (assuming I actually do continue exploring this and don’t just forget about it like so many other things).

This is really pretty simple stuff… but it’s fun to write asimple exercise like this and think about what’s going on, why and see how it affects the way I think and approach software development.


Post Footer automatically generated by Add Post Footer Plugin for wordpress.

About Derick Bailey

Derick Bailey is an entrepreneur, problem solver (and creator? :P ), software developer, screecaster, writer, blogger, speaker and technology leader in central Texas (north of Austin). He runs SignalLeaf.com - the amazingly awesome podcast audio hosting service that everyone should be using, and WatchMeCode.net where he throws down the JavaScript gauntlets to get you up to speed. He has been a professional software developer since the late 90's, and has been writing code since the late 80's. Find me on twitter: @derickbailey, @mutedsolutions, @backbonejsclass Find me on the web: SignalLeaf, WatchMeCode, Kendo UI blog, MarionetteJS, My Github profile, On Google+.
This entry was posted in DSL, Functional, Javascript. Bookmark the permalink. Follow any comments here with the RSS feed for this post.
  • Colin Yates

    Very nice – small enough to grasp the ideas and large enough to demonstrate the consequences.

    Please keep going – I am going through a similar process myself and you are doing the hard work for me :)

  • Anonymous

    If you want to stretch your mind a little more in this direction, check out Programming with Nothing:
    http://speakerdeck.com/u/tomstuart/p/programming-with-nothing

    Make sure you stick around until the conclusion. One of the best ways to put “language debates” into perspective.

    • http://mutedsolutions.com Derick Bailey

      heh – yeah, i’ve seen the blog post that went along with that before. it’s crazy stuff! definitely something i need to read more thoroughly :)

      • Edwin G. Castro

        That slide deck demonstrates a more complex piece of code implemented using the same techniques Derick is using for his calculator. 
        Turtles, I mean, Functions all way down!

        Perhaps an interesting experiment would be to implement the same algorithm in Javascript using the same functional technique used for the calculator. The result might even provide an interesting way to compare Javascript implementations.

        • http://mutedsolutions.com Derick Bailey

          I thought about that… then I remembered there is no -> shortcut syntax in javascript. The thought of writing that code with function(){…} everywhere made me scream in horror. :P

  • http://wizardsofsmart.net/ panesofglass

    Functional programming doesn’t avoid state any more than the web avoids state; it avoids mutable state where possible. So you can change your functional version to represent values as values. Your prototypal version would also be functional if you returned a new instance rather than ‘this’. After all, OOP and functional programming are not mutually exclusive. Finally, you can return a value in your first example. Nothing wrong with that. What you return is a lazy way of invoking a value in the future. Both eager and lazy evaluation are fine in fp.

    • http://mutedsolutions.com Derick Bailey

      “Your prototypal version would also be functional if you returned a new instance rather than ‘this’.” 

      I’m not sure I follow you on that one… returning a new object instance would make it immutable, but I don’t see how that would be functional, since it’s objects and not functions.

      “Both eager and lazy evaluation are fine in fp.”

      Right – I don’t think I was trying to say you can’t have plain values in fp… but it did sort of come across that way. I originally tried to write this code with plain values, but I couldn’t figure out how to make it work the way I thought it should. It was easier for me to wrap the values in a function and do the lazy-evaluation.

      • http://wizardsofsmart.net/ panesofglass

        “[The presence or absence of objects] matters not.” – Yoda

        Immutability is part of fp. Objects are irrelevant. Objects are just data structures. In javascript, this is even more the case, as you could treat the object as a hash. Thus, making the methods return a new instance is the same in essence as pulling off the methods and making functions that work against a similar object (with only values).

        In the end, methods on objects are just a way of packaging data structure functions along with the data structure, allowing you to hide the internal data structure, a la OOP. FP and OOP are orthogonal.

      • http://profiles.google.com/thedwalker Thedric Walker

        That begs the question of how did you think it should work?

  • lefthandedgoat

    In FP not everything is a function.  Functions are your primary means of abstractions instead of objects.  Functions and data are separate.  In OOP they are (usually depending on language) together.

  • http://twitter.com/dangerbell Gregory Bell

    The code that you say is “inside-out-backwards” is called Polish notation or prefix notation. By writing the operator before the operands you should be able to write equations unambiguously without using parentheses.

    7 * (3 + 4) = 49, but 7 * 3 + 4 = 25 due to the standard operator precedence rules. But with prefix notation there’s only one way to evaluate the equation.
    * + 3 4 7 = 49

    The equation is always evaluated inner most operator first.

    Older calculators used to use Reverse Polish Notation (RPN). So the example would be written as 7 3 4 + *. And the same rules apply.

    From what I remember of it Polish notation is just how things work out in the Lisp world.

    • Edwin G. Castro

      Polish Notation conceptually uses a stack of operations (functions) and values (data) to perform calculations.

      You push * which requires two pieces of data. You then push + which also requires two pieces of data. By pushing 3 and 4 you have provided enough data for + which evaluates to 7. Now you need just one more piece of data (7) to evaluate the original * with 7 and 7 with a result of 49.

      Both the Java and .NET virtual machines use a stack in this fashion. My memory is a little rusty but I think most languages that compile to an intermediate language of some kind execute on a stack-based virtual machine.

      Everything begins to look very similar when you get down to the dirty details.

      • http://mutedsolutions.com Derick Bailey

        interesting… this makes a bit of sense when you explain it via IL. I’ve looked at enough MSIL to see the pattern you’re talking about. 

        One thing that bothers me about the example I’ve shown here: I have this vague idea that functional languages don’t use call stacks. Rather, they just call through to the next function to be executed, like a stream of functions instead of a call stack of functions.

        I’m not sure where I got that from, but it would be interesting to know if this is the case, and what the impact of that is when looking at something like my example here.

  • Edwin G. Castro

    I would recommend the video lectures for the “Structure and Interpretation of Computer Programs” on the MIT OpenCourseWare site. The instructors use LISP but you could easily experiment with the ideas in Javascript using a similar style as you used for your calculator. For me the course truly got interesting when I started watching the “2B: Compound Data” video.

    Hmm… I don’t think I’ve finished watching all of these videos… I should probably do that!http://ocw.mit.edu/courses/electrical-engineering-and-computer-science/6-001-structure-and-interpretation-of-computer-programs-spring-2005/video-lectures/

    • http://mutedsolutions.com Derick Bailey

      I’ve been meaning to read that book… a video series would be even better! thanks :)