-
Notifications
You must be signed in to change notification settings - Fork 18k
proposal: Go 2: permit defining function using named function type #30931
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Comments
See also #21498. |
Note, that this one is probably different since referenced proposal is based on deriving typing information from given context. Current proposal deals with implicitly defined named types. This should allow faster parsing and less changes overall in comparison. |
I will say that it would be quite nice to be able to use return http.HandlerFunc(rw, req) {
// Do something.
} instead of return http.HandlerFunc(func(rw http.ResponseWriter, req *http.Request) {
// Do something.
}) Some solution to the aforementioned related issue would probably fix this as well, but not in some cases, such as when returning. If the function returns an |
@DeedleFake In case of type aliasing you would probably write.
Also return types are included into named type definition, so there's zero guessing to do. |
Just want to make sure there aren't any semantic confusions here: There's no type aliasing there. The type alias syntax is |
You are right. It was a harsh misuse on my part. |
Actually, I like this as this is a arguably simpler approach to get the benefits of #21498, in a mostly backwards compatible way. I don't know, though if this would be practically possible though without too much impact on the speed of the compiler, since now there is no func keyword to tell the go parser that an inline function is following. |
@beoran Mostly guessing but:
Looking at go/less package there is a Lookup method that shows you to position your token defined in. So basically if you encounter any type usage you lookup the definition anyway and the definition has all typing info on your new function - what's left is to put parameter names into places they belong. You if you have more insight on how things really work in compile time - lets discuss this. |
@DeedleFake There was some truth to your original assessment: https://play.golang.org/p/jVstCUCnxG- |
So, it seems to me that this is the root issue that caused me to run into a different issue (#31444). Right now, function literals can be passed to a function taking a defined function type if they have the same underlying type, because of assignability. This doesn't happen for defined types based on the basic types (like int) because those are all defined types. I do see some difficulties from losing the
At the expense of making everything even harder to read, you could use explicit conversion:
but that seems awkward, even though it's exactly what we do for cases where we're passing in a typed value to something that wants a defined type. Obviously, when struggling with a language design choice, the right place to look is the C preprocessor's macro definition rules. We could just use roughly the cpp macro redefinition rule of "you're allowed to provide that definition again, but it has to be identical":
and state that this is permitted only if the signature actually matches. So, once a function type name exists, that name can be used as a synonym for
|
Given your last example with Copier you just need to go one step further and get in/out parameter type from definition but leave naming to the developer. This takes away most of the "repetitive" code
If you are concerned about not knowing those types consider that this is how easy it is now: |
I think my concern is mostly that if you don't include the names, we have no clue what the parameters are named -- do we inherit them from the type? What if the type didn't name them? And if we include just the names, with no types, we have to go look at the type definition for the function type to find out what the parameters are. I'd sort of prefer to just accept that I'm redeclaring the parameters, but that way I can read the code without having to bounce around. |
We include the name.
Type for parameter as for any other variable probably can be looked up in IDE. As example we don't redeclare field types while making a struct. We just know what they are. You have to know the types to write that function in full syntax as well. Same syntax will do for single-method interfaces. But that's harder since we'll have to distinguish single-method and multi-method interfaces. The 'type' keyword and functions is an attempt to avoid that. |
Under this proposal, how should we handle the names of result parameters? |
Also, can this be used in the declaration of regular functions? |
I don't know, but I would like to be able to declare regular functions that way, because then users of |
Do we need to? "reflect" package doesn't seem to have any support for it. |
I would rather not do that. This will make things complicated since you need to put actual function name into syntax. Also we probably love current syntax for regular functions as it is.
|
That turns out not to be the same, though! CopierFunc is now a variable referring to a function, not a function. Consider what you get from |
I can't quite see why would you want to abstract away any of the top level function declaration as those are mostly exported and represent type for interaction. |
@iamgoroot The reflect package doesn't support names of local parameters either. But in some cases you need a name of a result parameter in order to change it in a deferred function. That said, of course people could use the existing function declaration syntax for that case. But not permitting result parameter names does seem like an odd limitation. |
I wouldn't want to "abstract away" the top-level function declarations, but I do want a way to declare a top level function of a defined type. So it may not be part of your use case, but it's part of a related use case, and your proposal is the closest I've seen to something that would address mine. |
My bad. Thanks for pointing that out. Then we could get away with same approach - use the names and reuse the types. But this should probably be optional if needed at all.
|
Using an expression like Without a more persuasive notation we aren't going to adopt this proposal. Closing, but please free to comment, or open a new issue, if you have a different approach. |
Summary
As the title says it's all about named function types
If type 'transform' is an named function type allow for reusing that type data in function definition.
Motivation
Named function type seems like a nice feature but now the best you can do with it is code documentation and also you can put methods on your functions.
If you give a name to a function signature - you want to use that name in code somehow.
Same syntax will do for single-method interfaces. But that's harder since we'll have to distinguish single-method and multi-method interfaces. The 'type' keyword and functions is an attempt to avoid that.
It's not that go needs lambda functions. It's that we have those types defined in projects and they are 100% compatible.
The text was updated successfully, but these errors were encountered: