add a always turn on "assert"

"assert" is good, but it is used as a guard frequently. We can make such usage legal by adding a new syntax: assert bool_expr, ExceptionType, True suggest reasons: 1) even "__debug__" turn off, assert is working assertion as guard. 2) to avoid boilerplate code I write code like this: if pred(....) or pred(....): raise ValueError('pred(....) or pred(....)') Simplifed: assert pred(...), ValueError, True # the above line will be printed when error. # I need not to copy the condition! 3) future: "assert bool_expr, ET, False" To aid static tool, like Proof System. Better document. For complicate algorithm, I actually add a invariant outline comment above every statement.

On Wed, Mar 01, 2017 at 10:44:22AM +0800, 语言破碎处 wrote:
"assert" is good, but it is used as a guard frequently.
Using assert as a guard is an abuse of assert. We should not encourage it. assert has many uses already, but runtime guards is not one of them: http://import-that.dreamwidth.org/676.html
We can make such usage legal by adding a new syntax: assert bool_expr, ExceptionType, True
What is the purpose of the constant True? Why is there no way to set the exception message? Of course assert-as-guard is possible, but why should we do that? There is already a perfectly good way of doing guards which is more general and more powerful than anything you can do with a single assert statement. if condition: if something(): raise TypeError("message") elif another(): raise ValueError(argument) else: raise RuntimeError("error...") How can you write that with your syntax? assert condition and something(), TypeError, True assert condition and another(), ValueError, True assert condition, RuntimeError, True Your syntax has much more boilerplate, it repeats itself, and you can't specify the error message.
This goes against the purpose of assert. The reason assert exists is so that it can be disabled according to __debug__.
What if the source code is not available? Then all you will see is a mystery ValueError, with no message, and no source. If the condition is long: # indent # indent # indent # indent assert (long_function_name(alpha, beta, gamma, delta) or another_function(a, b, c) == something(x, y , z) or some_condition), ValueError, True then all you will see if the assertion fails is something like: Traceback (most recent call last): or some_condition), ValueError, True ValueError It is better to be explicit about creating good, useful error messages, not to rely on Python printing the source code.
3) future: "assert bool_expr, ET, False" To aid static tool, like Proof System.
What does that mean? What is the purpose of the False? -- Steve

On Wed, Mar 01, 2017 at 10:44:22AM +0800, 语言破碎处 wrote:
"assert" is good, but it is used as a guard frequently.
Using assert as a guard is an abuse of assert. We should not encourage it. assert has many uses already, but runtime guards is not one of them: http://import-that.dreamwidth.org/676.html
We can make such usage legal by adding a new syntax: assert bool_expr, ExceptionType, True
What is the purpose of the constant True? Why is there no way to set the exception message? Of course assert-as-guard is possible, but why should we do that? There is already a perfectly good way of doing guards which is more general and more powerful than anything you can do with a single assert statement. if condition: if something(): raise TypeError("message") elif another(): raise ValueError(argument) else: raise RuntimeError("error...") How can you write that with your syntax? assert condition and something(), TypeError, True assert condition and another(), ValueError, True assert condition, RuntimeError, True Your syntax has much more boilerplate, it repeats itself, and you can't specify the error message.
This goes against the purpose of assert. The reason assert exists is so that it can be disabled according to __debug__.
What if the source code is not available? Then all you will see is a mystery ValueError, with no message, and no source. If the condition is long: # indent # indent # indent # indent assert (long_function_name(alpha, beta, gamma, delta) or another_function(a, b, c) == something(x, y , z) or some_condition), ValueError, True then all you will see if the assertion fails is something like: Traceback (most recent call last): or some_condition), ValueError, True ValueError It is better to be explicit about creating good, useful error messages, not to rely on Python printing the source code.
3) future: "assert bool_expr, ET, False" To aid static tool, like Proof System.
What does that mean? What is the purpose of the False? -- Steve
participants (2)
-
Steven D'Aprano
-
语言破碎处