Thanks for your answers.
Ian Lance Taylor <[email protected]> wrote:
> Giles Lean <[email protected]> writes:
>
> > a) Will there be a way other than relying on package
> > documentation or reviewing a package's source code to tell
> > whether a package may call panic(), and in particular which
> > function(s) in the package might do so?
>
> That is a fair question, and the answer is no.
Thanks, question answered, and it's probably the appropriate
choice.
> In particular, although it is not part of this proposal, I think that
> if this proposal is adopted it is fairly likely that a runtime error
> like an out of bounds access to a slice or an erroneous type assertion
> would become a panic. (Perhaps division by zero would also become a
> panic if that can be done efficiently.)
Now, those could be useful: I can imagine a defer() function picking one
of those up and giving useful (and likely different) data to both the
user of the application (who probably can't fix it) and the programmer
(who usually wants to).
Users find stack traces very unappealing, however useful they are
to programmers!
(Ian -- are you trying to sell me on exceptions being useful after
all? Hmm ....)
> > b) Will there be any indication (e.g. a compiler warning) when
> > I call a function which may panic without setting up an
> > appropriate defer() beforehand?
>
> Probably not. After all, there is nothing wrong with letting the
> panic propagate upward in the call stack, nor even with letting it
> crash your program if that is a reasonable course of action.
Pretty much what I expected. Indeed, I suspect if this proposal is
adopted it'll be common to declare a suitable defer() function early in
a goroutine's existence, just to take over control of the error
reporting so a compiler warning probably wouldn't help much: if there's
no appropriate defer(), there probably wasn't meant to be one.
> The name panic was chosen in part because it connotes a truly unusual
> condition.
I'm familiar -- one might say overly familiar -- with the term from 8+
years of kernel support for a Unix vendor. If used in similar
circumstances and as little as possible, I don't really object. If
you've painted yourself into a corner and can't levitate, you're out of
options, after all.
I would like to think there are fewer cases for libraries to panic than
for kernels to panic, of course, but good library design is non-trivial.
(And certainly during development panic wouldn't hurt in a language
without assertions; making it blatantly obvious to developers and Q&A
departments that "yes, we know this doesn't work yet" isn't nutty when
they hit something that's not implemented yet. Woe to the developer and
reviewers who let one of those out into a product though!)
> I personally think that a library function which intentionally panics
> and forces the caller to handle the panic is poorly designed.
I concur. (I've fought similar arguments about library functions that
spat error messages out to what they *thought* was standard error.
Library functions shouldn't do that, either.)
> Of course nothing in this proposal prevents somebody from writing such
> a function. It's reasonable to ask whether the language can provide
> some mechanism to prevent it. This is just a proposal at this point,
> and if anybody has a clever suggestion here we would certainly
> consider it.
I suspect nobody will come up with a clever enough suggestion, because
sometimes it may be the library that has something panic-worthy happens.
One example would be a "can't happen" case in a library triggered by
hardware data corruption: a panic would sometimes not be out of order
there, any more than it would be within a kernel.
(A "can't happen" based on corrupt input would be another matter:
that would just be an error, IMHO. Programs should expect and be
prepared for corrupt input.)
> That said, still speaking purely personally, I don't think exception
> specifications as in C++ or Java are appropriate for Go.
+1
In both languages I've found them a PITA, as I've had to code all this
extra "stuff" without much knowledge of what any of the individual
exception types was going to mean if I got one, at least until I buit up
an understanding of the underlying code. (Yeah, I have worked on too
many projects that have had totally inadequate documentation.)
> I don't think they have been succesful in those languages, ...
+1 also, but your knowledge of C++ and Java is well ahead of mine.
Thanks for the response. It answered of both my questions, and provided
more background to Rob's proposal (which I now suspect is not just Rob's
proposal :-).
Cheers,
Giles
Goexit would just be:
func Goexit() {
panic(runtime.Exiting)
}
if you have this then no-one can evade a defer
without taking down the whole program.
To unsubscribe from this group, send email to golang-nuts+unsubscribegooglegroups.com or reply to this email with the words "REMOVE ME" as the subject.
--
Daniel Smith
http://www.schaumburggoclub.org/
recoverable in the sense that you could abort some
number of function call frames and move on with
the rest of your program.
not recoverable in the sense that you could do something
to let the goroutine continue at the point of fault.
you shouldn't see many more invalid map accesses,
by the way. the next release will change the behavior
of m["no-such-key"] to return a zero value instead of
crash/panic. that change is already in tip.
russ
Thanks.
Also the exception proposal looks promising. :)
On Mar 24, 11:36 pm, "Rob 'Commander' Pike" <[email protected]> wrote:
> Instead, this proposal uses a slight change to the definition of defer and a couple of runtime functions to provide a clean mechanism for handling truly exceptional conditions.
Very elegant.
It looks like testing for panics would incur very little overhead (as
compared to creating a try-catch frame).
Do you have a general idea of what runtime errors could be detected
and what would just crash no matter what? A few were discussed, div
by 0, array index out of bounds...
Regarding:
>Another proposal may happen regarding handling/monitoring exceptions
>in goroutine A from the safety of goroutine B, but that is not part of this
>proposal and may not happen at all, although we believe it may be
>achievable entirely by library code given this proposal.
This would also be very cool. Right now I feel the syntax proposed is
a little bulky, but it is very precise. It seems tempting to creating
a generic "catch" syntax such as:
recover(x) {
printError()
}
rather then defer func() { x :=recover() }
but that may be taken as a C++, Java, C# style error handling. I
guess by writing out exactly what's happening there's much more
control, and these should be few and far between.
If this is able to handle handling and monitoring exceptions in other
goroutines, it sounds great! Otherwise, there may be a syntax that
can work with arbitrary goroutine exceptions... Hmm that thought
needs work.
> However there are some problems with it:
>
> ...
>
> 2. If a defer is handling a panic and there is a nested
> panic happens deep down in the called functions (which can
> easily happen while logging the panic), then this nested
> panic will be re-thrown.
I was and am uncomfortable about that too. But I'm still
thinking it through; in kernel land nested panics aren't
unusual (and nobody cares: only the first one counts, and
you're not trying to recover). And I don't think I _ever_ saw
more panics than one per CPU core and one extra, and I
wouldn't swear that I ever saw even that many in a single
crash.
On one hand, not allowing nested panics puts us right back
with "Your program exited. Sorry about that. Bye."
On the other hand, I agree the number of times that recovering
from a nested panic will then allow recovery from the initial
panic will be few, but disallowing this case seems harsh.
On the gripping hand, why stop at all? Can we have an
infinite cascade of panics? (Rob -- will we need a hard limit
at which point the runtime does throw up its hands in horror
and just bails out?)
Exceptions are tricky. After the discussion I've seen, I'm
becoming more enthusiastic about the proposal for Go, but
still fear that panic() will be way overused -- after all,
exceptions have been overused and abused in every language I'm
familiar with that has any form of them except perl, and
they're almost under the radar there, and there are plenty of
/other/ unwise things one can do in perl to mess with a
maintainer's sanity.
My take on this is still twofold, presuming the proposal or
a variant goes ahead (which I imagine it will):
a) the design and implementation has to be very, very careful
not to encourage overuse
b) as a community, much as preferred idioms (e.g. don't use an
'else' clause if you've called 'return' in the 'if' clause)
are already developing, we need to recognise and encourage
healthy (and only healthy) use of the new facility whatever
it turns out to be
Giles, possibly being pessimistic. Perhaps eggs sunny side up
will help. I think it's time to go and find out. :-)
What I like is to place my recovery at the beginning of the context,
without any more surrounding, indentation, and handling later. The
only thing I don't like is the notation. Defer is misused here, the
original idea is ok so. But I would like a statement like recover
taking a func with an empty interface. This func will be called if
there has been a panic().
func ImportantFunc() {
recover func(panic interface{}) { log.Stderrf("Ouch: %v", panic) }
DoSomething()
if IDontKnowWhatToDo() {
panic("I don't know what to do!")
}
DoMoreButOnlyWithNoPanic()
}
I hope I've been able to make my idea clear.
mue