Hacker News new | ask | show | jobs
by bern4444 1086 days ago
I can't help but think this is a clunkier than necessary. With function composition and the try/finally approach described we can get the same thing:

    const doSomeWork = () => {
      // some computation here. 
    }

    const withCleanup = (fn, cleanupFn) => {
      let x;
      try { x = fn() }
      finally { cleanupFn() }
      return x; 
    };

    const someCleanupFn = () => {
      // remove that file or whatever...
    };
    
    const doSomeWorkAndCleanup = withCleanup(doSomeWork, someCleanupFn);
    
This also provides lots of nice ways to understand what that cleanup behavior was to the caller. We could return an array of the original function return value and the result of the cleanup function. Maybe this reveals a potential new monadic structure that would be useful...

I agree doing this in OO, like what's shown in the page's examples, without the execution environment's support is tricky... I'd rather see though a new class to handle this rather than adding this behavior by adding a special method - it seems to put us back in the direction of having lifecycle methods like what React supports in class components that the community has totally moved away from.

I think I don't like that triggering the `dispose` method only takes place when the keyword `using` is present. It'd be much cleaner that it is always invoked on any object whose extends `Disposable`. Unless I have that behavior wrong...

1 comments

How would I access anything locally created inside doSomeWork from my someCleanupFn in this example?
Arguments to the doSomeWork can be carried through to someCleanupFn as can any return values from doSomeWork.

If doSomeWork returns all the pieces that need to be cleaned up by someCleanupFn (or those pieces are part of the original arguments), then those values can also be passed in as arguments to someCleanupFn.

This pattern (passing original arguments through, along with return values, to a supporting function) hints at a more elegant solution as well - a new monadic structure that supports this behavior by default.