Hacker News new | ask | show | jobs
by preseinger 1497 days ago
> on line 1471 of emacsclient.c[1], a call to connect() may fail - yet the caller, set_local_socket(), is clearly not responsible for e.g. quitting the application, because only its caller, set_socket()[2], has the contextual information necessary to know that quitting should not happen unless the attempts to open local UNIX domain and network sockets to the Emacs server also fail.

Line 1471 describes a failure condition, which is returned to the caller of the encapsulating function, which in this case is is line 1374 set_local_socket. The caller which invokes the function set_local_socket absolutely is responsible for handling that failure condition. The caller is not set_local_socket, the caller is the code which invokes set_local_socket. And if set_local_socket fails, the code which invoked set_local_socket is absolutely responsible for determining what to do. Quitting the application is a decision that only `func main` can choose to do! All other points in the call stack can only bubble the error up to their caller. That's the only rational course of action.

> Exceptions are very simple - they bubble up through the stack until handled . . .

I agree that this is "simple" in one sense. The problem is that this "simplicity" means that there are two mechanisms of call stack control flow. One is the code as it exists "on the page" -- function calls and return statements -- and another is the exception control flow -- everything expressed as throw/catch statements. This is two control flow paths: one visible in the code, and another invisible, or implicit, to the code as written. It should not be controversial to say that removing the concept of exceptions makes control flow easier to understand, to model, to predict, and therefore easier to model the behavior of programs in general.