Discussion:
[std-proposals] Keyword Forcing Trailing Return
a***@gmail.com
6 years ago
Permalink
Not sure what tone to write this in, but this is a problem that I think
needs to be addressed, and would like some feedback regarding the issue and
this proposed solution.
I also did not see this anywhere else, but if it is redundant, please let
me know.

*Currently the auto keyword is required to use a trailing return (except
with lambda functions).*
*However, auto can also be used without a trailing return to auto-deduce
the return type.*
*This can lead to errors if a trailing return is unintentionally forgotten,
which could then cause difficult to locate unintended behavior.*
*I'd like to discuss a keyword that required that the function return type
should be specified though a trailing return.*

The keyword would take on a subset of the auto keyword's behavior. Similar
to the auto keyword, it would look for the trailing return.
However, it would not auto deduce the return type if there is no trailing
return.
If no trailing return is given, then no return type would have been
specified, and a compiler error would be thrown (No return type specified).
In the case of the trailing return being "auto", it should be equivalent to
using the auto without a trailing return (to allow for consistent code
style).

The keyword would add additional specificity to the language, by allowing
programmers to better express intention.
examples:
auto get42(){ return 42; } //
returns 42 as an int (possibly unintended return type)

<keyword> get42(){ return 42; } // compiler error, no
return type specified

<keyword> get42()->double { return 42; } // returns 42 as a
double (intended)

<keyword> get42()->auto { return 42; } // returns 42 as an int
(auto return type behavior intended)


This is useful in preventing the following:

auto get42()->double { return 42; } // Intended: returns 42
as a double

auto get42() { return 42; } // Unintended:
returns 42 as an int

In this case, the error is that the programmer intended to write a function
with a trailing return, but forgot the trailing return.
Everything could work fine, or unintended behavior could occur in the
program somewhere due to the different type.
The source of the unintended behavior could also be difficult to locate,
especially if the auto keyword is overused.
A similar issue can also be introduced in the case of a bad refactor, if
the return type of an auto function is unintentionally changed.

The keyword would prevent issues like this by catching such a scenario at
compile time using additional specificity.
Thus the case of a programmer unintentionally forgetting to specify a
trailing return type, can be caught at compile time, and remove a source of
difficult to locate errors.
It also increases code readability, by better expressing programmer intent.

Hopefully I've shown that such a keyword is useful, and there is just the
question of naming.
The two keywords I've thought of are "trailing" and the ever controversal
"func".
My preference is towards "func", since I think it makes code more readable.

example: func get42()->double() { return 42; }

Unfortunately I am not sure if it would cause any name conflict issues
given the given the prevalence of the abbreviation.
It could also possibly conflict with possible future uses of func.
--
You received this message because you are subscribed to the Google Groups "ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send an email to std-proposals+***@isocpp.org.
To post to this group, send email to std-***@isocpp.org.
To view this discussion on the web visit https://groups.google.com/a/isocpp.org/d/msgid/std-proposals/41781a83-d5ed-46d3-a936-da2416158846%40isocpp.org.
Ville Voutilainen
6 years ago
Permalink
...
All of which I can write with a traditional return type, completely
avoiding the problem. Show me a compelling
use case where the return type must be trailing, and we'll talk.
--
You received this message because you are subscribed to the Google Groups "ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send an email to std-proposals+***@isocpp.org.
To post to this group, send email to std-***@isocpp.org.
To view this discussion on the web visit https://groups.google.com/a/isocpp.org/d/msgid/std-proposals/CAFk2RUbD6GqOC6XtAhDR3DVG4npXEPA4ghT_FDDHqkSCr7PO2w%40mail.gmail.com.
Alexander Graber-Tilton
6 years ago
Permalink
My understanding is that there is are already compelling use cases for
trailing returns, which is why it is part of the standard.
This is more aimed at resolving the ambiguous uses of the auto keyword,
which can be used for multiple purposes when defining a function and as
such be a contributing factor to programmer errors.
In this case the keyword is to create a more specified way to declare
programmer intention between the following use cases.
1. Declare a function with a trailing return: auto mul(T a, T b) ->
decltype(a*b){ return a*b; }
2. Automatically deduced the return type for a function: auto getChild(T
a){ return a.child(); }
Currently there is no way to express the intent of #1 without the intent of
#2
We have #2: auto-deduce return type.
We have #1 else #2: use trailing return type, else auto-deduce.
We don't have #1: use the trailing return type.

On Mon, Oct 1, 2018 at 2:51 PM Ville Voutilainen <
...
--
You received this message because you are subscribed to the Google Groups "ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send an email to std-proposals+***@isocpp.org.
To post to this group, send email to std-***@isocpp.org.
To view this discussion on the web visit https://groups.google.com/a/isocpp.org/d/msgid/std-proposals/CAFNER8RFT%3DUG1hnY1oiBp%3DO--EpNZZFZZLkPooG3T7nX6Ga3yg%40mail.gmail.com.
Gašper Ažman
6 years ago
Permalink
This sounds a lot like a self-correcting declaration to me, which is...
weird? There are no other intent-checking provisions in declarations, so
why would we need one for the trailing return type?

The only motivation for *something* like this, to me, would be, if I could
*omit* the return type, but the deduction of it would still take place in a
SFINAE context, so I didn't have to *repeat* it.

My point is that the feature space is larger than just checking, and there
are competing interests in this space, where keywords are already very
scarce.

G

On Mon, Oct 1, 2018 at 6:42 PM Alexander Graber-Tilton <
...
--
You received this message because you are subscribed to the Google Groups "ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send an email to std-proposals+***@isocpp.org.
To post to this group, send email to std-***@isocpp.org.
To view this discussion on the web visit https://groups.google.com/a/isocpp.org/d/msgid/std-proposals/CAANG%3DkX-d0pWd1OUrQ63X_BAb9XrVHqVAF3vORN-imRrOYqKOA%40mail.gmail.com.
a***@gmail.com
6 years ago
Permalink
This is somewhat aimed at a more general use case, in favor of tying to
have a consistent style.
There are now essentially two ways to write functions, both valid, and both
use-able in multiple scenarios.
The trailing return can be used in all scenarios, as it can be used for:
templates, non-templates, and lambda functions.
The traditional return style can only be used for a subset of those: some
templates, and non-templates

This means the most consistent way to write a function is using a trailing
return, yet it has a number of issues including the else auto-deduce return
type.
With the traditional style, a missing return type causes a compile error: "ISO
C++ forbids declaration of with no type"
There is no way to get a compilation error for a missing return type with
trailing return, since the "else auto-deduce" automatically kicks in.
The auto deduction leaves a space for programmer error in a way that is
difficult to locate, despite the fact that this is something that should be
catch-able at compile time and easily found.
So given that everything can be done using trailing returns, it makes a lot
of sense to have a way of enforcing that the return type is specified.

So the question then becomes how to specify a function that requires a
trailing return.
auto can't be used, since the auto-deduction is the issue.
I would have proposed something like being able to specify a trailing
return function without the auto keyword, but that seems odd to me, as it
doesn't match the typical way of defining things

get42()->double{return 42;} // this doesn't seem like it should be valid,
as it still has no type, but would be the alternative.

I don't see a way to deal with this other than a keyword.

In the end, I don't think that auto-deduction should be the default return
type for a function, and that is currently the case for any trailing return.
The programmer should have the option to use auto-deduction, but it
shouldn't be the default.
...
--
You received this message because you are subscribed to the Google Groups "ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send an email to std-proposals+***@isocpp.org.
To post to this group, send email to std-***@isocpp.org.
To view this discussion on the web visit https://groups.google.com/a/isocpp.org/d/msgid/std-proposals/28fd5d17-7ef4-41df-a1fd-c619a8e5d00d%40isocpp.org.
a***@gmail.com
6 years ago
Permalink
Thinking about this further, it could also be done using static analysis,
but would then end up forcing warnings with the traditional style auto
return type functions.
The ambiguity comes from weather auto is indicating an auto-deduced return
type, or if it is indicating a trailing return.
The only way to check programmer error where they possibly forgot the
trailing return would be to warn on something like: "auto doSomething(){}"

It does make sense to have the func keyword though for this purpose, as it
would add a lot of readability to the trailing return style.
It is easier to read type and teach
{
int i = 0;
func test()->bool{return false;}
}
in comparison to:
{
int i = 0;
bool test(){return false;}
}

Maybe this would be better to simply revisit if there is ever a proposal
for a func keyword for some other reason.
...
--
You received this message because you are subscribed to the Google Groups "ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send an email to std-proposals+***@isocpp.org.
To post to this group, send email to std-***@isocpp.org.
To view this discussion on the web visit https://groups.google.com/a/isocpp.org/d/msgid/std-proposals/b2593726-3857-4bc4-8459-4afa527a39fa%40isocpp.org.
Ray Hamel
6 years ago
Permalink
What about just extending C-syntax returns so they behave the same way as
trailing returns? It would be a potentially breaking change if a parameter
shadows another identifier at class, namespace or global scope, but I don't
think that would break much actual code, and it might even fix some subtly
incorrect code.

-Ray
...
--
You received this message because you are subscribed to the Google Groups "ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send an email to std-proposals+***@isocpp.org.
To post to this group, send email to std-***@isocpp.org.
To view this discussion on the web visit https://groups.google.com/a/isocpp.org/d/msgid/std-proposals/48e91aee-be7b-4154-8e98-9763849f8976%40isocpp.org.