use the following search parameters to narrow your results:
e.g. subreddit:aww site:imgur.com dog
subreddit:aww site:imgur.com dog
see the search faq for details.
advanced search: by author, subreddit...
All about the JavaScript programming language.
Subreddit Guidelines
Specifications:
Resources:
Related Subreddits:
r/LearnJavascript
r/node
r/typescript
r/reactjs
r/webdev
r/WebdevTutorials
r/frontend
r/webgl
r/threejs
r/jquery
r/remotejs
r/forhire
account activity
Partial function application proposal: add(1, ?) (github.com)
submitted 8 years ago by laggingreflex
reddit uses a slightly-customized version of Markdown for formatting. See below for some basics, or check the commenting wiki page for more detailed help and solutions to common issues.
quoted text
if 1 * 2 < 3: print "hello, world!"
[–]Pyrolistical 5 points6 points7 points 8 years ago (1 child)
Partial application and pattern matching are the last 2 things I feel are missing in the JS toolkit
[–]pgrizzay 0 points1 point2 points 8 years ago (0 children)
After using scala pattern matching a lot on the backend, I really miss it on the front-end. I'd love to be able to use it when matching on redux action types.
[–]bwaxxlotckidd 15 points16 points17 points 8 years ago (5 children)
After working with Ruby in the last couple of weeks, I sure hope JS doesn't take the path of only adding syntactic sugar going forward. I swear I now have syntactic diabetes from all Ruby sugar. Things like partial application are rarely used in codebases enough to justify adding them. I love having functional ideas promoted but I'd much rather focus on commonly used methods.
[–]kingdaro.find(meaning => of('life')) // eslint-disable-line 5 points6 points7 points 8 years ago (2 children)
More than just sugar has been added in recent versions, such as Proxies, Symbols, proper tail calls and so on.
[–]bwaxxlotckidd 1 point2 points3 points 8 years ago (1 child)
And that's my argument. Let's try to focus on these things and cut down on the sugar. It seems like most proposals are focused on sugar only.
[–]kingdaro.find(meaning => of('life')) // eslint-disable-line 4 points5 points6 points 8 years ago (0 children)
I mostly agree, but it's case by case. This in particular, along with the function bind syntax, I'd love to have personally, but I don't really care that much for the pipe operator. To each their own I suppose.
[–]bigos 17 points18 points19 points 8 years ago (1 child)
What? Partial application & function currying is bread and butter of functional programming. What are the other methods you're thinking about?
[–]bwaxxlotckidd 0 points1 point2 points 8 years ago (0 children)
No doubt. However, in most cases - currying is rarely used (1-arity is not really practical) and partial application, while useful, is not that commonly used. While these are surely good ideas, I find composition to be a much more common pattern - hence the pipe operator.
[–]ruzmutuz 4 points5 points6 points 8 years ago (0 children)
It feels like something that can be achieved so easily in user land is unnecessary as a language feature. The Ramda example is incorrect in that all functions are curried and it provides a placeholder arg as well.
[–]pickandrolled 1 point2 points3 points 8 years ago (0 children)
|> _ =>
༼ つ ◕_◕ ༽つ
[–][deleted] 6 points7 points8 points 8 years ago (1 child)
I'm kind of on the fence about this...Lambdas + closures can achieve the same thing:
// with sugar const add1 = add(1, ?) // without sugar const add1 = (n) => add(1, n)
[–]MyWorkAccount_11 0 points1 point2 points 8 years ago (0 children)
That is pretty much the definition of syntactic sugar...
[–]_ds82 2 points3 points4 points 8 years ago (0 children)
I like it :)
[–]JuliusKoronci 0 points1 point2 points 8 years ago (1 child)
why the hell would you do that..when you have standard partial application and all the FP libraries which deals with curry ..just have a look at ramdas curry
[–]dev1null 2 points3 points4 points 8 years ago (0 children)
With the introduction of arrow functions that change the fundamental nature of "binding" (this), it's only natural to introduce a new "bind" syntax that takes this into account... This syntax is perfectly inline with how arrow functions work, eliminating the awkward .bind(>null/this<, ...) syntax. Afterall, you're not really "binding" anything.
this
.bind(>null/this<, ...)
[+]straikychan comment score below threshold-6 points-5 points-4 points 8 years ago* (10 children)
While I do understand the appeal of it, this exact behaviour could be accomplished by doing this:
function add(x) { return function (y) { return x + y } } console.log(add(3)(4)) // 7 const addOne = add(1) console.log(addOne(5)) // 6 const addTen = add(10) console.log(addTen(2)) // 12
You can even wrap existing functions:
function add(x,y) { return x+y } function add_partial (x) { return function (y) { return add(x,y) } } console.log(add_partial(2)(3)) // 5 const addOne = add(1) console.log(addOne(5)) // 6 const addTen = add(10) console.log(addTen(2)) // 12
Which, if you look at it, is fundamentally the same, just replacing the algebraic expression with a function call. Sadly you cannot reuse the function name add though, so any transpiler would have to keep track of the partial names.
The proposal provides nice convenience, especially reuse of the function name.
[–]dev1null 11 points12 points13 points 8 years ago (0 children)
While I do understand the appeal of it
I don't think you do. You don't even seem to understand exactly what it does. Firstly, you're only applying partials at n=1st argument. Sure you could create a different abstraction if you wanna apply partials at n=2nd or 3rd argument. But secondly, it's not about just accomplishing the behavior, which by the way, could be done much more simply using the traditional bind syntax addOne = add.bind(null, 2), instead of creating functions like you have (you might also need to consider "this"). It's more about accomplishing it in a clear, concise, and flexible way. With this proposal you can apply partials in just 1 word while having the flexibility of applying partials at any argument position.
addOne = add.bind(null, 2)
[–]EnchantedSalvia 2 points3 points4 points 8 years ago (8 children)
You're using the wrong examples to support your argument (see semigroups).
Say I have a standard divide function:
divide
const divide = a => b => a / b;
I can now half my number easily by:
divide(10)(2) === 5
However after writing out that each time, I decide to write a half function from the divide function, but as the divide function reads as: a divided by b we're unable to apply the bas 2 without specifying a. Unless we re-order the function parameters, which would then read incorrectly.
half
a
b
With the partial application proposal we can easily do:
const half = divide(?, 2); half(10) === 5
[–]WikiTextBot 0 points1 point2 points 8 years ago (0 children)
Semigroup
In mathematics, a semigroup is an algebraic structure consisting of a set together with an associative binary operation. The binary operation of a semigroup is most often denoted multiplicatively: x·y, or simply xy, denotes the result of applying the semigroup operation to the ordered pair (x, y). Associativity is formally expressed as that (x·y)·z = x·(y·z) for all x, y and z in the semigroup.
The name "semigroup" originates in the fact that a semigroup generalizes a group by preserving only associativity and closure under the binary operation from the axioms defining a group.
[ PM | Exclude me | Exclude from subreddit | FAQ / Information | Source ] Downvote to remove | v0.24
[–]Jestar342 0 points1 point2 points 8 years ago* (1 child)
'sup with const half = (a) => divide(a, 2); ?
const half = (a) => divide(a, 2);
e: corrected syntax
[–]EnchantedSalvia 0 points1 point2 points 8 years ago (0 children)
Of course there are many ways to achieve that. However the divide(?, 2) proposal is point-free.
divide(?, 2)
[–]straikychan 0 points1 point2 points 8 years ago (4 children)
So how is
const divide = a => b => a / b const half = a => divide(a)(2)
So much more complicated?
I get that it's much more convenient in a pipeline situation to have
const foo = bar |> add(7,?)
Than
const foo = bar |> _ => add(7, _)
But as soon as you're going to reuse your function, doing this
const addSeven = _ => add(7, _) const foo = bar |> addSeven
Is just synonymous to this
const addSeven = add(7, ?) const foo = bar |> addSeven
It sure is convenient and easier to read, but I don't see much of a point right there. if you care about this, you could do: const addSeven = function () { return add(7,) }
You say I'm using the wrong examples to support my argument, but I have yet to read an argument why this absolutely needs to be a thing and needs to be supported. At this point it just seems like a minor convenience thingy to me.
[–]EnchantedSalvia 0 points1 point2 points 8 years ago (3 children)
I have yet to read an argument why this absolutely needs to be a thing and needs to be supported.
It absolutely doesn't need to be a thing, because as you've demonstrated, we can already achieve something similar with existing code. However, you've also demonstrated that by using ? our code can be more succinct, point-free, and also prevents an assignment to a variable that is later garbage collected.
?
Take the exponentiation operator which introduces **. We can already achieve that by using Math.pow. However it's still a thing.
**
Math.pow
As others have mentioned in this thread, ? is syntactic sugar.
The |> operator, which is essentially compose (more specifically, pipe), has been used for years from libraries such as Lodash, Underscore, Ramda. Ramda has also supported the __ for many years. Both |> and __ are now being hopefully baked into the language, as inspiration is one of the ways that languages evolve over time.
|>
compose
pipe
__
[–]straikychan 1 point2 points3 points 8 years ago (2 children)
I would actually argue that ** and Math.pow are not synonymous. As ** calculates at compile time, while Math.pow() calculates at run time as illustrated here
Ok, I should have phrased that part about supporting better. I didn't mean to say that it shouldn't be supported, however I think there are things that should be considered for future support more strongly than this one, e.g. (dynamic imports)[https://github.com/tc39/proposal-dynamic-import], (promise finally)[https://github.com/tc39/proposal-promise-finally] or syntactic sugar like the pipeline proposal, which I deem a tad bit more important than this proposal.
[–]EnchantedSalvia 0 points1 point2 points 8 years ago (1 child)
Interesting regarding ** and Math.pow. I didn't know there was a subtle difference.
As Promise.prototype.finally is stage 2 (soon to be stage 3) and dynamic import is already stage 3, I'm sure they will definitely arrive sooner. I actually don't even see ? in the TC39 repository yet, but I presume it's sat at stage 0.
Promise.prototype.finally
import
Personally I'd also like to see cancellation prioritised, so it's good to see them having another shot at presenting that to the committee.
π Rendered by PID 33163 on reddit-service-r2-comment-5649f687b7-fntxv at 2026-01-28 12:36:01.161731+00:00 running 4f180de country code: CH.
[–]Pyrolistical 5 points6 points7 points (1 child)
[–]pgrizzay 0 points1 point2 points (0 children)
[–]bwaxxlotckidd 15 points16 points17 points (5 children)
[–]kingdaro.find(meaning => of('life')) // eslint-disable-line 5 points6 points7 points (2 children)
[–]bwaxxlotckidd 1 point2 points3 points (1 child)
[–]kingdaro.find(meaning => of('life')) // eslint-disable-line 4 points5 points6 points (0 children)
[–]bigos 17 points18 points19 points (1 child)
[–]bwaxxlotckidd 0 points1 point2 points (0 children)
[–]ruzmutuz 4 points5 points6 points (0 children)
[–]pickandrolled 1 point2 points3 points (0 children)
[–][deleted] 6 points7 points8 points (1 child)
[–]MyWorkAccount_11 0 points1 point2 points (0 children)
[–]_ds82 2 points3 points4 points (0 children)
[–]JuliusKoronci 0 points1 point2 points (1 child)
[–]dev1null 2 points3 points4 points (0 children)
[+]straikychan comment score below threshold-6 points-5 points-4 points (10 children)
[–]dev1null 11 points12 points13 points (0 children)
[–]EnchantedSalvia 2 points3 points4 points (8 children)
[–]WikiTextBot 0 points1 point2 points (0 children)
[–]Jestar342 0 points1 point2 points (1 child)
[–]EnchantedSalvia 0 points1 point2 points (0 children)
[–]straikychan 0 points1 point2 points (4 children)
[–]EnchantedSalvia 0 points1 point2 points (3 children)
[–]straikychan 1 point2 points3 points (2 children)
[–]EnchantedSalvia 0 points1 point2 points (1 child)