dart-lang / language

Design of the Dart language
Other
2.65k stars 202 forks source link

Language suggestion: partial application for functions #351

Open xareelee opened 5 years ago

xareelee commented 5 years ago

It's just a suggestion for Dart lang, not a bug report. I did not find a way to publish my suggestion, so I file this here.

Partial application would be useful for functional programming.

With question mark ? when calling a function, it turns a function into 'currying' similar to a proposal in tc39. For example,

foo(x, y, z) {
  return (x - y) / z;
}

// currying with placeholders
var a = foo(8, 2, ?);  
// same as 
// var a = (z) => foo(8, 2, z);  
a(2);  //~> foo(8, 2, ?)(2) ~> foo(8, 2, 2) ~> 3 
a(3);  //~> foo(8, 2, ?)(3) ~> foo(8, 2, 3) ~> 2
a(6);  //~> foo(8, 2, ?)(6) ~> foo(8, 2, 6) ~> 1

// useful for functional programming
[2, 3, 6].map(foo(8, 2, ?));  //~> [3, 2, 1]
[3, 2, 1].map(foo(?, 5, -1));  //~> [2, 3, 4]
[2, 3, 4].map(foo(9, ?, 1));  //~> [7, 6, 5]

// calling with multiple placeholders
foo(?, ?, 3)(9, 6);  //~> foo(9, 6, 3) ~> 1
foo(?, ?, 3)(?, 6)(9);  //~> 1

This feature would be useful to make functions ease-of-use in functional programming with Future/Promise and Stream/Rx, because the design of the function parameter ordering is irrelative.

request(query)  // return a Future<ResponseData>
  .then(processData(?, options))   // pass data to processData(data, options)
  .then(writeDataIntoDatabase(database, ?));  // pass data to writeDataIntoDatabase(database, data)
tedhenry100 commented 5 years ago

Yes partial application would be a significant improvement!

Named parameters need to be handled as well. I need to be able to fix some named parameters and obtain a new function of the remaining parameters. To accomplish this now, I must write a lot of boilerplate defining functions that capture parameter values and return other functions of fewer parameters. It is a lot of boilerplate!!

(I'm interested in partial application. I'm not interested in currying. See Currying vs Partial Application)

kasperpeulen commented 5 years ago

What about:

request(query)  // return a Future<ResponseData>
  .then(=> processData(it, options))   // pass data to processData(data, options)
  .then(=> writeDataIntoDatabase(database, it));  // pass data to writeDataIntoDatabase(database, data)
munificent commented 5 years ago

? probably isn't a good choice since it is used for so many other things, especially once NNBD lands: conditional operator, nullable type, null-aware method calls, null-aware operator, etc.

See also: #8.

mateusfccp commented 3 years ago

Would this be more feasible if we have a perfect correspondence between tuples and argument lists? (#1293)

munificent commented 3 years ago

I do like partial application and, yes, tuples might help somewhat, but I don't think even tuples as arguments list will give us partial application for free. It would still be a separate feature we'd have to think through.