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: add receiver shortcut (default this/self) #25353

Closed
kgolab opened this issue May 11, 2018 · 8 comments
Closed

proposal: Go 2: add receiver shortcut (default this/self) #25353

kgolab opened this issue May 11, 2018 · 8 comments
Labels
FrozenDueToAge LanguageChange Proposal v2 A language change or incompatible library change
Milestone

Comments

@kgolab
Copy link

kgolab commented May 11, 2018

Currently the method receiver needs to be explicitly specified when it's used, whether it's for calling another method of the receiver or accessing struct fields.

My proposal is to allow the receiver name be omitted, either completely or by using only a dot.

Let's assume I have a method:

func (obj *MyObject) MyMethod() {
  obj.anotherMethod()
  // more code
}

I could then simply use anotherMethod() or, if we're afraid of shadowing, let's keep the dot and use .anotherMethod().

The only rationale behind the idea is to omit the often-repeated name and slightly shorten the code.
As far as I can see (not far, admittedly), this could be incorporated in Go2 or even Go1.

@gopherbot gopherbot added this to the Proposal milestone May 11, 2018
@myitcv
Copy link
Member

myitcv commented May 11, 2018

I suggest this is a problematic idea for many of the same reasons that dot imports are discouraged.

More details https://groups.google.com/forum/m/#!topic/golang-nuts/XCNzIfM4VmU

@agnivade
Copy link
Contributor

This will hurt readability. Go emphasizes clarity and readability over terseness. And in most cases, a receiver is just 1 to 3 characters long anyways. So IMO, it's not worth it.

@ianlancetaylor ianlancetaylor changed the title Proposal: add receiver shortcut (default this/self) proposal: Go 2: add receiver shortcut (default this/self) May 11, 2018
@ianlancetaylor ianlancetaylor added the v2 A language change or incompatible library change label May 11, 2018
@ianlancetaylor
Copy link
Contributor

func Do() { ... }

type T struct { ... }

func (t *T) Do() { ... }

func (t *T) M() {
    // Which Do is called?
    // There is an answer, but it seem sure to be confusing to readers.
    // Is the benefit worth the cost?
    Do()
}

@creker
Copy link

creker commented May 11, 2018

Omitting it completely will definitely hurt readability and introduce a bunch of problems that other languages have to deal with because of the ability to omit this/self.

Why not instead introduce mandatory this/self when the name of the receiver is omitted? Like so:

func (*MyObject) MyMethod() {
  this.anotherMethod()
  // more code
}

This has two advantages:

  1. You no longer have to come up with a name for the receiver. Naming things is always hard
  2. Future readers wouldn't have to guess, what it is when they see f.Foo(). Is it local or global variable, name of a package or the receiver? You see this.Foo() and instantly understand what it is.

Obvious disadvantage is it introduces a new keyword. Don't known how context aware Go compiler is and will it be a major problem.

@kgolab
Copy link
Author

kgolab commented May 11, 2018

Regarding shadowing caveat: that's why I also suggested an alternative dot-syntax .anotherMethod() to avoid problems here.

Regarding readability: actually I consider short receiver names a bit harmful since they tend to lose the context, what is a good receiver name below? If it's usually self, this or me it does not add much to readability. If it's something longer (washer perhaps) then the code becomes a bit too verbose for my taste.

func (self *WashingMashineImpl) Wash() {
  self.checkPreconditions()
  self.heatTheWater()
  // more code
}

I like the direction suggested by @creker, removing the receiver name altogether solves the above problem for me. Instead of introducing this I'd simply stay with dot notation though, to avoid an extra keyword. If easy parsing is important than maybe we can use underscore instead of the name though to my eyes it's not too pretty: _.anotherMethod().

But based by the initial reaction I guess the suggestion is not really in the spirit of go language.

@robpike
Copy link
Contributor

robpike commented May 11, 2018

Not just the spirit, but the idea that every identifier's origin is easy to find just by looking at it, without parsing and other complexities. Type aliases complicated that somewhat but they are, sadly, a necessary evil. Otherwise, when I see x.Y I know that if I find the declaration for x, I will know what Y is, and that x is an identifier defined in this package. If I see a bare Y, I know that Y is itself defined as a top-level name in this package.

Your proposal breaks that property and should be rejected.

@quasilyte
Copy link
Contributor

There are of course fewer places in Go where some expression doesn't need "other complexities", but selector expressions, for example, can mean many things.
Methods expressions (Type.Method), fully-qualified names (idents from other packages), field access. And method invocations that can be either "real method" call or access for function-type struct member with invocation (for example: v.f() can mean more than one thing).

So there are some places that violate the idea described above, but it doesn't mean more of such features are desired.

@ianlancetaylor
Copy link
Contributor

We aren't going to do this, even in Go 2.

@golang golang locked and limited conversation to collaborators Sep 12, 2019
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

9 participants