3 ms·
Holy shit that function adapters example is convoluted. I'd say fewer than 5% of my programmer coworkers would figure out what's going on. func init() {
by rorrr2 13y ago
Holy shit that function adapters example is convoluted. I'd say fewer than 5% of my programmer coworkers would figure out what's going on.
func init() {
http.HandleFunc("/", errorHandler(betterHandler))
}
func errorHandler(f func(http.ResponseWriter, *http.Request) error) http.HandlerFunc {
return func(w http.ResponseWriter, r *http.Request) {
err := f(w, r)
if err != nil {
http.Error(w, err.Error(), http.StatusInternalServerError)
log.Printf("handling %q: %v", r.RequestURI, err)
}
}
}
func betterHandler(w http.ResponseWriter, r *http.Request) error {
if err := doThis(); err != nil {
return fmt.Errorf("doing this: %v", err)
}
if err := doThat(); err != nil {
return fmt.Errorf("doing that: %v", err)
}
return nil
}
- zeeboo 13y agoLess than 5% of your coworkers understand decorators? I don't want to sound snooty but this is a pretty trivial application of higher order functions.
- rorrr2 13y agoI guess I work a lot with average developers. Not every corp is Google.
- jasonkostempski 13y agoSince you're a developer let's assume it's just that your estimate is way off :) Multiply it by 3 and pad it with an extra 10% or so.
- icebraining 13y agoI have to agree; it's basic stuff even for a Python weenie like me.
- marssaxman 13y agoIt's basic stuff because you're a Python weenie; I don't see much use or discussion of decorators outside the Python world.
- icebraining 13y agoThey might not be called decorators, but they're also used in JavaScript and other languages with higher-order functions.
- dragonwriter 13y agoDecorators are a special Python syntax for this use, the more general term for what is going on is "higher-order functions". Which are pretty important, and not specific to python.
- marssaxman 13y agoyes, of course, but the discussion I replied to was talking about this specific idiom, this application of higher order functions, and not about the use of higher order functions generally.
- sanderjd 13y agoFor what it's worth, this is also a very common pattern in ruby, using blocks: def with_error_handler if error = yield puts "error: #{error}" end end def do_things error = do_this return "error doing this: #{error}" if error error = do_that return "error doing that: #{error}" if error nil end with_error_handler do do_things end Having said that, I did need to read the Go version more than once to grok it. I theoretically like Go's syntax for defining functions that take functions, but in practice I find it quite hard to scan, especially if there are more parameters on top of the function, or the passed function has multiple returns, or (god forbid!) it takes a function itself - it can all become quite a lot of bookkeeping.
- hannibalhorn 13y agoIt's important to compare with the previous slide, to see the problem this is trying to solve. It'd be really easy to do a lot of if err != nil { http.Error(w, err.Error(), http.StatusInternalServerError) return } all over the place, as the error return type isn't part of the standard Handler signature. The decorator approach lets you return errors from your handlers, and then have your actual error handling centralized; you may want to send an e-mail to the ops team, send it to a third party exception management web service, etc.