Skip to content

Go pain points

Ayke edited this page Aug 9, 2019 · 6 revisions

Pain points in the current Go implementation

Here are a few pain points of the Go language and standard library for TinyGo. More details below.

  • [high] The Go standard library is closely coupled with the runtime. This is very problematic, because it forces numerous hacks and workarounds to be able to use standard library packages from Go code.
  • [high] No support for a non-OS (baremetal) GOOS. It would be great to have GOOS=noos (or similar) that requires manual implementation of system calls (perhaps reusing the POSIX libc interface). This is worked around by using linux/arm as GOOS/GOARCH, even on bare-metal systems.
  • [med-high] Package initialization order forces sequential initialization of globals. This has been worked around with a partial evaluator, which works surprisingly well but cannot be entirely complete.
  • [medium] No support for volatile variables. This has been worked around by defining a new "runtime/volatile" package that is implemented directly in the compiler. Volatile variables are commonly used to directly access memory mapped peripherals.
  • [low] No support for bitfields. It would be useful to be able to split up a struct field into multiple pieces like in C, to reduce memory consumption and because some memory-mapped I/O is much easier to implement with this. Also, it makes supporting this in CGo much easier.
  • [low] No support for binary numbers. Bit twiddling is very common in embedded software. It would be useful to be able to write constant numbers with a 0b prefix like in Python, for example 0b11001010 (0xca). This has been implemented in Go 1.13.

Standard library

The current Go standard library is closely coupled with the runtime. This is fine for gc and gccgo, but it is problematic for tinygo as it implements its own runtime.

A solution is to clearly separate the Go standard library from the Go runtime. Ian Lance Taylor has described this in his Go 2 transition proposal. It comes down to determining which packages are runtime bound and which are not, and distributing the latter as a separate Go module. Runtime-related packages are of course package runtime, but also packages like reflect and sync that must be closely coupled with the compiler and runtime for them to work. As an addition to Ian's proposal, some packages like time may need to be split into a runtime-independent part providing parsing/formatting of time strings and basic time calculations, and a runtime-dependent part providing functions like time.Now and time.Sleep.

An additional constraint for TinyGo is that this standard library package must be truly independent of the compiler and runtime and not just version-independent of the compiler and runtime. It is not enough to keep the compiler/runtime ABI-compatible with past and future versions of the standard library package, but every part of the API/ABI between the standard library and the compiler/runtime must be clearly specified.