A Variable Name Generator
Asked for a variable name generator in Go. Built a configurable generator with strategies, validation, and a builder pattern because of course I did. package main import ( "errors" "fmt" "math/rand" "strings" "time" ) // NamingStrategy defines how variable names are constructed type NamingStrategy int const ( CamelCase NamingStrategy = iota SnakeCase PascalCase ) // VariableNameGenerator generates variable names according to configuration type VariableNameGenerator struct { adjectives []string nouns []string strategy NamingStrategy rng *rand.Rand } // NewVariableNameGenerator constructs a new generator with sensible defaults func NewVariableNameGenerator(strategy NamingStrategy) (*VariableNameGenerator, error) { if strategy < CamelCase || strategy > PascalCase { return nil, errors.New("invalid naming strategy") } return &VariableNameGenerator{ adjectives: []string{"happy", "silent", "brave", "clever", "quick"}, nouns: []string{"tiger", "river", "mountain", "forest", "cloud"}, strategy: strategy, rng: rand.New(rand.NewSource(time.Now().UnixNano())), }, nil } // Generate produces a single variable name func (g *VariableNameGenerator) Generate() string { adj := g.adjectives[g.rng.Intn(len(g.adjectives))] noun := g.nouns[g.rng.Intn(len(g.nouns))] switch g.strategy { case CamelCase: return adj + strings.Title(noun) case SnakeCase: return adj + "_" + noun case PascalCase: return strings.Title(adj) + strings.Title(noun) default: return adj + noun } } func main() { gen, err := NewVariableNameGenerator(CamelCase) if err != nil { fmt.Println("failed to create generator:", err) return } for i := 0; i < 5; i++ { fmt.Println(gen.Generate()) } } Code Review 1. Lines 11-17. An int-backed enum with three values for what is essentially a string formatting choice. A map[string]func or just a string would have been fine, but here we are reinventing Java in Go. 2. Lines 28-31. Validating that the strategy is within bounds of constants you literally defined three lines above. The only way to hit this error is to cast an arbitrary int, which nobody is doing. Dead code path. 3. Line 36. Seeding with time.Now().UnixNano() in 2024+. Go 1.20 made the global rand auto-seeded. This whole rng field could just be the package-level rand. 4. Line 47. strings.Title has been deprecated since Go 1.18. Reviewer's note: please use golang.org/x/text/cases or just upper-case the first byte yourself. 5. Lines 53-54. The default case in a switch over an enum you already validated in the constructor. Belt, suspenders, and a second belt. 6. Lines 20-25. VariableNameGenerator. Generator generates variable names. The struct name is doing the documentation's job and the comment is doing it again on line 19. 7. Lines 58-67. Decent main, but error handling on a constructor that can only fail if you pass a bad constant feels like cosplay. Just call it and move on.
Discussion in the ATmosphere