Proposal Details

It occurs to me that interfaces with single methods are ~isomorphic with passing funcs. Where one can pass a single-method interface, one can equivalently pass just that func.

My suggestion is that the complier might rewrite the call sites to pass this func instead of the interface, and avoid dynamic dispatch at runtime. I am curious if this idea is ~correct and whether it might be desirable.

type interface Fooer {
    Foo() Bar
}

func doSomethingWithFooer(fooer Fooer) {
    bar := fooer.Foo()
}

// becomes...

func doSomethingWithFooer(foo func() Bar) {
    bar := foo()
}

Exceptions

If one reflects or type-asserts against the interface, then substituting the func would not work. In that case, perhaps the rewrite would be to add the func as an argument, while also accepting the interface for reflection or type assertion.


// do both
func doSomethingWithFooer(fooer Fooer, foo func() Bar) {
    bar := foo()
    if fooer.(concreteThing)...
}

Thanks. Some related thinking here.

Comment From: randall77

I'm not sure it makes a difference. They are both dynamic dispatch.

package main

func f(x func()) {
    x()
}

type I interface {
    foo()
}

func g(x I) {
    x.foo()
}

If you look at the generated assembly, you get (on arm64)

f:
    0x0018 00024 (/Users/khr/gowork/tmp1.go:4)  MOVD    (R0), R1
    0x001c 00028 (/Users/khr/gowork/tmp1.go:4)  MOVD    R0, R26
    0x0020 00032 (/Users/khr/gowork/tmp1.go:4)  CALL    (R1)
g:
    0x0020 00032 (/Users/khr/gowork/tmp1.go:12) MOVD    24(R0), R2
    0x0024 00036 (/Users/khr/gowork/tmp1.go:12) MOVD    R1, R0
    0x0028 00040 (/Users/khr/gowork/tmp1.go:12) CALL    (R2)

There isn't really a meaningful difference between the two.

The only real benefit I see is that a func uses one word where as an interface uses 2. But if it is just in registers (as it would be for arg passing) that isn't a big deal. That smaller size only really matters in memory.

Comment From: gabyhelp

Related Issues

(Emoji vote if this was helpful or unhelpful; more detailed feedback welcome in this discussion.)

Comment From: clipperhouse

Makes sense. Thanks! The linked issue above is more general. I’ll close unless you intend to consider further.