I tried to experiment with such behavior a while ago.��

I added an opal compiler extension here:��http://smalltalkhub.com/mc/ClementBera/NeoCompiler/main . One needs to recompile the package after it is loaded as it uses a compiler extension.

The idea was to introduce [ "some code" ] Cvalue, with Cvalue a message evaluated at compilation time depending on a class-side setting.

I put examples in the package. This method:

example
^ [ Smalltalk vm class ] Cvalue �� ��

is compiled, depending on a class side setting, to:

example
^ VirtualMachine

or

example
�� �� �� ��^ Smalltalk vm class

I could have added similar things for assert: and maybe add the C++ IFDEF macro, but in the end I don't think this is a good idea in a Smalltalk system. The code becomes hard to read or you have to extend a lot Smalltalk (extend the syntax, etc.).

If one really wants to do that, he can write it in his own DSL that compiles to Smalltalk. It is way easier and does not pollute the base Smalltalk. The user-designed compilation could happen with RB AST transformations, and honestly this is not very difficult and a good developer could do it without too many troubles.



2016-01-29 2:12 GMT+01:00 Eliot Miranda <eliot.miranda@gmail.com>:
Hi Richard,

> On Jan 28, 2016, at 2:15 PM, Richard Sargent <richard.sargent@gemtalksystems.com> wrote:
>
> Aliaksei Syrel wrote
>> Hi
>>
>> Assertions play an important role in design by contract. It is great to
>> have assertions in Pharo out of box (Object>>#assert:). However in
>> projects
>> with many post- and precondition as also class invariants heavy usage of
>> assertions decreases performance...
>>
>> Would it be possible to have a compiler setting (in setting browser) to
>> enable/disable assertions and not compile them to bytecode? Compiler
>> should
>> ignore the whole assertion statement with removed condition. For example:
>>
>>> self assert: self hugeInvariant.
>>
>> with disabled assertion hugeInvariant must not be sent.
>>
>> Thanks,
>> Alex
>
> My concern with this is that this proposal requires certain selectors to
> become /reserved/. Most SUnit variations that I have seen entail several
> dozen methods for asserting and denying behaviours, block evaluation versus
> inline expressions, descriptive explanations, and so on.
>
> It seems to me that you would be better off sending messages to a global.
> Instead of:
>> self assert: self hugeInvariant.
> have something like:
>> Assert that: self hugeInvariant.
>
> If the global Assert is bound to a stub the message is sent and ignored. If
> bound to a real assertion mechanism, it gets evaluated. Use blocks when the
> argument evaluation is expensive or expensive enough.
>> Assert evaluationOf: [self hugeInvariant].
>
> None of the names should be taken as suggestions. Just the concept.

It's a good concept, and is the object-oriented approach.�� It's just that in practice the costs of creating blocks as assert: arguments, while typically much cheaper than evaluating the assert and discarding its result, are still significant

Hence I'm open to a compiler hack that elides the assert: or deny: and it's send altogether from the code.�� Open but not happy; it's something I hold my nose to do.�� But this is a style I've been using for twenty odd years and it is really nice to be able to write assert-laden code but not have to pay in production.

There is a ray of hope.�� The Sista adaptive optimiser /will/ be able to elide all the cost of the block form:

�� �� ...
�� �� self assert: [self expr].
�� �� ...

Foo methods for assertions
assert: aBlockOrBoolean
�� �� �� ��^self

because there are obviously no side effects.�� Whereas it will only be able to elide the entire thing depending on expr in the non-block form:

�� �� ...
�� �� self assert: self expr.
�� �� ...

But I wonder how any people would have the discipline or insight to use the block form.�� It looks unnecessarily verbose yes?

> This also offers the benefit that assertions are practical everywhere, not
> just under a TestCase hierarchy.

Whether asserts are practicable everywhere IME depend on how useful they are in ongoing development.�� The fact that they cost a /lot/ and slow down the VM simulator for Cog doesn't change the fact that it would be much much slower to modify the code base.

In another thread I was proposing to Gulle to use the VM simulator instead of a custom VM for his Pharo bootstrap.�� But in that case one would /have/ to find a way of eliding asserts.�� One approach would be a package-level rewrite tool that could produce a copy of a package in which asserts have been eliminated.�� One would always do development in the assert-laden version, but could make the assert-less version available to clients who treat the package as a black box, can therefore assume that no asserts ever fail (because the asserts prove they don't) and use as high-performance a version of the package as possible.

With this approach there are no hacks in the compiler, although a derivative of the compiler might be a workhorse in the rewrite from assertful to assertless code.�� And the Monticello tools (& Metacello) could help automate things.


> A second order effect is you aren't playing with the compiler to turn it on
> and off, nor to extend the controlled API.


> --
> View this message in context: http://forum.world.st/Disable-assertions-design-by-contract-tp4874499p4874621.html
> Sent from the Pharo Smalltalk Developers mailing list archive at Nabble.com.
>