Go doesn't provide assertions. They are undeniably convenient, but our experience has been that programmers use them as a crutch to avoid thinking about proper error handling and reporting. Proper error handling means that servers continue operation after non-fatal errors instead of crashing. Proper error reporting means that errors are direct and to the point, saving the programmer from interpreting a large crash trace. Precise errors are particularly important when the programmer seeing the errors is not familiar with the code.

As it currently stands, this question is not a good fit for our Q&A format. We expect answers to be supported by facts, references, or expertise, but this question will likely solicit debate, arguments, polling, or extended discussion. If you feel that this question can be improved and possibly reopened, visit the help center for guidance.
If this question can be reworded to fit the rules in the help center, please edit the question.

I like to use assert a lot. I find it very useful when I am building applications for the first time (perhaps for a new domain). Instead of doing very fancy error checking (that I would consider premature optimization) I code fast and I add a lot of asserts. After I know more about how things work I do a rewrite and remove some of the asserts and change them for better error handling.

Because of asserts I spend a lot of less time coding/debugging programs.

I've also noticed that the asserts help me think of many things that could break my programs.

This comes up a lot, and I think one problem that makes defenses of assertions confusing is that they are often based on argument checking. So consider this different example of when you might use an assertion:

build-sorted-list-from-user-input(input)
throw-exception-if-bad-input(input)
...
//build list using algorithm that you expect to give a sorted list
...
assert(is-sorted(list))
end

You use an exception for the input because you expect you'll get bad input sometimes. You assert that the list is sorted to help you find a bug in your algorithm, which by definition you don't expect. The assertion is in the debug build only, so even though the check is expensive, you don't mind doing it on every single invocation of the routine.

You still have to unit-test your production code, but that's a different, and complementary, way of making sure your code is correct. Unit tests make sure your routine lives up to its interface, while assertions are a finer-grained way to make sure your implementation is doing exactly what you expect it to.

Assertions are not evil but they can be easily misused. I do agree with the statement that "assertions are often used as a crutch to avoid thinking about proper error handling and reporting". I have seen this quite often.

