Live data from Hacker News

You’re better off using Exceptions

eiriktsarpalis.wordpress.com

201–210 of 242 posts

Re: You’re better off using Exceptions

#201

Earlier quoted context omitted.

In Java/C# land exceptions are EXPENSIVE. Like magnatudes more expensive. You have to build a full stack trace etc. Removing places in the code where it is "Throwing exceptions for non exceptional circumstances" has a dramatic performance increase benefit.

Technically in Java it is possible to create an exception object once, and throw it multiple times, making throws much cheaper as the stack trace is filled during the object's construction only.

Does this actually save much time? I thought it was the throw mechanic that was slow, rather than just creating the exception?

Re: You’re better off using Exceptions

#202

Good article but it is tangential to a basic design issue. Error handling should be done at the edges of systems rather than in the center. If you do that, it doesn't matter whether you use exceptions or error monads, you have a pure core that doesn't need to deal with error handling and a very slim area to catch errors. The mechanism you use for error handling, at that point, doesn't matter. The problems of error ha…

it's not trivial in every domain to distinguish between pure and non-pure operations. If you're writing software for control systems, robotics, anything that has a very tight, low-level coupling between programming logic and the outside world it's harder or often not possible to separate concerns into some sort of data -> logic pipeline that lends itself to this style of programming, or it may come at the cost of per…

It's a decent goal, though. For all else, there's Erlang.

Re: You’re better off using Exceptions

#203
post #60

Earlier quoted context omitted.

It all depends on context. I believe that's why python for example throws an exception if given key doesn't exist when you use `dictionary[key]` but also gives you option to call `dictionary.get(key, [value])` which returns `None` or `value` (if specified) if the `key` doesn't exist.

That one bites me when I've been away from Python for awhile. I prefer 'open' maps/dicts, where every key is valid and any unassigned value is None/nil. I don't consider looking for an invalid key exceptional, basically, so I wish the syntaxes were reversed, so I could use the more succinct form for (my) more common case.

Golang maps returns the value type's zero value in case the key doesn't exist: https://blog.golang.org/go-maps-in-action

The idiomatic way here being that the zero value should be a sane default for that value. You are then free to create your own types ontop of that, but the defaults are often in the ballpark of where you want to be unless you have specific needs in your context.

Re: You’re better off using Exceptions

#204
post #112
post #62

Earlier quoted context omitted.

> A record not being found is a normal thing! It's not a normal thing for code that needs that record that wasn't found. > They literally tell you nothing and there's no way to solve them without catching/rescuing them. A null value, a plain "error" object, or an error argument in a callback would have been sufficient. If I need an exception to be raised for this kind of thing, I'll do it myself. They tell you lots:…

> It's not a normal thing for code that needs that record that wasn't found. In many popular programming languages, the way to check whether some value has a certain property is with an “if” statement. It would be very odd to replace every code path inside an “if” statement with exception control flow simply because that code path “needs” some condition to be met for it it to execute.

If a user doesn't exist, any code that relies on having a user is broken, and I want a guarantee that code can't be reached. Throwing does that, mapping an Option does that, but "if" doesn't.

Re: You’re better off using Exceptions

#205

Earlier quoted context omitted.

I haven't written very much Java, but here are some differences between Java checked exceptions and Rust errors as I understand them: In Java, a function may throw a long list of checked exceptions, and these lists tend to grow to inconvenient sizes in larger programs. For example, if foo() calls bar() and baz(), which each throw 3 different exception types, then now foo() might throw 6 different exception types. In…

I don't think this is a real difference. You can make the exact same API design mistakes regardless of which error delivery mechanism you use. The important thing is for the API designer to think about the abstractions, i.e which types of errors should be part of the API and which errors are just implementation details that may change. If the API designer is too lazy to put enough thought into that then the result wi…

There is always an onus on an API designer creating an API to express it well. However I think the difference between good vs bad language (and a good vs bad API come to think of it) is that it makes doing the right thing easy (lazy), and the wrong thing hard.

