C to Go

Go was born out of frustration with existing languages and environments for systems programming.

Thus spake the Go FAQ. I empathize. I dislike C++ and Java so much that I’ve stayed with C. More precisely, I’ve stayed with GNU C, because of lexical closures and a few other extensions.

Could Go replace C? Does Go truly combine efficient compilation, efficient execution, and ease of use? The best way to judge was to try real systems programming with Go.

A good place to start is the list of GNU Core Utilities. Here are my experiences with implementing some of the simpler utilities.

Thanks!

Thanks to Ivan Krasin, Carlos Cobo, Karl Magdsick, Michael Gehring, and Bob Appleyard for suggestions.

CAUTION

I wrote these notes long ago while I was learning Go, so they are likely outdated.

Nowadays I spend most of my energy on Haskell. Go is a natural intermediate step between C and Haskell.

  • Go’s (:=) operator does type inference. Haskell’s type inference is so powerful that we can write entire complex programs without a single type declaration (though leaving some in is usually preferred for clarity).

  • Go has channels and goroutines. Haskell has equivalents, along with other powerful constructs for concurrency such as Software Transactional Memory.

  • Go has interfaces. Haskell has type classes, which can be viewed as generalized Go interfaces. Type classes easily solve one of Go’s biggest problems: lack of generics.

  • Go has anonymous functions. Haskell has lambdas, currying, type parameters, and type inference which together yield elegant notation for manipulating functions.

  • Go has numeric constants. Haskell also has numeric literals, but thanks to type classes, we can use constants with user-defined types rather than a specific subset of built-in types.

  • Go has garbage collection. Haskell does too, but since data is typically immutable (due to purity), garbage collection can be extremely simple and fast.

For example, here’s a Haskell version of yes:

import Control.Monad
import System.Environment

main = getArgs >>= forever . putStrLn . f where
  f [] = "y"
  f xs = unwords xs




Ben Lynn blynn@cs.stanford.edu