Giter Club home page Giter Club logo

Comments (4)

ameensol avatar ameensol commented on August 19, 2024 7

@magopian I didn't read the above comment (tl;dr) but just wanted to point out that your example of a closure returning a pure function wasn't correct.

Your example:

function (x) {
  return function (y) {
    return function (z) {
      return z
    }
  }
} 

According to @raganwald the definition of a closure is "a function containing one or more free variables". Since none of the functions above contain any free variables, they are all in fact pure functions, despite being nested.

That said, I think you're right that "contain" should be "return" in the context of the original challenge. A closure can contain a pure function pretty simply.

Consider this closure:

(x) => {
  let foo = (a) => a
  return foo(y * x)
}

I realize this is banal, but the closure above does "contain" the pure function foo.

I can also think of a somewhat contrived example of a closure returning a pure function:

(x) => 
  (y) => {
    return z ? (a) => a : (a) => y * a
  }
}

In this case, the first function (x) => ... is pure but the second (y, z) => ... is a closure which depends on the free variable z and may return the pure function (a) => a if z is truthy but will otherwise return the closure (a) => y * a if z is falsy.

from javascript-allonge.

hectorip avatar hectorip commented on August 19, 2024 1

So, the conclusion is that it is possible that a closure both contains and returns a pure function?

from javascript-allonge.

kid-icarus avatar kid-icarus commented on August 19, 2024

👍

from javascript-allonge.

mehranhatami avatar mehranhatami commented on August 19, 2024

@magopian When you say:

even though it's pure, still is in a closure, and still needs its
parent's environment (so, its closure).

you are making assumptions, based on what you think is a necessary part of these closure statements, a return statement which RETURNS a function. Whereas there is no need to return any of those functions, although it makes more sense in the real world and also in the world of functional programming, but in the world of theoretical JavaScript concepts, you don't need to return the function to have a closure.

To Make it more clear I thought why not make an actual working example, which does the exact same thing without using the return statement.

Before getting into the main part of my example let's say we have a storage to store our functions, say for the sake of creating less pointers to them, although this pattern could have a lot of implications but here we just need it just to help us not create inline variables for our functions:

var FN = (function () {
  var storage = [];

  FN.has = function (id) {
    return (typeof id === 'number' && id > -1 && id < storage.length);
  };

  function FN(fn) {
    if (typeof fn === 'number') {
      return storage[fn];
    } else if (typeof fn === 'function') {
      return (fn.__storeId__ = storage.push(fn) - 1);
    } else {
      console.warn('Invalid input parameter!');
    }
  }

  FN.call = function (id) {
    var fn = storage[id],
      args;
    if (typeof fn === 'function') {
      args = Array.isArray(arguments[1]) ?
        arguments[1] :
        Array.prototype.slice.call(arguments, 1);

      result = fn.apply(undefined, args);

      return {
        result: result,
        call: function () {
          if (typeof result === 'number' && FN.has(result)) {
            return FN.call(result, Array.prototype.slice.call(arguments));
          }
          return null;
        },
        valueOf: function () {
          return result;
        }
      };
    } else {
      console.warn('Invalid input parameter!');
    }
  };

  return FN;
}());

I know the code block above may sound complicated, but let's use it as a black box and assume this allows us just to use closures without returning functions. the first code block I want to mention here is the code example in the book:

var fn = function (x) {
  return function (y) {
    return function (z) {
      return x + y + z;
    }
  }
};

console.log(fn(10)(11)(6) == 27);

As we all know none of these functions is pure except for fn itself.

Using FN api we can transform it to:

var fn = function A(x) {
  var fny,
    fnyId;

  fny = function (y) {
    var fnz = function (z) {
      function () {

      }
      return x + y + z
    };

    //here we store the 'fnz' function in storage
    var fnzId = FN(fnz);

    //here we only return a number not a function
    return fnzId;
  };

  //here we store the 'fny' function in storage
  fnyId = FN(fny);

  //here we only return a number not a function
  return fnyId;
};

//here 'fnId' is only a number not a function
var fnId = FN(fn);

This may seem much more code but I transformed it like this just to put comments, but the better syntax transformation could be:

var fnId = FN(function A(x) {
  return FN(function (y) {
    return FN(function (z) {
      return x + y + z
    });
  });
});

Which is more like the first closure code block we have mentioned above, but with a big difference:

None of these function RETURNS functions.

and the way we could have this nested function call:

console.log(fn(10)(11)(6) == 27);

is like:

console.log(FN.call(fnId, 10).call(11).call(6) == 27);

As you see we get almost the same result using only numbers, without passing functions around.
the idea here is now if you do:

var fnId = FN(function (x) {
  return FN(function (y) {
    return FN(function (z) {
      return z;
    });
  });
});

console.log(FN.call(fnId, 10).call(11).call(6) == 6);

the most inner function which as it is mentioned on the book is:

the I Combinator or Identity Function

is a pure function and if you save its storeId somewhere like:

var mostInnerfnId;

var fnId = FN(function (x) {
  return FN(function (y) {
    return (mostInnerfnId = FN(function (z) {
      return z;
    }));
  });
});

And then if you call right to its upper function:

FN.call(fnId, 10).call(11);

Now you can have access to this function like:

var fn = FN(mostInnerfnId);

which can be called as a pure standalone function:

fn(26);//output: 26

All the code above here is just to clarify one single point. The way closure environment object gets managed doesn't have anything to do with returning functions, it is all about containing or having nested function definitions and pure functions are always pure no matter if you return them or not. Basically when you say:

In this case, the function (z) { return z }, even though it's pure,
still is in a closure, and still needs its parent's environment (so,
its closure).

as it is called in my last code block, it doesn't need its parent's environment object. It only needs to get defined, then you could call it anywhere.

Hope this could be helpful.

from javascript-allonge.

Related Issues (20)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.