Don’t Worry About Anything, Just Call Us

Callbacks are great and always have been. Long ago, we didn’t know we were injecting control or inverting dependencies; we just used them. When closures appeared, I did not see a huge difference: a little state here, a little context there. I have found my Closures Killer App: remote cleanup

Here is an example in Go:

In the calling code (with dependencies on DataDog, Redis, etc.)

type cleanupSignature  func(aName, aType string) func()

cleanupFactory := func(aName, aType string) func() {
    if _, found := SpanFromContext(context); !found {
        span, _ := datadog.SpanFromContext(context, aName, aType)
        return func() {
            span.Finish()
        }
    } else {
        return func(){}
    }
}

baz := foo(cleanupFactory, bar)

// ...

In the called code (with no dependencies on context, DataDog, etc.)

func foo(cleanupFactory cleanupSignature, zap int) string {
    cleanupFunction := cleanupFactory("my name", "my type")

    // this is like a `finally`, but lives at the top of a function
    defer cleanupFunction()

    // ...

The cleanupFactory is more than a factory: in the example, it might create and start a DataDog Span. It closes (encapsulates) the caller’s context and the reference to DataDog. It decides what cleanup its actions need, possibly being no actions at all. If the factory creates and starts a Span, the function it returns encapsulates the Span reference needed to clean up. The host function has no knowledge or access to this value

Rather than the function foo() holding extra values returned from the factory to control if and how the cleanup function works, the factory always returns only a simple function which foo() blindly calls. If nothing needs doing, the cleanup function is a nop. If it needs to do things, the cleanup function has encapsulated the values it needs to do them rather than requiring foo() to pass arguments

from a story by Nick Potts

 
0
Kudos
 
0
Kudos

Now read this

A Function’s Interface Is It’s Bond

TL;DR: A function must respect all arguments or return an error The Arguments # The only realistic way a function can fail its interface is how it treats arguments as mis-typed arguments or return values are usually caught by a framework... Continue →