question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

Helper for creating a new function via partial application

See original GitHub issue

I ran into a minor issue with the error messages generated by sanctuary def when you export a function that has already been partially applied.

For example, if we have a library that exports an incr function via a partial application of add like so:

const add =
def('add', {}, [$.Number, $.Number, $.Number], (x, y) => x + y);

exports.incr = add(1);

And a separate library imports it and calls incr(1, 2), sanctuary-def will throw a TypeError complaining that add expected two arguments but got three. This can be confusing because 1) the add function was never called directly and 2) the incr function expects only one argument, but the error message complains about a function that expects two arguments.

We could rewrite our incr like so:

exports.incr = def('incr', {}, [$.Number, $.Number], add(1));

For this simple case it’s not so bad, but I was recently working on a library with 10-12 functions that were exported this way, each with different types of arguments. The boilerplate can become annoying and gets hard to maintain if you want refactor a function signature later (because now you have to change it in two places).

It would be awesome if sanctuary-def provided a helper function for defining a new function that is implemented as a partial application of another. It might look something like this:

// redef :: String -> Function -> Function
exports.incr = redef('incr', add(1));

redef takes a new name, a function which is returned by a partial application of some other function defined with def, and returns a new, curried function which accepts any arguments not already provided.

So now if you called incr(1, 2), the error message would explain that incr expects one argument but received two.

I’m not sure exactly what to call this helper function or if sanctuary-def has enough information to do the introspection that would be required here, but it would be extremely nice to have.

Issue Analytics

  • State:closed
  • Created 8 years ago
  • Comments:5 (4 by maintainers)

github_iconTop GitHub Comments

2reactions
davidchamberscommented, Mar 1, 2016

I agree that this would be marvellous! I’ll give the matter some thought.

0reactions
davidchamberscommented, Jan 8, 2020

I would now write the original code as follows:

//    add :: Number -> Number -> Number
const add = x => y => x + y;

exports.add =
def ('add')
    ({})
    ([$.Number, $.Number, $.Number])
    (add);

exports.incr =
def ('incr')
    ({})
    ([$.Number, $.Number])
    (add (1));

The implementation is shared yet type checking only occurs at the module boundary.

Read more comments on GitHub >

github_iconTop Results From Across the Web

How to use partial application to improve your JavaScript code
Partial application starts with a function. We take this function and create a new one with one or more of its arguments already...
Read more >
Partial Application and Currying - DigitalOcean
Partial application allows us to fix a function's arguments. This lets us derive new functions, with specific behavior, from other, more ...
Read more >
Functional JS #5: Partial Application, Currying - Medium
Currying and Partial Applications are two functional techniques we can use to improve code reuse and readability.
Read more >
Functional programming for your everyday javascript: Partial ...
The first step gets the function and collects a list of arguments into an array, then we return a function that collects another...
Read more >
Curry me This: Partial Application in JavaScript - LinkedIn
Partial application generally refers to the ability to (surprise) partially apply a function. Just give it less arguments than it requires, as a ......
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found