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 <[email protected]>:
> Hi Richard,
>
> > On Jan 28, 2016, at 2:15 PM, Richard Sargent <
> [email protected]> 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.
> >
>
>