# Method expressions

### October 30, 2023

There was no livestream today, as I was a bit under the weather. I intend to be back live streaming next Monday as usual

## Method expressions

If `M` is in the method set of type `T`, `T.M` is a function that is callable as a regular function with the same arguments as `M` prefixed by an additional argument that is the receiver of the method.

``````MethodExpr    = ReceiverType "." MethodName .
``````

This might seem a bit mundane at first. But there’s something subtle, going on here, that surprises most people when they first encounter it.

Consider a struct type `T` with two methods, `Mv`, whose receiver is of type `T`, and `Mp`, whose receiver is of type `*T`.

``````type T struct {
a int
}
func (tv  T) Mv(a int) int         { return 0 }  // value receiver
func (tp *T) Mp(f float32) float32 { return 1 }  // pointer receiver

var t T
``````

The expression

``````T.Mv
``````

yields a function equivalent to `Mv` but with an explicit receiver as its first argument; it has signature

``````func(tv T, a int) int
``````

If you’re like most, you’re so accustomed to calling methods on instantiated values, that you’ve never considered what the full function signature of a method looks like when separated from the receiver—or that the concept even makes sense.

But that’s essentially what we’ve done here:

``````x := T.Mv

notMv := func(T, int) int {
return 0
}
x = notMv  // This assignment is valid, because notMv is of the same type as x, aka `func(T, int) int`
``````

That function may be called normally with an explicit receiver, so these five invocations are equivalent:

``````t.Mv(7)
T.Mv(t, 7)
(T).Mv(t, 7)
f1 := T.Mv; f1(t, 7)
f2 := (T).Mv; f2(t, 7)
``````

Tomorrow we’ll complete the discussion of the second half of the example, with the pointer receiver.

Quotes from The Go Programming Language Specification Version of August 2, 2023