There are a couple reasons.
If the function is used internally (e.g. without a message call), meaning a revert would undo the entire call, so you would just return if it failed or succeeded instead of failing the call.
Prior to the Byzantium hardfork, the only way to fail a call was by using an invalid opcode (the opcode 0xfe, INVALID, is the official byte for this) which ate all the gas sent to the call. If you returned true/false to indicate failure/success, you could instead control how much gas it ate. Now there is the REVERT opcode which undoes the message call but doesn't eat all the unused gas.
If the function is external only, e.g. #1 above doesn't apply to you, then you don't need to do this true/false anymore and you can just use the REVERT opcode (the "require" function in Solidity).
Realistically #1 shouldn't be an issue either because it's a good pattern to not have functions callable externally and internally, e.g. you should have external function withdraw
which calls the internal function _withdraw
, and other functions within the contract can call _withdraw
as well.