Tuesday, April 24, 2012

I started playing with Google App Engine for Go, and immediately encountered failures due to how I like to structure code in packages. The go-app-builder parser rejects any imports containing double dots (..) outright, instead of checking if the import path actually attempts to escape the root of the app.
One structure I was trying to use was:
  • ./app
  • ./app/app.go
  • ./module
  • ./module/interface.go
  • ./module/implementation1
  • ./module/implementation1/implementation1.go
  • ./module/implementation2
  • ./module/implementation2/implementation2.go
where ./app/app.go has something like:
    package app

    import "../module"
    import "../module/implementation1"

    var instance module.Interface = implementation1.New()
and ./module/interface.go has something like:
    package module

    type Interface interface {
            // omitted
    }
and ./module/implementation1/implementation1.go has something like:
    package implementation1

    import "../../module"

    func New() module.Interface {
            // omitted
    }
I could change ./module to ./app/module, which make one part of it work. It would also make code structure ridiculous, since, if I had another package, ./module2, that imports ../module1, then I'd have to structure it as ./app/module2/module. And if I had a third module that also imports ../module, then I'd need ./app/module2/module3/module or ./app/module3/module2/module, which is the case of ./module/implementation1 and ./module/implementation2. And it gets worse with more packages. Perhaps it's expected that AppEngine code should all be lumped into a single package, which is horrible.

Monday, April 2, 2012

After playing with Go (golang), I think the biggest flaw in its
syntax is using the period (.) for the package qualifier, which
is not distinct from field selectors and method calls. It's
not horrible and not worth changing, but I still consider it a
minor flaw. Here's an illustrative example:

package main

import "os"

type a struct {
Args int
}

func main() {
println(os.Args) // os is a package
os := a{4}
println(os.Args) // os is a variable
}

Java has the same issue, but since packages qualifiers in Java
tend to be things like java.util.something or org.apache.something,
they aren't likely to collide with identifiers, and, in practice,
the result is there are compile errors about unknown packages when
using undeclared variables. In Go, package qualifiers are much
more likely to collide with useful names.

If one could go back in time to change it, some alternatives could
be ::, \, or #. Other possibilities include ~, !, @, $, or ?.