Skip to content
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

proposal: Go 2: spec: shorter, type-inferred anonymous function syntax with usage limited to function arguments #47358

Closed
DeedleFake opened this issue Jul 23, 2021 · 6 comments
Labels
FrozenDueToAge LanguageChange Proposal v2 A language change or incompatible library change
Milestone

Comments

@DeedleFake
Copy link

Would you consider yourself a novice, intermediate, or experienced Go programmer?

Experienced.

What other languages do you have experience with?

C, Java, Kotlin, Ruby, Python, JavaScript, and some others, all to varying degrees.

Would this change make Go easier or harder to learn, and why?

Slightly harder, probably, but not by much, I think.

Has this idea, or one like it, been proposed before?

Yes. I can't seem to find them, but there have been proposals for similar syntaxes before. However, I believe that there are two key differences between those proposal and this:

  • The circumstances have changed due to generics being so close.
  • This proposal is much more restricted in what it allows, which I believe removes some of the concerns with the previous proposals.

Who does this proposal help, and why?

Anyone trying to call functions that take a simple function as an argument.

What is the proposed change?

The proposal is for a short syntax for anonymous functions. Currently, all functions must be fully typed, which can lead to some awkward code. For example, take the new proposed slices package:

// Pointless usage of EqualFunc() instead of Equal(), I know.
slices.EqualFunc(s1, s2, func(v1, v2 int) bool {
	return v1 == v2
})

The explicit typing makes calling this type of function a lot bulkier than it needs to be, and I think that it hurts readability as I result. Despite the type inference on the type parameter for EqualFunc(), the function signature of its third argument must be explicitely typed at the call site if using an anonymous function in this way. This example is very simple, but more complicated code could easily get very awkwardly difficult to read.

I propose that a short syntax be added that is only available in an argument to a function call. What the specifics of the syntax are can be debated, but as an example with some syntax borrowed, somewhat, from Kotlin:

// One-line function example:
slices.EqualFunc(s1, s2, { v1, v2 -> v1 == v2 })

// Multi-line function example:
slices.EqualFunc(s1, s2, { v1, v2 ->
	d := v1 - v2
	return (d < 3) && (d > 3)
})

Again, syntax isn't too important, but whatever syntax was used needs to support listing arguments without types. I think that it's also a good idea if it allows returns without the return keyword, at least in shorter, single-expression functions.

Is this change backward compatible?

Yes, fully. The example syntax above could potentially conflict with #12854 in some cases.

What is the cost of this proposal? (Every language change has a cost).

Minor increase to language complexity from an understanding point-of-view. Potentially larger effect on compilation, as it would require some amount of type inference backwards from the usage of the value. Due to the limited nature of it, however, I believe that it would not be too problematic. Run-time cost is non-existent, as this is 100% syntax sugar for an existing feature.

gofmt would have to be updated to support a nice formatting for the new syntax, such as inserting spaces in between the { and the arguments in the example syntax.

How would the language spec change?

An additional section would have to be added to the section on function calls explaining the usage, and various syntax specifications would have to be updated to accomodate it.

Orthogonality: how does this change interact or overlap with existing features?

It improves the ergonomics of in-line anonymous function usage as arguments to other functions.

Is the goal of this change a performance improvement?

No. This has no run-time impact whatsoever.

Does this affect error handling?

Not directly.

Is this about generics?

Indirectly. Mostly no.

@gopherbot gopherbot added this to the Proposal milestone Jul 23, 2021
@jba
Copy link
Contributor

jba commented Jul 23, 2021

One of the costs is reduced readability. Of course it's easier to "read" the typeless closure superficially, since it's less cluttered. But it's harder to understand it, since the types are missing.

I don't think we'll be able to truly understand this cost without a significant corpus of before-and-after examples.

@seankhliao
Copy link
Member

this looks to have a lot of overlap with #21498

@DeedleFake
Copy link
Author

DeedleFake commented Jul 23, 2021

@jba

I agree that it's possible, but I don't think that it's by much. Other arguments to the function aren't named at the call site, either, but no one thinks that they should be. I realize that this is different because this is technically a variable declaration, but I think that the same principle still applies.

I think that it's also worth noting that a lot of languages have a feature like this, and the hit to readability has never been any kind major issue even without the proposed restriction, and certainly not one that outweighs the benefit. And that does include statically-typed languages, such as Rust, Java, and Kotlin. A thorough study of different examples would be good, though.

@seankhliao

Ah, there's the one that I couldn't find when I was writing. I know it has overlap, but that one's a proposal for a general shorthand anonymous function syntax, while this one's very restricted, only allowing them in one specific place that's by far the most useful. I think that that's different enough to warrant an entirely different proposal, but if the devs think that it's too similar I'm perfectly willing to recreate it as an addendum in the comments of that one.

@seankhliao seankhliao changed the title proposal: shorter, type-inferred anonymous function syntax with usage limited to function arguments proposal: Go 2: spec: shorter, type-inferred anonymous function syntax with usage limited to function arguments Jul 23, 2021
@seankhliao seankhliao added v2 A language change or incompatible library change LanguageChange labels Jul 23, 2021
@ianlancetaylor
Copy link
Contributor

I think this is just an aspect of #21498, notably #21498 (comment). That issue has a wide ranging discussion of shorter ways to write function literals, and I think this suggestion fits in there as well. I think this idea should be added to #21498 and we should close this issue.

@DeedleFake
Copy link
Author

Sounds good to me. I'll rewrite it as a comment in that one.

@DeedleFake
Copy link
Author

DeedleFake commented Jul 23, 2021

Commented.

@golang golang locked and limited conversation to collaborators Jul 26, 2022
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
FrozenDueToAge LanguageChange Proposal v2 A language change or incompatible library change
Projects
None yet
Development

No branches or pull requests

5 participants