Subject: Re: About the usage of throw/catch From: Erik Naggum <erik@naggum.no> Date: 2000/02/14 Newsgroups: comp.lang.lisp Message-ID: <3159477157011411@naggum.no> * arolambler@aol.com (ArolAmbler) | I phrased it in a way subject to misintrepretation. Since the dynamic | scope of a tag ends with the dynamic scope of the tagbody, it is not | legal tn CL to create closures over recursive tagbodies, and go to tags | for tagbodies that have been exited. (Although I strongly suspect some | implementations do not detect the problem, and some may even support it | properly.). well, I asked for an example, got it, and now I'm asking for more. why this "strongly suspect" point? it seems you're creating problems for the purpose of creating or showing off complexity, not for the opposing, much more reasonable, purpose of solving them and reducing overall complexity. (this is a more verbose version of the "ivory tower" accusation.) | Thus, foo is called recursively, so there are multiple closures and | tagbodies active. a GO is explicitly defined to reach the innermost accessible tag, so this is not a semantic problem. it may be a pragmatic or stylistic problem in that you can't easily figure out which tag is the innermost, however. | As to "throw/catch" being "needed". That is true, WHEN you have to glue | together stuff in a hurry, and can't change the interfaces to some of it. I think you should consider the possibility that you have overlooked something when you make sweeping generalizations like this. it is quite annoying to have to deal with statements that are true but incomplete, yet false when completed or extended to their natural context. that is, your assessment of the situation is relevant, yet not the only one that needs to be considered, and therefore, the conclusion does not hold for anyone but those who restrict themselves to your particular context. again, "ivory tower" might apply to such strong yet narrow arguments. | BUT: it is far better to make the result value have one or more | "exceptional" values (such as null in ANSII SQL, or the NANs of IEEE | floating point arithmetic). The operations all "propagate" the | exceptional VALUE, without any non-local control transfer. I was disappointed when waiting for the capitalized WHEN to support the "it is far better" sweeping generalization sans reservations or context. in some contexts, what you propose is indeed a good idea. few people use CATCH/THROW or other exception-handling mechanisms in such contexts, for the very simple reason that the first time they run into a problem, they will most probably swear and even more probably redesign their code. in the context of an exception-handling mechanism that is ill-designed, we do have the option of talking to the people who wrote the code and even in many cases to do what you consider so gross -- to wrap up the code in some advice or whatever to protect you from harm, but doing so in cases where it clearly has no value is an argument against your generalization. | As I said in the first post on this issue: non-local transfer of control | is dirty, because it does not "reuse" well. yes, this is so, in _some_ contexts, but I'm getting increasingly curious why you exclude all _other_ contexts as inherently irrelevant to any discussion of this language feature or of exception-handling in general. | Said in a more sophisticated way, incomprehensible probably to the | original poster, neither functors nor combinators in general, nor any | function that maps a function over a set of values can easily use any | function that sometimes throws, unless the function is first "cleaned up" | by wrapping a catch, return exceptional value piece around it. And | repetitively "cleaning up" every time I reuse a function means the | function has a bad behavior. this is obviously a bogus general claim. most of the time, we are not faced with irreversible side effects of our functions, and we are not therefore in need of a transactional approach to "committing" or not "committing" whole executions of complex pieces of code. it helps, and I'll easily grand you that, to know _when_ to require a simple "completed or not done at all" result from a function, however. "best effort"-functions that return some "impossible" values may actually have the annoying consequence that the failure mode is _less_ predictable than an exception, as _some_ transactions were "committed" after some failure had occurred, meaning that the failed transactions now have to be committed out of order, or not at all, which is very different from an _aggregate_ "commit". I hope you appreciate this distinction. I'm not interested in your ad hominem arguments: just because you have shipped so-and-so-products does not lend any credibility to any of your arguments -- I'm _not_ interested in who you are or what you have done; I _am_ interested in whether you can support your sweeping arguments without reference to such claim to fame or credentials, the inclusion of which in my view detracts very significantly from effective argumentation. #:Erik, who's beginning to discover that vacations have serious down-sides :)