Hacker Newsnew | past | comments | ask | show | jobs | submitlogin

If you were to implement this in a procedural language with side effects, what would you do about "finally"?


It would be a little more cumbersome to write, but the same effect can be achieved easily:

  A a = new A();
  try {
      B(a);
      return C(a);
  } finally {
      a.cleanup();
  }
 
Transforms into:

  Either<Exception, Result> ret;
  
  A a = new A();

  ret = B(a);
  if (ret.isRight()) ret = C(a);
  
  a.cleanup();
  return ret;
Maybe someone can rewrite this even more cleanly. I can think of an easy-to-generate improvement containing a GOTO.


Forgive my ignorance, but what about this method saves us from having to use continuations to unwind/rewind the stack, as Exceptions do?


You can implement "finally" as a higher order function in Haskell:

  finally :: Either err a -> IO () -> (a -> IO (Either err b)) -> IO (Either err b)
  finally (Left err) cleanup  _k = cleanup >> return (Left err)
  finally (Right x)  _cleanup k  = k x
You avoid having to unwind the stack because the user of finally has to manually convert into CPS in order to supply the higher order argument of type "a -> IO (Either err b)"


"even more cleanly"

I think I prefer the try..catch..finally version - looks much cleaner to me.


Well yeah, but I thought the point was they were equivalent: i.e., one is simply syntactic sugar for the other.


It doesn't seem like the non-finally version will necessarily run in every case. In the instance of try/finally, a runtime exception might occur as well as a checked exception. finally will always run. But a.cleaup will not.




Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: