I was extending Gorgonia for a project of mine when I rapidly ran into a dot-import gotcha in Go. Specifically I was trying to implement a fused version of the Conv2d function that exists. The current Conv2d function works well, if you want to do image convolution related work. It could be quite a bit faster (if anyone from Intel is reading, I’d love some help in the same way Intel boosted the speeds of Caffe), but that’s not really the concern - different convolution algorithms have different performance characteristics, and should be used accordingly.

Anyway, here’s the project directory:

PROJECT/ ├── ops/ │ ├── convolution.go │ ├── convolution_nocuda.go │ └── convolution_cuda.go │ ├── main.go

The Conv2d function I was writing was in ops/convolution.go . It looked something like this:

package ops import ( "gorgonia.org/gorgonia" "gorgonia.org/tensor" ) func Conv2d ( im , filter * gorgonia . Node , kernelShape tensor . Shape , pad , stride , dilation [] int ) ( retVal * gorgonia . Node , err error ) { return nil , nil // actual code here, }

I go-built it, and ran into this error message:

$ go build . ./convolution.go:12:6: Conv2d redeclared in this block previous declaration during import "gorgonia.org/gorgonia"

WTF?

As it turns out, it’s because I had this import in convolution_nocuda.go , which actually implemented the op:

import ( . "gorgonia.org/gorgonia" )

I had used it as a dot-import because unqualified imports look more like I’m writing parts of the Gorgonia package. I had assumed that the dot-imports were unqualified per-file. It’s not. It’s unqualified throughout the package.

The solution is simple: namespaces are useful. Use them.