Pure functions in EcmaScript

Oliver Hunt oliver at apple.com
Wed Nov 28 10:49:40 PST 2012

Just adding an implementers point of view:
Adding a new keyword/annotation is risky and/or complicates language semantics -- we don't want to break existing code, so new keywords are hard, likewise context dependent keywords can be tricksy: "f = function pure(){}" means what?

Assuming that there is an annotation that says a function is pure, runtime enforcement becomes either very expensive very quickly (possibly tending towards the halting problem in the general case), or can randomly throw exceptions.  Your sum function is a trivial case:
   function sum(a,b) { return a + b } // I'm pure!!!!

 We want to ensure sum has no side effects so we either typecheck on entry to ensure we will not need make a function call for the a and b typeconversions, or we throw on the first attempt to make a typeconversion (the exception will occur before any side effects, so you're still "safe" just annoyed).

But what about:
function bizzaroSum(a, b) {
while (a.b) a = a .b;
return a + b;

An ahead of time type check has unbounded time complexity, so there is no reason to not just execute and throw on a side effecting operation.

(Also what if a.b is a getter that simply returns 1 - does that count as a side effect because of the implied call, or does it not? after all there's not actually any side effect here)

So the only efficient way of dealing with a "pure" function is to run the code and perform type checks as you go to ensure that no calls are happening.

This gets us to _almost_ the level of performance modern JS engines are already getting, without having any concept of "pure".  If your code is doing sensible things, and the types are consistent every supposed gain you get from "purity" is already there.

But your purity constraints means no side-effects, no general case calls, neither of these limits is helpful to modern JS engines as they will happily inline functions anyway regardless of purity, and will just do a stack rewrite and fallback to general code if their assumptions turn out to be false.

As an aside, the performance issues JSC at least has with map, reduce, etc is VM re-entry.  For us that's a much more significant performance problem than code gen quality.


On Nov 28, 2012, at 9:45 AM, David Bruant <bruant.d at gmail.com> wrote:

> Le 28/11/2012 18:19, Claus Reinke a écrit :
>>>> With many new functional programming possibilities (like map, reduce, filter, lambdas) there are many scenarios where the implementer should use pure (or as I renamed it in another reply, side-effect-free) functions.
>>> Why "should"? What is the problem if people don't?
>> In the non-sequential versions, side-effect-free operators
>> give more flexibility in scheduling, eg, splitting an array
>> into sub-arrays, running partial loops on separate processors,
>> then combine the results.
> I agree, but it's far from being applicable in JS apparently (I see you agree later in your response). I suggested this as my very first Bugzilla bug. I encourage to read the comments: https://bugzilla.mozilla.org/show_bug.cgi?id=593706
> David
> _______________________________________________
> es-discuss mailing list
> es-discuss at mozilla.org
> https://mail.mozilla.org/listinfo/es-discuss

-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mail.mozilla.org/pipermail/es-discuss/attachments/20121128/49a3866c/attachment.html>

More information about the es-discuss mailing list