I think about this when I think about GraphQL. I like GraphQL, I really do, but GraphQL's N+1 problem is why I don't recommend it. The easy thing is to hammer the heck out of your database, the hard things is to parse the GraphQL request and correctly transform it into a SQL statement. I just don't trust everyone on the dev team to not be lazy.

Re: You’re better off using Exceptions

#206

Earlier quoted context omitted.

For most implementations of maps (hashtables and various tree-ish things), even in the single-threaded case, doing .exists and then .get is about twice as expensive as doing a .get that returns an Option (or nullable reference, default value, whatever)- you have to do the map lookup twice. (Okay, probably not twice as slow, since the cache will be hot, but still.)

Not twice as slow. But you are forgetting the case where you know the element is already in the map, and you want to call map.get() without wrapping it in an option.

C# does this fairly nicely with an "out" parameter: https://docs.microsoft.com/en-us/dotnet/api/system.collectio...

Or if you "know" it's there call the version that throws an exception if it isn't.

Re: You’re better off using Exceptions

#207
post #130

Earlier quoted context omitted.

Nulls are also called the billion-dollar mistake (and that was decades ago; it's much more than that now). Both nulls and exceptions are ways of trying to make the main line of processing clear, while handling other lines in structured ways. There's no one-size-fits-all solution. In a lot of ways, the best response to "record not found" is that you get the same result as finding one, except with zero answers. That me…

> Nulls are also called the billion-dollar mistake (and that was decades ago; it's much more than that now). Both nulls and exceptions are ways of trying to make the main line of processing clear, while handling other lines in structured ways. At the same time before NULL, devs used to use "guard values", so NULL is really just a convenience. for instance, just to illustrate what I'm saying: let NULL = {} /* should e…

Zero values may act as nice defaults. Programmers who care about their code, often want initial state or default state to reflect something useful. What zero value should reflect depends on context, but you get to state that once and for all, for that type. It's just one less thing off a mind when building code, although you'd want to catch any invalid usage. Ie. referencing zero value, could result in error if due to control flow, and panic() in case of programmer error. I don't think the language or library should choose for you, unless being bound by that is a very useful trade-off.

Re: You’re better off using Exceptions

#208

Exception != Error Old Ada programmer here. Example of reading bytes from a file... just keep reading bytes and don’t include logic for checking for EOF. Let the exception handler catch it where the file will be closed. Clean separation of code. In Ada, every bock can have exception handlers at the bottom. No need for “try” syntax. Very clean.

> don’t include logic for checking for EOF. Let the exception handler catch it where the file will be closed What happens if the file is smaller than you anticipate? That's why exceptions aren't used for flow control.

Simply count bytes as they are read. In the exception handler check to see if the count matches the expected value. Clean.

Re: You’re better off using Exceptions

#209

Earlier quoted context omitted.

C++ too. I suspect it’s true in almost every language. Maybe not Python? But Python is slow regardless.

In C++, exceptions are often faster than manual error checking when errors are rare. But C++ does not provide a stack trace.

> But C++ does not provide a stack trace

Which makes exception in C++ a very, very bad idea!

My reaction to 'the test fails because map::at threw an exception': stupid STL!!

A core dump would be so much easier to analyze.. Gdb's 'catch thow' is wonderful (well, it is after I fixed the part of our codebase which use exceptions as a control flow mechanism)

Re: You’re better off using Exceptions

#210
post #79

Earlier quoted context omitted.

Of course, if you're in a web app, and you've received an email address, and you can't find a User record for that email address, a perfectly valid approach would be for the fetch to throw a 'not found' exception and to generically handle all 'not found' exceptions in request handlers to return 404 status codes.

Then would you be nesting a number of exceptions. Some maybe real 404 exceptions, but some would be zero records found. And I think the zero records found should be handled in the business logic (if statements, switch/case), not in the exceptions.

The expectation of a single result should be encoded in the API, not the business logic. It's a very common expectation for e.g. identifiers found on http paths.
Post reply on HN