<p>Several OO languages allow you to grab unapplied method references.</p>
<p>Some, such as Kotlin or Python, have them accessible from the class itself and just append <code>self</code> onto the front of the argument list.</p>
<pre class="lang-kotlin prettyprint-override"><code>class IntWrapper(private val x: Int) {
  fun adding(other: IntWrapper) = IntWrapper(x + other.x)
}

val additionFunc: (IntWrapper, IntWrapper) -&gt; IntWrapper = IntWrapper::adding
</code></pre>
<p><sup>Excuse the terrible example, I can't think of any practical one off the top of my head.</sup></p>
<p>JavaScript handles this notoriously poorly, due to the weird rules around <code>this</code>:</p>
<pre class="lang-js prettyprint-override"><code>class NumberWrapper {
  constructor(x) { this.x = x; }
  adding(other) { return new NumberWrapper(this.x + other.x); }
}

const additionFunc = NumberWrapper.prototype.adding;
let fifteen = additionFunc.apply(new NumberWrapper(5), [new NumberWrapper(10)]);
// OR
const addFive = additionFunc.bind(new NumberWrapper(5));
fifteen = addFive(new NumberWrapper(10));
</code></pre>
<p>Swift handles this in a way I don't think I've seen before, modelling unapplied references as currying in a way that's not otherwise common in the language.</p>
<pre class="lang-swift prettyprint-override"><code>// Example method call, for comparison
let x = 1.0
_ = x.addingProduct(2.0, 3.0)

// Now, for the unapplied reference:
let fma: (Double) -&gt; (Double, Double) -&gt; Double = Double.addingProduct
// what the heck is that type signature?
</code></pre>
<p>Some languages, like C#, don't provide any mechanism for this, and you have to explicitly write out <code>x =&gt; x.Foo()</code>.</p>
<p>What are the advantages and disadvantages to each approach? What other approaches exist?</p>

<language-design><object-oriented>
How should unapplied method references be handled?
<p>C++ has <code>std::mem_fun()</code> to turn a pointer-to-member-function into a function object:</p>
<pre><code>class IntWrapper {
    int x;
public:
    IntWrapper(int x): x(x) {}
    IntWrapper adding(const IntWrapper&amp; other) {
        return {x + other.x};
    }
};

auto additionFunc = std::mem_fun(&amp;IntWrapper::adding);
auto three = additionFunc(IntWrapper(1), IntWrapper(2));
</code></pre>
<p>You can use the pointer-to-member-function itself instead of using <code>std::mem_fun()</code>, but the syntax is rather awful:</p>
<pre><code>auto additionFunc = &amp;IntWrapper::adding;
auto three = (IntWrapper(1).*additionFunc)(IntWrapper(2));
</code></pre>
<p>There is <code>std::bind()</code> as well to do currying. But all that results in objects that act like regular functions: you call them with some parameters, and a value comes out. What happens in your Swift example:</p>
<pre><code>let fma: (Double) -&gt; (Double, Double) -&gt; Double = Double.addingProduct
// what the heck is that type signature?
</code></pre>
<p>This is not a function that returns a value, but you are declaring a function that takes a <code>Double</code> and returns another function that has the signature <code>(Double, Double) -&gt; Double</code>. So the call <code>fma(1.0)</code> returns a function that takes two parameters and that evaluates <code>Double(1.0).addingProduct(/* those parameters */)</code>; <code>fma(1.0)(2.0, 3.0)</code> is then equivalent to <code>Double(1.0).addingProduct(2.0, 3.0)</code>.</p>
<p>In C++ you could write:</p>
<pre><code>auto fma(double z) {
    return [z](double x, double y) {
        return std::fma(x, y, z);
    }
}
</code></pre>
<p>And call it like <code>fma(1.0)(2.0, 3.0)</code> as well. Swift's syntax doesn't use lambda expressions, it's more like the pointer-to-member function from above, but with the benefit that you can call it the same way as a normal function, whereas C++ needs that special syntax.</p>
<p>I don't think Swift has any benefits for flexibility or performance, but it definitely is shorter to write.</p>
<p>Something I don't see though is a way to make this generic in Swift; you can't write:</p>
<pre><code>let fma&lt;T&gt;: (T) -&gt; (T, T) -&gt; T = T.addingProduct
</code></pre>
<p>Whereas in C++ you could write:</p>
<pre><code>auto fma = [](auto z) {
    return [z](auto x, auto y) {
        return std::fma(x, y, z);
    }
};
</code></pre>

