[erlang-questions] erlang:raise/3 considered harmful?
Per Hedeland
per@REDACTED
Sat May 14 16:13:41 CEST 2016
Thanks for your reply. It's always difficult to put enough info in a
post while still avoiding the TL;DR syndrome, and while it is indeed
often the case that the right answer is to a different question than the
one that was originally asked, I'm afraid you're completely missing my
point.
The interface/3 is a library function, part of a larger library (and the
interface of the library isn't up for discussion), and loop/3 is just
the traditional we-don't-have-loops-so-I-need-a-recursive-function
helper, not a "main loop" in any way. Think lists(3), some of the
functions there take a fun, some don't, and I don't think I've ever
heard the suggestion that it would be a better design if you had to
implement a behavior with callbacks in order to use the currently
fun-taking functions...
And the question also isn't about *using* exceptions - just the fact
that they happen due to bugs, and that it should be possible for the
library user to handle the exceptions that happen due to bugs in hir
fun, even if only by getting a useful crash report from them. The lists
module doesn't have the problem I want to solve, since there are no side
effects and thus no need for "cleanup" in the case of an exception - it
can (and does) just "let it crash", but that isn't acceptable in my case
- I need the "cleanup" to happen.
Bottom line, the only question here really *is* the one I asked below.
--Per
zxq9 <zxq9@REDACTED> wrote:
>
>On 2016å¹´5æ14æ¥ åææ¥ 13:48:20 Per Hedeland wrote:
>> Hi,
>>
>> I happened to want something like erlang:raise/3 for a library function
>> - I didn't think it existed:-), but found that it does, although it
>> comes with a semi-dire warning. The loop/3 function below does exactly
>> what I want, specifically: if the fun provided by the caller of
>> interate/3 crashes, the caller gets the same exception as if there had
>> been no try ... catch, can handle it with hir own try/catch or not, but
>> in any case receives full information about *what* went wrong in hir fun
>> - all while the "protocol" spoken over the socket remains in sync.
>>
>> So, to take heed of the warning - is there a way to write an equivalent
>> function *without* using raise/3 - or should it just be considered a
>> case of "you really know what you are doing"? I believe I am of
>> course:-), but I also think that the code below is a perfectly
>> reasonable implementation of a side-effecty library function, and has no
>> more to do with debugging or knowing what you're doing than any other
>> code...
>
>Two things:
>
>1- Exceptions do indeed suck -- there is usually a better way to deal
> with errors in almost every case. Once you start using them there is
> often a strong urge to accidentally start writing imperative Erlang,
> and that gets so ridiculous so quickly that you'll start hating your
> project.
>2- In Erlang I tend to not keep lambdas around for very long as labeled
> objects (like keeping them in main loop state as in this example).
>
>The solution?
>
>*Usually* this purpose can be better served by changing this loop into
>a primary/callback module pair, where you have passed the callback module
>name in instead of a specific function. This can be as small or as large
>as you want, and Erlang has a special syntax to help give you warnings
>at compile-time by creating behaviors -- if you haven't done this before,
>it can be very rewarding. (The other way is to have an initiator call a
>function defined in some module and have the module define its own loop --
>the example provided does not include enough boilerplate/"system"-handling
>type code to discourage me from writing a custom module to do whatever Fun
>is doing there.)
>
>This principle is the whole basis for much of OTP, actually, and is a
>structure you will almost certainly wind up re-inventing yourself given
>enough time (I've re-invented OTP without realizing it at least 5 times
>in different languages and environments... before I realized what was
>happening.)
>
>If you have some specific reason a primary/callbacks structure can't work
>please detail it and let's see if it can be either worked around cleanly,
>or if some other approach is really required.
>
>-Craig
>_______________________________________________
>erlang-questions mailing list
>erlang-questions@REDACTED
>http://erlang.org/mailman/listinfo/erlang-questions
>
More information about the erlang-questions
mailing list