<p>I added return type deduction to my (strongly and statically typed) language, but now I'm kind of concerned that it may not be a good thing. My language has no function declarations separate from the implementations, the compiler infers the declaration from the definition. This is convenient for small programs, but I'm concerned that with large functions in larger programs it may cause confusion for the reader of the code. For example</p>
<pre><code>fn foo(bar: Bar) {
    // Many lines of code 
    if bar.baz() {
        return bar.quux();
    }
    else {
        return bar.quuz();
    }
}
</code></pre>
<p>It is not easy to see at a glance what type this function returns.</p>
<p>Also while newer C++ standards allow return type deduction on inline functions, Rust and Swift explicitly forbid it for global functions.</p>
<p>So what are arguments for and against this feature?</p>

<type-inference>
What are pros and cons of return type deduction?
CC BY-SA 4.0
2023-12-14T15:35:42.150Z
Note that Rust allows returning _abstract_ types (`impl Trait`): semantically the return type capabilities are known, but the concrete type isn't, while in terms of code generation the concrete type will be known (hence its size). Are you solely interested on semantic aspects, or are you also considering code-generation aspects?
Matthieu M.
CC BY-SA 4.0
2023-12-14T20:23:45.353Z
@MatthieuM. The code generation I have figured out, I'm asking about the design aspect or the impact that return type deduction has on the usability of a language. But apparently the question is not on topic.
chrysante
CC BY-SA 4.0
2023-12-15T08:18:03.933Z
Oh... it seemed on-topic to me but I'm not super familiar with the rules here.
Matthieu M.
<p>One contra argument I can think of right away is that it prevents the programmer from consciously defining interfaces separately from the implementation. In the program</p>
<pre><code>fn foo(n: int, m: int) {
    return bar(m, n);
}

fn bar(int, int) -&gt; double { ... }
</code></pre>
<p>does <code>foo</code> return a <code>double</code> because <code>bar</code> returns double or because <code>foo</code> logically should return a <code>double</code> regardless of its implementation? If <code>bar</code>'s return type is changed to something else, we'll get a compiler error on the call sites of <code>foo</code>, not in the body of <code>foo</code> which seems undesirable and harder to debug.</p>

CC BY-SA 4.0
2023-12-14T12:08:27.933Z
2023-12-14T12:08:27.933Z
chrysante
# What are pros and cons of return type deduction?
Posted by: username_0 on 2023-12-14
I added return type deduction to my (strongly and statically typed) language, but now I'm kind of concerned that it may not be a good thing. My language has no function declarations separate from the implementations, the compiler infers the declaration from the definition. This is convenient for small programs, but I'm concerned that with large functions in larger programs it may cause confusion for the reader of the code. For example
fn foo(bar: Bar) {
    // Many lines of code 
    if bar.baz() {
        return bar.quux();
    }
    else {
        return bar.quuz();
    }
}

It is not easy to see at a glance what type this function returns.
Also while newer C++ standards allow return type deduction on inline functions, Rust and Swift explicitly forbid it for global functions.
So what are arguments for and against this feature?
**Tags:** type-inference
> **Comments:**
> **username_1**: Note that Rust allows returning _abstract_ types (`impl Trait`): semantically the return type capabilities are known, but the concrete type isn't, while in terms of code generation the concrete type will be known (hence its size). Are you solely interested on semantic aspects, or are you also considering code-generation aspects?  
> **username_0**: @MatthieuM. The code generation I have figured out, I'm asking about the design aspect or the impact that return type deduction has on the usability of a language. But apparently the question is not on topic.  
> **username_1**: Oh... it seemed on-topic to me but I'm not super familiar with the rules here.  
---
## 1 answers
### Answer by username_0 on 2023-12-14. Score: 4
One contra argument I can think of right away is that it prevents the programmer from consciously defining interfaces separately from the implementation. In the program
fn foo(n: int, m: int) {
    return bar(m, n);
}

fn bar(int, int) -> double { ... }

does foo return a double because bar returns double or because foo logically should return a double regardless of its implementation? If bar's return type is changed to something else, we'll get a compiler error on the call sites of foo, not in the body of foo which seems undesirable and harder to debug.
---
