Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Does this make Javascript less teachable? #82

Closed
zenparsing opened this issue Jan 17, 2018 · 13 comments
Closed

Does this make Javascript less teachable? #82

zenparsing opened this issue Jan 17, 2018 · 13 comments

Comments

@zenparsing
Copy link
Member

zenparsing commented Jan 17, 2018

Because of the multiple argument issue (where the user has to create an arrow function to pass additional arguments), this proposal is going to encourage developers to rewrite "normal" functions as single-argument arrow functions that return other arrow functions.

function f(a, b, c) {
  // Doesn't really work with the pipeline operator too well
}

const f = a => b => c => {
  // This works better with the pipeline operator
};

Is encouraging this pattern a good idea in the context of Javascript? I've had to explain the above transformation to developers when teaching them certain libraries (e.g. Redux) and it's not always easy. It's generally a FTW moment for developers that don't have experience with a functional programming language. One of the design goals that we used to have for Javascript was that it should be approachable. Is encouraging a strange-looking alternate function syntax promoting the goal of approachability?

The pipeline proposal and the bind proposal seek to solve some of the same syntax problems. I'm wondering whether encouraging these "arrow-list" functions is really a better path than simply using this as a 0th argument (which is already well-supported in the standard library).

@littledan
Copy link
Member

My hope was that this style would not be encouraged, in favor of either

  • Using arrow functions inside the pipeline
  • Using the partial application proposal
  • Some arguments will already be for a single function

If that's not enough, and people will really be encouraged to use this "curried function" pattern, that would be unfortunate. Some people are already advocating currying in JavaScript, but I would not want to encourage it further because of the mental model reasons you explain (as well as optimizability, and not working well with JS's optional argument passing model)

@mAAdhaTTah
Copy link
Collaborator

My plan / expectation is @littledan's first bullet will be the most common, e.g.:

a |> a => f(a, 2, 3)

Despite generally liking currying, I'm finding it increasingly difficult to work with and debug properly in JavaScript. If we get pipelining, I'm planning on dropping the practice completely.

@zenparsing
Copy link
Member Author

zenparsing commented Jan 17, 2018

My feeling is that requiring arrow functions for multiple arguments will be perceived as an ergonomic problem. If the user is simply trying to feed a value through a series of function calls, then the arrow functions themselves, syntactically speaking and from the point of view of the user, are just noise.

If that's the case, then users will try to solve the ergonomic problem by either using the currying-arrows pattern or by using even more syntax. If they use the currying-arrows pattern, then we have the teachability concern. But if they use an additional layer of syntax, then it begs the question of whether or not this proposal has actually solved the original syntax problem that it is intended to solve (feeding a value through a series of function calls left-to-right).

@aikeru
Copy link

aikeru commented Jan 17, 2018

My hope was that this style would not be encouraged, in favor of either

I've been following functional pipelining proposals for awhile now (bind operator and pipeline operator) and this is a huge surprise to me. The curried function pattern seemed like a natural fit / the only ergonomic option for the pipeline operator itself. (an aside: This was one reason I was hoping the :: operator would proceed, because it felt like a more natural fit for JS and makes it effortless to specify multiple arguments.)

@gilbert
Copy link
Collaborator

gilbert commented Jan 17, 2018

To be fair, every new feature makes JavaScript less teachable :)

I agree with @littledan. The partial application proposal or pipeline placeholders will make working with multi-arg function quite ergonomic. People who like currying can curry without issue, but others can use one of the aforementioned options, which will be faster since they should be optimizable. IMO this makes both ways equally viable.

@zenparsing
Copy link
Member Author

zenparsing commented Jan 17, 2018

@gilbert Understood. But we need to keep in mind the fact that basing a proposal's viability on another proposal multiplies risks. Not only obvious risks like adoption, but also complexity risks: when the success of one proposal depends on another, it's much harder to predict how a feature will end up affecting the evolution-path of the language.

@gilbert
Copy link
Collaborator

gilbert commented Jan 17, 2018

I don't disagree, and am personally for pipeline placeholders, which would be part of the pipeline proposal itself.

@aikeru
Copy link

aikeru commented Jan 17, 2018

@gilbert when you use a placeholder, does it not curry?

//Are these equivalent?
foo |> bar(?)
foo |> bar
//What about these?
foo |> bar(?, 5)
foo |> ((a, b) => bar(a, b))(?, 5)

If I see the placeholder, I think I am more likely to assume it will behave the same way as if I had not used any placeholder (and instead just used parens and passed arguments), and simply adding the placeholder changing it not to curry would be surprising behavior to me.

Edited for clarity and corrections.

@gilbert
Copy link
Collaborator

gilbert commented Jan 17, 2018

Currying is converting a function to receive one argument at a time instead of multiple. This original issue showcases an example of currying – going from function f(a,b,c) to const f = a => b => c.

foo |> bar(?) and foo |> bar are equivalent. The second example is not quite equivalent since the last line creates an intermediate function (the end result is the same, though).

littledan added a commit to tc39/agendas that referenced this issue Jan 19, 2018
- Pipeline operator: There are some significant, recently filed issues with the proposal that need to be resolved before Stage 2 including tc39/proposal-pipeline-operator#82 and tc39/proposal-pipeline-operator#83 (as well as the arrow function grammar). I plan to follow up on these offline.
- Extensible literals: Changes to the proposal to incorporate feedback from the last presentation are still needed, but it's too close to the meeting to let others review these changes.
@zenparsing
Copy link
Member Author

@gilbert After spending more time looking, I think that adding pipeline placeholders clears up the issues with multiple arguments nicely and is intuitive enough (even to those without much functional programming experience) to remove my concerns. I also think placeholders should be a part of this proposal.

@zenparsing
Copy link
Member Author

zenparsing commented Jan 20, 2018

I misstated the concern in the original post. To restate it briefly:

The proposal in its current form encourages lots of little functions that return single argument closures. I believe that that partial application style will be somewhat confusing for developers that don't have experience with functional programming paradigms.

My conclusion is that a limited form of partial application syntax would fix that problem.

Closing, thanks!

@littledan
Copy link
Member

Sounds like we need to figure out whether that is feasible and update the explainer and draft spec before we can close the issue.

@tabatkins
Copy link
Collaborator

Closing this issue, as the proposal has advanced to stage 2 with Hack-style syntax. The proposal is now optimally compatible with ordinary functions, defined in the standard way you'd write functions for any other use-case.

@github-actions github-actions bot locked as resolved and limited conversation to collaborators Oct 11, 2021
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

No branches or pull requests

6 participants