A simple hack-functional-programming challenge was posted to Hacker News a few nights ago, quickly rising on the front-page, just as quickly disappearing (penalized for getting too many comments too quickly without corresponding upvotes).
Given that I’d been working on a solution using Go at the time, and that language was tagged as “likely impossible”, it grabbed my focus for a bit.
So I whipped up a solution.
It is a bit iffy whether it fully conforms with the guidelines (e.g. the score function type has a method String that is recognized and used (Stringer interface) by methods such as fmt.Println for seemingly automatic conversion, however this is by convention and the r-value is a func, not a string: You can’t simply cast or assign the func to a string without calling the String method), but I thought it a fun diversion.
Of pertinence for those who are less accustomed to go-
- g() creates a closure that is held and used by the returned function for its lifetime. This allows it to cleanly hold per-instance state without hacks like globals
- g() returns a function of the type score. That function type returns itself
- both f() and g() take …string arguments (variadic), meaning 0..n values. It adds o on 0 arguments, the string on 1, and panics on more than one, which is overloaded to extract the closure value
- the type score has a method called String defined on it, which by convention will be used by various library functions when a non-string type is encountered, calling String() to get the string representation (similar to Object.ToString/toString in C#/Java)
- as it’s a simple function type, without any further payload, and the closure was created in g(), getting at the value of the base variable in the closure from String was a fun challenge. In the end I abused panic/recover to extract the value, but still search for better methods. Do you know something better?
Anyways, it was a fun brief diversion. Go is an enjoyable language and the whole closure quandary amused me.