# Simple partial application

**URL:** <https://internals.rust-lang.org/t/simple-partial-application/7685>\
**Category:** language design\
**Created:** [June 3, 2018, 6:47am UTC](https://internals.rust-lang.org/t/simple-partial-application/7685 "2018-06-03T06:47:13Z")\
**Posts on this page:** 13\
**Page:** 3

<div class="post-metadata">

**Author:** ![Centril](https://sea2.discourse-cdn.com/flex002/user_avatar/internals.rust-lang.org/centril/32/3334_2.png) [@Centril](https://internals.rust-lang.org/u/Centril)\
**Post date:** [June 7, 2018, 8:25am UTC](https://internals.rust-lang.org/t/simple-partial-application/7685/41 "2018-06-07T08:25:15Z")

</div>

> [@mcy](#):
>
> The only practical application I can imagine is things like `foo([x; _])` , which I don’t find terribly compelling. Can you elaborate on what you envision this being useful for?

Generally speaking when one value constrains another with dependent types you can do some value inference . This is usually what implicit arguments are used for tho in Agda and Idris.

> [@mcy](#):
>
> but I don’t think it’s worth applying stop energy over a feature that I can’t imagine there being an RFC for any time soon

I take the long view; full dependent typing is a very large feature that I don't expect will be accepted anytime soon, but I would like to see it in the next 10 years or so. If and when that happens, we shouldn't have painted ourselves into a corner design-wise. Besides, there have been RFCs and designs to add full dependent types to Rust. However these were not accepted.

> [@mcy](#):
>
> ( `const` generics are not dependent types iirc).

Const generics as framed in the accepted RFC constitute Pi-types for a limited subset of values: those that can be computed at compile time. That is, a const generic function can be seen as: `Π (a: A) -> B(a)` with the side condition that `can_ctfe_eval(a)`.

* * *

On the `partial!` macro -- while it is nice that you can do that as a macro, and I'd like to thank @Emerentius for the effort, it concerns me that it becomes longer for the common case:

```rust
partial!(some_fn, arg0, _,)
|a, b| some_fn(arg0, a)
some_fn(arg0, _)
some_fn(arg0)

```

Using the lambda seems better to me if I have no other choice and I don't have to use a dependency for it (or convince someone else to pull it in); Also, annotating `_` is noise to me in and of itself; partial application can usually be inferred from the HoF function that consumes the lambda (because `iter.map(..)` requires `Fn(A) -> B`).

---

<div class="post-metadata">

**Author:** ![mcy](https://sea2.discourse-cdn.com/flex002/user_avatar/internals.rust-lang.org/mcy/32/6512_2.png) [@mcy](https://internals.rust-lang.org/u/mcy)\
**Post date:** [June 7, 2018, 3:29pm UTC](https://internals.rust-lang.org/t/simple-partial-application/7685/42 "2018-06-07T15:29:20Z")

</div>

> [@Centril](#):
>
> Generally speaking when one value constrains another with dependent types you can do some value inference . This is usually what implicit arguments are used for tho in Agda and Idris.
> 
> [...]
> 
> I take the long view; full dependent typing is a very large feature that I don’t expect will be accepted anytime soon, but I would like to see it in the next 10 years or so. If and when that happens, we shouldn’t have painted ourselves into a corner design-wise. Besides, there have been RFCs and designs to add full dependent types to Rust. However these were not accepted.

Can you give examples? I have very little experience with such languages, and I'd like to see how such a construction solves real-world problems Rust can't solve effectively today, which judicious use of `const` generics can't win us. I especially think we disagree on the point that reserving syntax for a feature that we may not see for 10 years (which is a long, long time in the lifespan of a language, especially one as young as Rust) is a wise reason to present stop energy. (For the record, I don't think dependent types are a bad idea, but I don't think they are crucial to solving the problems Rust wants to solve. I really don't want Rust to turn into a kitchen sink language like C++)

Also, I'll point out that my proposed syntax, `|| _`, allows use of value inference in expression contexts that are not inside of a closure, which I can imagine being \< 95% of all expressions, not including `|| {..}` closures (from which we should forbid from any such syntax anyways).

---

<div class="post-metadata">

**Author:** ![CAD97](https://sea2.discourse-cdn.com/flex002/user_avatar/internals.rust-lang.org/cad97/32/3460_2.png) [@CAD97](https://internals.rust-lang.org/u/CAD97)\
**Post date:** [June 7, 2018, 5:39pm UTC](https://internals.rust-lang.org/t/simple-partial-application/7685/43 "2018-06-07T17:39:13Z")

</div>

I think there is a problem in using `|| _ + 5`.

Currently, we have the property that a closure always directly acknowledges how many arguments it’s receiving. This is done by the number of identifiers between the bars: `|one, two, three|` and so on.

Of course, you can ignore a parameter by giving it to the black hole: `|_|`, and there’s a proposal to allow using `|..|` to ignore any number of parameters, as can be done for tuples when destructuring.

However, if you allow `|| _ + 5`, then you have a `||` closure that takes an argument. This seems undesirable.

* * *

Side note: I made this topic mostly to spark discussion; I’m not sure if this is actually desirable, or if it can be specified in a strong enough fashion for Rust.

---

<div class="post-metadata">

**Author:** ![repax](https://sea2.discourse-cdn.com/flex002/user_avatar/internals.rust-lang.org/repax/32/1342_2.png) [@repax](https://internals.rust-lang.org/u/repax)\
**Post date:** [June 7, 2018, 6:57pm UTC](https://internals.rust-lang.org/t/simple-partial-application/7685/44 "2018-06-07T18:57:18Z")

</div>

Here’s another, not entirely serious idea:

```rust
$1 * $1 + $2

```

This is a closure taking two arguments and returning the square of the first arg plus the second arg.

---

<div class="post-metadata">

**Author:** ![mcy](https://sea2.discourse-cdn.com/flex002/user_avatar/internals.rust-lang.org/mcy/32/6512_2.png) [@mcy](https://internals.rust-lang.org/u/mcy)\
**Post date:** [June 7, 2018, 7:01pm UTC](https://internals.rust-lang.org/t/simple-partial-application/7685/45 "2018-06-07T19:01:33Z")

</div>

I wanted to collect some of the proposed syntaxes and their pros and cons, in no particular order. Throughout, we want to write the following with our shorthand syntax.

```rust
fn foo(a: i32, b: i32, c: i32) -> i32 { a + b + c }
let f = |c| foo(0, 1, c);

```

* * *

## Haskell-style currying

```rust
let f = foo(0, 1);

```

There was brief discussion about introducing curried functions as part of the type system, but that’s outside the scope of this discussion (imo).

Pros:

- No new syntax.
- Limited to partial applications instead of complex expressions.
- Intuitive and natural for users of functional languages.

Cons:

- A partial application can’t be visually distinguished from the full function call.
- `std` and other crates do not have their function parameters ordered to take advantage of this, like in Haskell.
- No good way to call inherent/trait methods, except for UFCS.

* * *

## Scala-style Wunderbar

```rust
let f = foo(0, 1, _);
// or even
let f = 0 + 1 + _;

```

Though originally proposed for partial function application, it can be extended to arbitrary closures, using semantics like Scala’s.

Pros:

- Uses the pre-existing `_` keyword.
- Consistent with other uses of `_` (in the sense of “I don’t want to name this variable because its name doesn’t matter”).

Cons:

- It’s unclear where the lambda starts in this expression: `foo().bar(_)`. Is `foo()` inside the closure, or is its value captured as part of it?
- How do I specify that the output closure should be `move`? `move foo(_)` doesn’t work, because now `&move foo(_)` is ambiguous.
- What does `foo(_, _)` mean? `|y| |x| foo(x, y)` or `|x, y| foo(x, y)`?
- Inconsistent with other uses of `_` (where it either stands for “ignore this value” (patterns) or “infer this type/region” (types)). Note: given that it already has two inconsistent uses, I argue that this is not a strong argument against `_`.

* * *

## Scala Wunderbar but with closure bars

```rust
let f = || foo(0, 1, _);
let f = |_| foo(0, 1, _);
let f = |..| foo(0, 1, _);
let f = |?| foo(0, 1, _);

```

Included are some ideas for what should go in the closure bars. (Disclaimer, this is my proposed syntax.)

Pros:

- Solves all but the last con of the regular wunderbar.
- Closure bars are still present when a closure is constructed.
- `|..|` is already proposed as “ignore all parameters passed to this closure”. I think extending it to instead mean "don’t bind any of the parameters by name, but make them accessible through `_`" is not an awful idea (but I’d like feedback on this).

Cons:

- `||` would no longer indicate a nilary closure.
- `|_|` is a strawman, since the `_` pattern doesn’t actually introduce bindings and would just confuse people.
- For single-argument closures, `|..|` is actually a character heavier (I think arguments about character counts are dumb but I’m including this for completeness).

* * *

## Scala Wunderbar but with a different sigil, with or without closure bars.

```rust
let f = foo(0, 1, $);
let f = || foo(0, 1, ?);
let f = |..| foo(0, 1, #);

```

Pros:

- No mucking about with the meaning of `_`.

Cons:

- New punctuation!
- `let f = #[0];`, for slice access, is ambiguous with attributes (I think?)
- Doesn’t solve any of the other cons of `_` (if we don’t use the bars).
- `$` could be confused with macro captures, and `?` is already mentally linked with error handling.

* * *

## `partial!()`

```rust
let f = partial!(foo, 0, 1, _);
let f = foo.partial!(0, 1, _);

```

Pros:

- Pure macro implementation without compiler support.
- Limited to partial application.

Cons:

- WAY more typing, and makes “closure noise” worse.
- No good way to call inherent/trait methods, except for UFCS.

* * *

Also, I noted somewhere else in the thread that banning `_` in `|| {..}` might be a good idea, since this syntax is meant for _short_ closures. This idea leads me to want to call this feature “trivial closures” (or some post-bikeshed equivalent), for use where you’d see Python’s single-statement `lambda`.

---

<div class="post-metadata">

**Author:** ![gbutler](https://sea2.discourse-cdn.com/flex002/user_avatar/internals.rust-lang.org/gbutler/32/3670_2.png) [@gbutler](https://internals.rust-lang.org/u/gbutler)\
**Post date:** [June 7, 2018, 7:05pm UTC](https://internals.rust-lang.org/t/simple-partial-application/7685/46 "2018-06-07T19:05:56Z")

</div>

You said:

> [@mcy](#):
>
> ```rust
> fn foo(a: i32, b: i32, c: i32) -> i32 { a + b + c }; 
> let f = |c| foo(0, 1);
> 
> ```

Don't you mean:

```rust
fn foo(a: i32, b: i32, c: i32) -> i32 { a + b + c }; 
let f = |c| foo(0, 1, c);

```

EDIT: Evidence of the crime preserved. 😉 😄

---

<div class="post-metadata">

**Author:** ![mcy](https://sea2.discourse-cdn.com/flex002/user_avatar/internals.rust-lang.org/mcy/32/6512_2.png) [@mcy](https://internals.rust-lang.org/u/mcy)\
**Post date:** [June 7, 2018, 7:12pm UTC](https://internals.rust-lang.org/t/simple-partial-application/7685/47 "2018-06-07T19:12:18Z")

</div>

You saw nothing! =P

---

<div class="post-metadata">

**Author:** ![gbutler](https://sea2.discourse-cdn.com/flex002/user_avatar/internals.rust-lang.org/gbutler/32/3670_2.png) [@gbutler](https://internals.rust-lang.org/u/gbutler)\
**Post date:** [June 7, 2018, 7:13pm UTC](https://internals.rust-lang.org/t/simple-partial-application/7685/48 "2018-06-07T19:13:53Z")

</div>

Those weren’t the droids I was looking for?

---

<div class="post-metadata">

**Author:** ![scottmcm](https://sea2.discourse-cdn.com/flex002/user_avatar/internals.rust-lang.org/scottmcm/32/2355_2.png) [@scottmcm](https://internals.rust-lang.org/u/scottmcm)\
**Post date:** [June 7, 2018, 7:30pm UTC](https://internals.rust-lang.org/t/simple-partial-application/7685/49 "2018-06-07T19:30:35Z")

</div>

> [@repax](#):
>
> Here’s another, not entirely serious idea:
> 
> ```rust
> $1 * $1 + $2
> 
> ```

That's essentially the Boost.Lambda `_1 * _1 + _2` approach, [mentioned earlier](https://internals.rust-lang.org/t/simple-partial-application/7685/22).

---

<div class="post-metadata">

**Author:** ![bbatha](https://sea2.discourse-cdn.com/flex002/user_avatar/internals.rust-lang.org/bbatha/32/2662_2.png) [@bbatha](https://internals.rust-lang.org/u/bbatha)\
**Post date:** [June 7, 2018, 8:31pm UTC](https://internals.rust-lang.org/t/simple-partial-application/7685/50 "2018-06-07T20:31:44Z")

</div>

> Here’s another, not entirely serious idea:
> 
> $1 \* $1 + $2
> 
> This is a closure taking two arguments and returning the square of the first arg plus the second arg.

This is also syntax is swift: [The Swift Programming Language: Redirect](https://docs.swift.org/swift-book/LanguageGuide/Closures.html#ID100)

---

<div class="post-metadata">

**Author:** ![CAD97](https://sea2.discourse-cdn.com/flex002/user_avatar/internals.rust-lang.org/cad97/32/3460_2.png) [@CAD97](https://internals.rust-lang.org/u/CAD97)\
**Post date:** [June 8, 2018, 1:53am UTC](https://internals.rust-lang.org/t/simple-partial-application/7685/51 "2018-06-08T01:53:25Z")

</div>

To throw another prior art into the ring: Kotlin allows a closure that takes a single argument to be written as if it takes no arguments, then treats it as if it were declared as taken with the name `it`. So in Kotlin our basic example would be:

```rust
fun foo(a: Int, b: Int, c: Int) = a + b + c;
val f = { foo(0, 1, it) }

```

(I think, I’m not sure if this behavior only works for trailing closures, and didn’t try this)

---

<div class="post-metadata">

**Author:** ![mcy](https://sea2.discourse-cdn.com/flex002/user_avatar/internals.rust-lang.org/mcy/32/6512_2.png) [@mcy](https://internals.rust-lang.org/u/mcy)\
**Post date:** [June 8, 2018, 2:18am UTC](https://internals.rust-lang.org/t/simple-partial-application/7685/52 "2018-06-08T02:18:25Z")

</div>

A few thoughts:

- Kotlin, unlike Rust, is a big, big fan of contextual keywords; `it` is one of them. In order to make this work in Rust (without introducing incongruity like `{ foo(0, 1, it) }` v. `|x| foo(0, 1, x)`) I think we’d need to make `it` a full keyword (ha, ha). Is the Rust2018 keyword list final yet? =P
- As mentioned, this only works for single-argument closures, which probably isn’t enough cases to warrant the trouble (I could be wrong… someone should go grep [crates.io](http://crates.io)).

---

<div class="post-metadata">

**Author:** ![system](https://sea2.discourse-cdn.com/flex002/user_avatar/internals.rust-lang.org/system/32/14092_2.png) [@system](https://internals.rust-lang.org/u/system)\
**Post date:** [March 25, 2019, 8:30am UTC](https://internals.rust-lang.org/t/simple-partial-application/7685/53 "2019-03-25T08:30:20Z")

</div>

This topic was automatically closed 90 days after the last reply. New replies are no longer allowed.

[Previous page](https://internals.rust-lang.org/t/simple-partial-application/7685.md?page=2)