Personally, I do like to use assertions because they document assumptions that I might have made whilst writing my code. If these assumptions are broken while maintaining the code, the problem can be detected during test. However, I do make the point of stripping out every assert from my code when doing a production build (i.e., using #ifdefs). By stripping out the assertions in the production build, I eliminate the risk of anyone misusing them as a crutch.

There is also another problem with assertions. Assertions are only checked at run-time. But it is often the case that the check you would like to perform could have been performed at compile-time. It is preferable to detect an issue at compile time. For C++ programmers, boost provides BOOST_STATIC_ASSERT which allows you to do this. For C programmers, this article ( link text ) describes a technique that can be used to perform assertions at compile time.

In summary, the rule of thumb I follow is: Do not use assertions in a production build and, if possible, only use assertions for things that cannot be verified at compile-time (i.e., must be checked at run-time).

I prefer avoiding code that does different things in debug and release.

Breaking in the debugger on a condition and having all file/line info is useful though, also the exact expression and the exact value.

Having an assert that would "evaluate the condition only in debug" may be a performance optimization, and as such, useful only in 0.0001% of programs - where people know what they are doing. In all other cases this is harmful, as the expression may actually change program's state:

assert(2 == ShroedingersCat.GetNumEars());
would make the program do different things in debug and release.

We have developed a set of assert macros which would throw an exception, and do it in both debug and release version. For instance, THROW_UNLESS_EQ(a, 20); would throw an exception with what() message having both file, line and the actual values of a, and so on. Only a macro would have the power for this. The debugger may be configured to break at 'throw' of the specific exception type.

I admit having used asserts while not considering proper error reporting. However, that doesn't take away that they are very helpful when used correctly.

They are especially useful for if you want to follow the "Crash Early" principle. For example suppose you're implementing a reference counting mechanism. At certain locations in your code you know that the refcount should be zero or one. And also suppose that if the refcount is wrong the program won't crash immediately but during the next message loop at which point it will be difficult to find out why things went wrong. An assert would have been helpful in detecting the error closer to its origin.

I dislike asserts intensely. I would not go as far as saying they are evil though.

Basically an assert will do the same thing as an unchecked exception would, the only exception is that the assert (normally) should not be kept for the final product.

If you build a safety net for yourself while debugging and building the system why would you deny this safety net for your customer, or your support help desk, or anyone that will get to use the software that you are currently building. Use exceptions exclusively for both asserts and exceptional situations. By creating an appropriate exception hierarchy you will be able to discern very quickly one from the other. Except this time the assert remains in place and can provide valuable information in case of failure that would otherwise be lost.

So I fully understand the creators of Go by removing asserts altogether and forcing programmers to use exceptions to handle the situation. There is a simple explanation for this, exception are just a better mechanism for the job why stick with the archaic asserts?

Go does not have exceptions. The usual reason to use an assert rather than an exception is because you want it elided in deployment for performance reasons. Asserts are not archaic. I'm sorry to sound harsh, but this answer is not remotely helpful to the original question, nor correct.
–
Nir FriedmanApr 13 at 19:35

Not so much evil as generally counterproductive. There's a separation between permanent error checking and debugging. Assert makes people think all debugging should be permanent and causes massive readability problems when used much. Permanent error handling ought to be better than that where needed, and since assert causes its own errors it's a pretty questionable practice.

My problem with these answers defending assert is no one clearly specifies what makes it different from a regular fatal error, and why an assert can't be a subset of an exception. Now, with this said, what if the exception is never caught? Does that make it an assertion by nomenclature? And, why would you ever want to impose a restriction in the language that an exception can be raised that /nothing/ can handle?

If you look at my answer. My use is to differentiate 'exceptions' (asserts) that i want to get rid of used for debugging vs exceptions that i keep. Why would i want to get rid of them? because without them working it would not be complete. Example is if i handle 3 cases and the 4th is todo. I can easily search assert to find them in code and know its incomplete rather then use an exception that might accidentally be caught (by another programmer) or hard to tell if i its an exception or a logic check that i should solve in code.
–
acidzombie24Jan 28 '10 at 21:17

In my eyes, this is a poor idea, on the same level as "sealed" classes and for just the same reason. You're assuming the exceptions you want to keep are acceptable for uses of your code you don't yet know of. All exceptions go through the same channels, and if the user doesn't want to catch them he can choose not to. If he does, he should have the ability too. Either way, you're just making assumptions or pushing off your practice with a concept like an assertion.
–
Evan CarrollJan 29 '10 at 0:55

I decided example scenarios are best. Heres a simple one. int func(int i) { if(i>=0) { console.write("The number is positive {0}", i); } else { assert(false);//to lazy to do negatives ATM } return i*2; <-- How would i do this without asserts and is an exception really better? and remember, this code will be implemented before release.
–
acidzombie24Jan 29 '10 at 10:52

Sure exceptions are better, lets say I take user input and call func() with a negative number. Now, suddenly with your assertions you've pulled the carpet out from under me and not given me a chance to recover, rather than politely telling me what I'm requesting can't be done. There is nothing wrong with accusing the program of being misbehaved and issuing it a citation: the problem is you're blurring the act of enforcing a law, and sentencing the felon.
–
Evan CarrollJan 29 '10 at 16:30

Thats the point, you SHOULDNT say what the user wants to do cant be done. The app should terminate with the error msg and whomever is debugging would remember its something that SHOULD BE DONE but isnt. You DONT want it to be handled. You want a termination and to be reminded you didnt handle that case. and its extremely easy to see what cases are left since all you need to do is a search for assert in code. Handling the error would be wrong since the code should be able to do it once ready for production. Allowing a programmer to catch it and do something else is wrong.
–
acidzombie24Jan 29 '10 at 19:51

Often they get used in places where proper error handling should be used. Get used to writing proper production quality error handling from the start!

Usually they get in the way of writing unit tests (unless you write a custom assert that interacts with your test harness). This is often because they are used where proper error handling should be used.

Mostly they get compiled out of release builds which means that none of their "testing" is available when you're running the code that you actually release; given that in multi-threaded situations the worst problems often only show up in release code this can be bad.

Sometimes they're a crutch for otherwise broken designs; i.e. the design of the code allows a user to call it in a way that it shouldn't be called and the assert "prevents" this. Fix the design!

If the asserts you're talking about mean that the program vomits and then exists, assertions can be very bad. This is not to say that they are always the wrong thing to use, they are a construct that is very easily misused. They also have many better alternatives. Things like that are good candidates for being called evil.

For example, a 3rd party module (or any module really) should almost never exit the calling program. This doesn't give the calling programmer any control over what risk the program should take at that moment. In many cases, data is so important that even saving corrupted data is better than losing that data. Asserts can force you to lose data.

This person says that asserts should be used when the module has potentially corrupted data that persists after an exception is thrown: http://www.advogato.org/article/949.html . This is certainly a reasonable point, however, an external module should never prescribe how important corrupted data is to the calling program (by exiting "for" them). The proper way to handle this is by throwing an exception that makes it clear that the program may now be in an inconsistent state. And since good programs mostly consist of modules (with a little glue code in the main executable), asserts are almost always the wrong thing to do.

So as language designers, they should rather see that proper error handling can be done with even lesser typing. Excluding assert because your exception mechanism is verbose is not the solution. Oh wait, Go doesn't have exceptions either. Too bad :)

I use asserts all the time in code and eventually replace them all when I write more code. I use them when I haven't written the logic required and want to be alerted when I run into the code instead of writing an exception which will be deleted as the project gets closer to completion.

Exceptions also blend in with production code more easily which I dislike. An assert is easier to notice than throw new Exception("Some generic msg or 'pretend i am an assert'");

I've recently started adding some asserts to my code, and this is how I've been doing it:

I mentally divide my code into boundary code and internal code. Boundary code is code that handles user input, reads files, and gets data from the network. In this code, I request input in a loop that only exits when input is valid (in the case of interactive user input), or throw exceptions in the case of unrecoverable file / network corrupt data.

Internal code is everything else. For instance, a function that sets a variable in my class might be defined as

This gives me two layers of checks. Anything where the data is determined at run-time always gets an exception or immediate error handling. However, that extra check in Class::f with the assert statement means that if some internal code ever calls Class::f, I still have a sanity check. My internal code might not pass a valid argument (because I may have calculated value from some complex series of functions), so I like having the assertion in the setting function to document that regardless of who is calling the function, value must not be greater than or equal to end.

This seems to fit into what I'm reading in a few places, that assertions should be impossible to violate in a well-functioning program, while exceptions should be for exceptional and erroneous cases that are still possible. Because in theory I'm validating all input, it should not be possible for my assertion to be triggered. If it is, my program is wrong.