Giter VIP home page Giter VIP logo

es-papp's Introduction

ECMAScript Proposal: Function.prototype.papp

This proposal introduces papp and rPapp โ€“ concise ways of using partial application for functions that require no immediate this parameter. It is backwards-compatible, and is immediately useful with most any JavaScript function today.

Try it out!

npm install --save papp-polyfill

Then require it once (in your code, as early as possible):

require('papp-polyfill')

Introduction

Partial application is possible in JavaScript via Function.prototype.bind:

function add (x, y) { return x + y; }

var addTen = add.bind(null, 10);
addTen(20) //=> 30

However, bind is undesirable for three reasons:

  1. Sometimes you don't care about the value of this, yet you still must provide bind's first argument
  2. Sometimes you do care about the value of this, but don't want to commit to a specific value yet.
  3. Using bind is significantly slower than using a plain closure (!) (this has been fixed in V8, and wasn't an issue in other engines for quite a while)

Function.prototype.papp solves both these issues in a simple, elegant, and noise-free manner. Here is an illustrative example:

function add (x, y, z) { return x + y + z; }

var addTen = add.papp(3, 7);
addTen(5) //=> 15

// AS OPPOSED TO:
// var addTen = add.bind(null, 3, 7)
// OR:
// var addTen = (x) => add(3, 7, x)

var addThenIncrement = add.papp(1);
addThenIncrement(10, 6) //=> 17

// AS OPPOSED TO:
// var addThenIncrement = add.bind(null, 1)
// OR:
// var addThenIncrement = (a, b) => add(1, a, b)

Accepting papp into the ES standard will allow JS runtimes to implement a more performant version of bind that is dedicated to partial application.

Ignoring this

For functions that don't use the keyword this, papp helps with brevity:

function add (x, y) { return x + y; }

var addTen = add.papp(10);
addTen(20) //=> 30

Deferring Function Binding

If a function does use the keyword this, papp allows you to partially apply arguments without committing to a this value:

function greet (target) {
  return `${this.name} greets ${target}`;
}

var greetNewcomer = greet.papp('the newcomer');
greetNewcomer.call({ name: 'Alice' }) //=> 'Alice greets the newcomer'

Practical Examples

These examples are pulled from real-world use cases of partial application.

HTTP API Output Whitelisting

Player.whitelist = {
  basic: pluck.papp(['name', 'score']),
  admin: pluck.papp(['name', 'score', 'email']),
};

function pluck (attrs, obj) {
  var result = {};
  attrs.forEach( name => result[name] = obj[name] );
  return result;
}

// Example use (in practice, alice would come from a database):
var alice = { name: 'Alice', score: 100, email: '[email protected]', password_hash: '...' };

Player.whitelist.basic(alice) //=> { name: 'Alice', score: 100 }

Player.whitelist.admin(alice) //=> { name: 'Alice', score: 100, email: '[email protected]' }

Constructing User-friendly APIs

function createClient (host) {
  return {
    get:  makeRequest.papp(host, 'GET'),
    post: makeRequest.papp(host, 'POST'),
    put:  makeRequest.papp(host, 'PUT'),
    del:  makeRequest.papp(host, 'DELETE'),
  };
}

var client = createClient('https://api.example.com');
client.get('/users');
client.post('/comments', { content: "papp is great!" });

function makeRequest (host, method, url, data, options) {
  // ... Make request, return a promise ...
}

// AS OPPOSED TO:
// function createClient (host) {
//   return {
//     get:  (url, data, options) => makeRequest(host, 'GET', url, data, options),
//     post: (url, data, options) => makeRequest(host, 'POST', url, data, options),
//     put:  (url, data, options) => makeRequest(host, 'PUT', url, data, options),
//     del:  (url, data, options) => makeRequest(host, 'DELETE', url, data, options),
//   }
// }

Other Examples

These examples illustrate concepts you can use in your own applications.

Mapping with Arrays

var chapters = ["The Beginning", "Climax", "Resolution"];

var numberedChapters = chapters.map( toListItem.papp('My Book') )
//=> ["My Book / 1. The Beginning", "My Book / 2. Climax", "My Book / 3. Resolution"]

// AS OPPOSED TO:
// var numberedChapters = chapters.map( (chapter, i) => toListItem('My Book', chapter, i) )

function toListItem (prefix, item, i) {
  return `${prefix} / ${i + 1}. ${item}`
}

Polyfill

ES6:

Function.prototype.papp = function (...args) {
  var fn = this;
  return function (...moreArgs) {
    fn.apply(this, args.concat(moreArgs));
  };
};

ES5:

Function.prototype.papp = function () {
  var slice = Array.prototype.slice;
  var fn = this;
  var args = slice.call(arguments);
  return function () {
    return fn.apply(this, args.concat(slice.call(arguments)));
  };
};

es-papp's People

Contributors

gilbert avatar rreverser avatar steelbrain avatar

Watchers

 avatar  avatar

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.