CC BY-SA 4.0
2023-07-04T22:37:06.633Z
2023-07-04T22:37:06.633Z
G. Sliepen
# How should unapplied method references be handled?
Posted by: username_0 on 2023-06-01
Several OO languages allow you to grab unapplied method references.
Some, such as Kotlin or Python, have them accessible from the class itself and just append self onto the front of the argument list.
class IntWrapper(private val x: Int) {
  fun adding(other: IntWrapper) = IntWrapper(x + other.x)
}

val additionFunc: (IntWrapper, IntWrapper) -> IntWrapper = IntWrapper::adding

Excuse the terrible example, I can't think of any practical one off the top of my head.
JavaScript handles this notoriously poorly, due to the weird rules around this:
class NumberWrapper {
  constructor(x) { this.x = x; }
  adding(other) { return new NumberWrapper(this.x + other.x); }
}

const additionFunc = NumberWrapper.prototype.adding;
let fifteen = additionFunc.apply(new NumberWrapper(5), [new NumberWrapper(10)]);
// OR
const addFive = additionFunc.bind(new NumberWrapper(5));
fifteen = addFive(new NumberWrapper(10));

Swift handles this in a way I don't think I've seen before, modelling unapplied references as currying in a way that's not otherwise common in the language.
// Example method call, for comparison
let x = 1.0
_ = x.addingProduct(2.0, 3.0)

// Now, for the unapplied reference:
let fma: (Double) -> (Double, Double) -> Double = Double.addingProduct
// what the heck is that type signature?

Some languages, like C#, don't provide any mechanism for this, and you have to explicitly write out x => x.Foo().
What are the advantages and disadvantages to each approach? What other approaches exist?
**Tags:** language-design object-oriented
---
## 1 answers
### Answer by username_1 on 2023-07-04. Score: 2
C++ has std::mem_fun() to turn a pointer-to-member-function into a function object:
class IntWrapper {
    int x;
public:
    IntWrapper(int x): x(x) {}
    IntWrapper adding(const IntWrapper& other) {
        return {x + other.x};
    }
};

auto additionFunc = std::mem_fun(&IntWrapper::adding);
auto three = additionFunc(IntWrapper(1), IntWrapper(2));

You can use the pointer-to-member-function itself instead of using std::mem_fun(), but the syntax is rather awful:
auto additionFunc = &IntWrapper::adding;
auto three = (IntWrapper(1).*additionFunc)(IntWrapper(2));

There is std::bind() as well to do currying. But all that results in objects that act like regular functions: you call them with some parameters, and a value comes out. What happens in your Swift example:
let fma: (Double) -> (Double, Double) -> Double = Double.addingProduct
// what the heck is that type signature?

This is not a function that returns a value, but you are declaring a function that takes a Double and returns another function that has the signature (Double, Double) -> Double. So the call fma(1.0) returns a function that takes two parameters and that evaluates Double(1.0).addingProduct(/* those parameters */); fma(1.0)(2.0, 3.0) is then equivalent to Double(1.0).addingProduct(2.0, 3.0).
In C++ you could write:
auto fma(double z) {
    return [z](double x, double y) {
        return std::fma(x, y, z);
    }
}

And call it like fma(1.0)(2.0, 3.0) as well. Swift's syntax doesn't use lambda expressions, it's more like the pointer-to-member function from above, but with the benefit that you can call it the same way as a normal function, whereas C++ needs that special syntax.
I don't think Swift has any benefits for flexibility or performance, but it definitely is shorter to write.
Something I don't see though is a way to make this generic in Swift; you can't write:
let fma: (T) -> (T, T) -> T = T.addingProduct

Whereas in C++ you could write:
auto fma = [](auto z) {
    return [z](auto x, auto y) {
        return std::fma(x, y, z);
    }
};
---
