Hacker News new | past | comments | ask | show | jobs | submit login
Go-internals: Chapter 2, “Interfaces” released (github.com)
252 points by teh_cmc 11 months ago | hide | past | web | favorite | 12 comments



It surprised me how go's interfaces have non-trivial limitations. What lately bit me is illustrated in the following snippet: the call to doSomething() is just not possible in Go:

  package main

  import "fmt"

  type S struct {
        i int
  }

  func (s *S) foo() {
        s.i++
        fmt.Println(s.i)
  }

  type Sarr []S

  type I interface {
        foo()
  }

  func doSomething(arg []I) {
        arg[0].foo()
  }

  func main() {
        arr := Sarr{S{i: 1}, S{i: 2}, S{i: 3}}
        arr[1].foo()

        doSomething(arr)
  }
I understand why the current implementation of Go doesn't work that way, and that the meta-reason for this not being implemented is the "we don't want generics" attitude, since it would effectively require 2 different compilations of doSomething(), one which accepts a slice of interfaces, which are a (pointer,type) tuple, and one which accepts an slice of this specific struct which happens to actually implement the I interface, and that's a taboo, but come on... it just weakens the idea of interfaces. It could have been done as a compile-time work-around which constructs the slice-of-interfaces argument on-the-fly before calling the function - it wouldn't have been the only magical thing in Go.


>It could have been done as a compile-time work-around which constructs the slice-of-interfaces argument on-the-fly before calling the function - it wouldn't have been the only magical thing in Go.

Is there a language that works the way you describe ?


Not quite, but I believe Nim works similarly. But it also has generics, and it’s function dispatch resolution is neat, so it’s not quite apples-to-apples


The reason this doesn’t work is because conversions of this nature may require allocations, and like C++, Go doesn’t want to hide costly operations from the author.


Really nice write up.

I wish more microbenchmarks go that deep into IR/codegen analysis (somewhat related : https://mrale.ph/blog/2014/02/23/the-black-cat-of-microbench...).


Go assembly is more of a low-level intermediate representation. It isn't as high level as LLVM-IR, but it isn't what the processor runs on. I wonder how much is obfuscated by this, especially when compiled with optimizations?

Is there really much to be learned by analyzing performance in unoptimized pseudo-assembly? It's like looking at JVM bytecode for performance indicators.


Love the writeup! Very readable for someone like me who works much layers up in programming.

I have also written a primer on go-concurrency. https://gist.github.com/rushilgupta/228dfdf379121cb9426d5e90...

Thoughts?


Looking forward to read the GC chapter.


Great writeup, really happy to see closer looks at Golang. I've worked with Go a few times, but I've thought that getting good independent looks/great examples is a bit too difficult.

Thanks!


What does //go:noinline mean in this context?


go has certain quasi hidden directives for the compiler. This one means "don't inline the following function."


to me it seems like the version of "you don't know JS" but for Golang. nicely done!




Applications are open for YC Summer 2019

Guidelines | FAQ | Support | API | Security | Lists | Bookmarklet | Legal | Apply to YC | Contact

Search: