Re: assert and enforce both compiled out with -release

2018-01-28 Thread Ali Çehreli via Digitalmars-d-learn

On 01/28/2018 11:31 AM, Steven Schveighoffer wrote:

>> Fixed it through the "Improve this page" link on that Phobos page:
>>
>>https://github.com/dlang/phobos/blob/master/std/exception.d
>>
>> Ali
>
> Hm... it appears that you committed directly to the branch. Even if
> changing docs, you should do so with a pull request.
>
> For normal mortals, this happens automatically, but for people who have
> commit rights, you have to be careful to select the right thing ;)
>
> -Steve

Guilty as charged! Seb has already brought me to my senses by email.

Ali



Re: assert and enforce both compiled out with -release

2018-01-28 Thread Steven Schveighoffer via Digitalmars-d-learn

On 1/27/18 9:31 AM, Ali Çehreli wrote:

On 01/27/2018 05:52 AM, kdevel wrote:
 > https://dlang.org/phobos/std_exception.html#enforce states:
 >
 > | Also, do not use enforce inside of contracts (i.e. inside of in and
 > out blocks
 > | and invariants), because they will be compiled out when compiling with
 > -release.
 > | Use assert in contracts.
 >
 > But assert is also ignored in release mode:

The documentation is not clear. "they will be compiled out" means 
"contracts are compiled out". So, an enforce() would disappear if it's 
inside such a block, which should not be what the programmer wants for 
an enforce().


There is another problem with using enforce in contracts, it throws 
Exceptions, whereas contracts are expected to throw Errors. The most 
important aspect about this is that nothrow functions can still throw 
Errors. So if you have a nothrow function with an in-contract that 
throws an Exception, compiling in release mode may is a mistake (I'm not 
sure if the compiler even detects this).


I think the current docs (as they have been modified) are fine.


Fixed it through the "Improve this page" link on that Phobos page:

   https://github.com/dlang/phobos/blob/master/std/exception.d

Ali


Hm... it appears that you committed directly to the branch. Even if 
changing docs, you should do so with a pull request.


For normal mortals, this happens automatically, but for people who have 
commit rights, you have to be careful to select the right thing ;)


-Steve


Re: assert and enforce both compiled out with -release

2018-01-28 Thread rjframe via Digitalmars-d-learn
On Sun, 28 Jan 2018 00:59:12 +, lobo wrote:

> On Saturday, 27 January 2018 at 22:53:37 UTC, Ali Çehreli wrote:
>> On 01/27/2018 10:33 AM, kdevel wrote:
>>
>>> I suggest the deletion of the sentence "Use assert in contracts."
>>
>> Done.
>>
>> Ali
> 
> Wait, no this isn't right, is it? Enforce should not be used in
> contracts so the "Use assert in contracts" statement is correct and
> should remain. I think the issue here is the OP is getting confused
> between assert vs. exception.

Without that statement, the documentation is still pretty clear that you 
shouldn't use enforce in contracts, so removing it won't hurt anything, 
and does make things clearer by staying on-topic.


Re: assert and enforce both compiled out with -release

2018-01-27 Thread Ali Çehreli via Digitalmars-d-learn

On 01/27/2018 04:59 PM, lobo wrote:
> On Saturday, 27 January 2018 at 22:53:37 UTC, Ali Çehreli wrote:
>> On 01/27/2018 10:33 AM, kdevel wrote:
>>
>>> I suggest the deletion of the sentence "Use assert in contracts."
>>
>> Done.
>>
>> Ali
>
> Wait, no this isn't right, is it?

It is right because that statement made one person to replace 'enforce's 
with 'asserts's.


> Enforce should not be used in
> contracts so the "Use assert in contracts" statement is correct and
> should remain.

I don't think enforce documentation is the right place to get into such 
matters. Warning against a potential misuse is fine but hinting at 
"correct use of assert vs. enforce" is not only distracting but also 
misguiding.


> I think the issue here is the OP is getting confused
> between assert vs. exception.
>
> Contracts (in D) are used to define and assert the agreed logic
> behaviour of the program code.
>
> Asserts catch logic bugs in the code that may lead to incorrect
> behaviour at runtime. Exceptions are for exceptional cases that crop up
> at runtime due to factors external to the code logic, e.g. invalid
> external state such as failing to open a file or a sensor not going off
> when it should because it is faulty.
>
> Asserts can be removed in -release code because it is assumed the logic
> has been asserted correct during debug builds and testing. The same
> reason compilers now are starting to optimise out code based on assert
> conditions.
>
> bye,
> lobo

All true.

Ali



Re: assert and enforce both compiled out with -release

2018-01-27 Thread lobo via Digitalmars-d-learn

On Saturday, 27 January 2018 at 22:53:37 UTC, Ali Çehreli wrote:

On 01/27/2018 10:33 AM, kdevel wrote:

I suggest the deletion of the sentence "Use assert in 
contracts."


Done.

Ali


Wait, no this isn't right, is it? Enforce should not be used in 
contracts so the "Use assert in contracts" statement is correct 
and should remain. I think the issue here is the OP is getting 
confused between assert vs. exception.


Contracts (in D) are used to define and assert the agreed logic 
behaviour of the program code.


Asserts catch logic bugs in the code that may lead to incorrect 
behaviour at runtime. Exceptions are for exceptional cases that 
crop up at runtime due to factors external to the code logic, 
e.g. invalid external state such as failing to open a file or a 
sensor not going off when it should because it is faulty.


Asserts can be removed in -release code because it is assumed the 
logic has been asserted correct during debug builds and testing. 
The same reason compilers now are starting to optimise out code 
based on assert conditions.


bye,
lobo


Re: assert and enforce both compiled out with -release

2018-01-27 Thread Ali Çehreli via Digitalmars-d-learn

On 01/27/2018 10:33 AM, kdevel wrote:


I suggest the deletion of the sentence "Use assert in contracts."


Done.

Ali



Re: assert and enforce both compiled out with -release

2018-01-27 Thread kdevel via Digitalmars-d-learn

On Saturday, 27 January 2018 at 18:00:32 UTC, rjframe wrote:
I think I see what you mean; you interpret "use asserts, 
because enforce will be compiled out" to imply that asserts 
wouldn't be compiled out, correct?


Is there any other meaningful interpretation?

Since, in reality, both would be compiled out, it shouldn't 
matter what you use, so the docs shouldn't care. That makes 
sense.


That's precisely my point.

The documentation seems to assume the reader has certain 
expectations of assert and enforce[0], so each function 
expresses a different intention to the programmer; when I see 
`assert()` I expect those checks only in non- release mode; 
when I see `enforce()` I expect those checks regardless of the 
flags that have been set[1]. Placing `enforce` in a contract 
messes with that expectation.


Right.

What language here would make more sense to you? Anything I can 
come up with is either awkward or pretty verbose.


I suggest the deletion of the sentence "Use assert in contracts."



Re: assert and enforce both compiled out with -release

2018-01-27 Thread Jonathan M Davis via Digitalmars-d-learn
On Saturday, January 27, 2018 17:12:25 kdevel via Digitalmars-d-learn wrote:
> Then please explain to me, in which respect the advice to "Use
> assert[s] in contracs" makes sense if the contracts are to be
> compiled out. I don't get it.

The entire point of contracts is to be asserting pre or post conditions. In
some cases, there really isn't much difference between putting the
assertion in the contract from putting it in the body. e.g.

void foo(int i)
in
{
assert(i > 42);
}
do
{
}

and

void foo(int i)
{
assert(i > 42);
}

are pretty much the same, but it can matter. e.g. you can have additional
lines of code in a contract that can't go in a assertion:

void foo(C c, D d, int i)
in
{
auto c = c.foo();
sort(c);
assert(d.bar(i) == c);
}
do
{
}

To do that in the function body, you'd either have to make it a single
expression (which in some cases is easy, and other cases can't be done), or
turn it into a function call where the result of the call gets asserted.
That particular example necessarily isn't a huge motivator for contracts,
but it can be useful.

It's more useful with out contracts, because then you can have have the
assertion in one place rather than with each return statement. e.g.

auto foo(T t)
out(retval)
{
assert(retval.foo() > 19);
}
do
{
if(blah)
return baz();
...
if(t.s == "str")
return doSomething();
...
return t.xyzzy();
}

However, where contracts really matter is with classes. In order for
contracts to work properly with inheritance when a function is overridden,
the in contract of a derived class cannot be more restrictive than that of
the base class. Otherwise, you wouldn't be able to call a function on base
class reference without caring what the actual class of the object was,
because you'd end up with contracts failing based on what the derived class
was. However, while the in contract for a derived function can't be made
stricter, it _can_ be made looser, since that wouldn't make any code fail
based on what the actual object type was, and there's no reason why the
derived class function couldn't work with a greater range of values than the
base class function.

Similarly, a derived function cannot have a looser out contract than the one
in the base class, because that would violate the guarantees that the base
class function makes. However, the derived function _can_ have a stricter
contract, because that doesn't violate the guarantees of the base class, and
there's no reason not to allow the derived class to be stricter about what
it outputs.

As such, with derived functions, the runtime effecively ||s all in
countracts and & all out contracts. In an inheritance chain, _one_ of the
in contracts needs to pass without throwing an AssertError, whereas none of
the out contracts can fail with an AssertError.

So, if you put an assertion in the in contract of a virtual function,
whether it actually has to pass or not depends on what the in contracts of
the other functions in the inheritance chain are, whereas if you put the
assertion in the function body, it always has to pass when that function is
run. However, if that function isn't run (e.g. a derived class function
doesn't call the base class function), then that assertion is never run,
whereas if it's in the in contract, it will be run so long as another in
contract hasn't already passed.

And if you put an assertion in the out contract of a virtual function, it
will always be run, regardless of whether a derived class function calls a
base class function. The only case where it wouldn't be run is if another
out contract had already failed (in which case, the AssertError killed your
program). But if you put the assertion in the function body, it will only be
run if that particular function is run (which may not happen if the derived
class function don't call the base class function).

So, the use of contracts can make a significant difference if you're dealing
with classes, but their benefits are pretty superficial outside of classes.

invariants are far more useful in that they run before and after every
public function call. So, you can assert the state of the object in one
place, and it gets tested whenever the public API is used.

Personally, I almost never use contracts. I rarely use classes, so the
benefits that contracts provide in that case would rarely help me, and in
other cases, I don't think that they provide enough value to bother. For in
contracts, you can just as easily put the assertion in the function unless
you need additional statements to prepare the condition to assert (which I
usually don't), and the contract syntax is verbose enough that I'd prefer to
not use it if I don't have to.

As for out contracts, I don't bother, because I find that it's rare that I
have a function where I can have a condition which is generically testable.
It's very common to be able to test that specific input gives specific
output but not that all output passes a 

Re: assert and enforce both compiled out with -release

2018-01-27 Thread rjframe via Digitalmars-d-learn
On Sat, 27 Jan 2018 17:12:25 +, kdevel wrote:

 
> This is not a problem, because this is perfectly legal. The problem is
> the wording of this phrase on the docs:
> 
> | Also, do not use enforce inside of contracts (i.e. inside of in and
> out blocks | and invariants), because they will be compiled out when
> compiling with | -release. Use assert in contracts.
> 
> Using assert *IN* contracts in -release mode is equally pointless.

...
 
> | Also, do not use enforce inside of contracts (i.e. inside of in and
> out blocks | and invariants), because they will be compiled out when
> compiling with | -release. Use assert in contracts.
> 
> to me. IMHO this advice is pointless.

...
 
> Then please explain to me, in which respect the advice to "Use assert[s]
> in contracs" makes sense if the contracts are to be compiled out. I
> don't get it.

I think I see what you mean; you interpret "use asserts, because enforce 
will be compiled out" to imply that asserts wouldn't be compiled out, 
correct? Since, in reality, both would be compiled out, it shouldn't 
matter what you use, so the docs shouldn't care. That makes sense.

The documentation seems to assume the reader has certain expectations of 
assert and enforce[0], so each function expresses a different intention to 
the programmer; when I see `assert()` I expect those checks only in non-
release mode; when I see `enforce()` I expect those checks regardless of 
the flags that have been set[1]. Placing `enforce` in a contract messes 
with that expectation.

What language here would make more sense to you? Anything I can come up 
with is either awkward or pretty verbose.

--Ryan


[0]: The correct expectation, but that's not necessarily important when 
it's not explicitly described.
[1]: So you can use enforce to validate user input, but never assert.


Re: assert and enforce both compiled out with -release

2018-01-27 Thread kdevel via Digitalmars-d-learn
On Saturday, 27 January 2018 at 16:19:30 UTC, Jonathan M Davis 
wrote:
On Saturday, January 27, 2018 14:59:50 kdevel via 
Digitalmars-d-learn wrote:

>>> https://github.com/dlang/phobos/blob/master/std/exception.d
>>
>> "Use $(D assert) in contracts." is still in there.
>
> What's wrong with that? What documentation is trying to say 
> is "do not use enforce in contracts; use assert in 
> contracts" and that's exactly the idea.


I can't see a problem which would be solved by following this 
advice. It distracts the reader (me) from gettin his (my) work 
done. If I compile not for release both, enforce and assert, 
are in effect. If I compile for release both, enforce and 
assert, are disabled. So by replacing enforce with assert I 
gain nothing.


No, enforce is _not_ disabled with -release. e.g.


That's not my point.


void foo(int i)
{
enforce(i > 42);
}

void main()
{
foo(0);
}


This is a different case.

will throw an exception even when you compile with -release. 
The problem is that you're using enforce inside a contract 
instead of inside the function's body.


This is not a problem, because this is perfectly legal. The 
problem is the wording of this phrase on the docs:


| Also, do not use enforce inside of contracts (i.e. inside of in 
and out blocks
| and invariants), because they will be compiled out when 
compiling with

| -release. Use assert in contracts.

Using assert *IN* contracts in -release mode is equally pointless.

Contracts are specifically for asserting pre and post 
conditions. It is expected that they only be used for 
assertions or for code which is going to be run in preparation 
for running an assertion. They are _not_ for code which is 
intended to be part of the final program, and they are compiled 
out with -release, just like assertions are compiled out 
elsewhere in the code. As such, any code in a contract - be it 
an assertion, a call to enforce, or any arbitarily complex 
piece of code - will not be in the final program.


Then please explain the meaning of the sentence

 Use assert in contracts.

in this context:

| Also, do not use enforce inside of contracts (i.e. inside of in 
and out blocks
| and invariants), because they will be compiled out when 
compiling with

| -release. Use assert in contracts.

to me. IMHO this advice is pointless.

Anything that you want in your final program should not be in a 
contract. If you want to use exceptions - be it with enforce or 
with an if statement and explicitly throwing - then don't put 
them in any contracts. They _will_ get compiled out. As such, 
it makes no sense to use enforce in a contract. It should go in 
the function body.


Then please explain to me, in which respect the advice to "Use 
assert[s] in contracs" makes sense if the contracts are to be 
compiled out. I don't get it.




Re: assert and enforce both compiled out with -release

2018-01-27 Thread Jonathan M Davis via Digitalmars-d-learn
On Saturday, January 27, 2018 14:59:50 kdevel via Digitalmars-d-learn wrote:
> On Saturday, 27 January 2018 at 14:51:23 UTC, Ali Çehreli wrote:
> > On 01/27/2018 06:36 AM, kdevel wrote:
> >> On Saturday, 27 January 2018 at 14:31:13 UTC, Ali Çehreli
> >>
> >> wrote:
> >>> > But assert is also ignored in release mode:
> >>> The documentation is not clear. "they will be compiled out"
> >>> means "contracts are compiled out". So, an enforce() would
> >>> disappear if it's inside such a block, which should not be
> >>> what the programmer wants for an enforce().
> >>
> >> The documentation was clear as glass (but wrong): "Use assert
> >> in contracts."
> >>
> >>> Fixed it through the "Improve this page" link on that Phobos
> >>> page:
> >>>
> >>>   https://github.com/dlang/phobos/blob/master/std/exception.d
> >>
> >> "Use $(D assert) in contracts." is still in there.
> >
> > What's wrong with that? What documentation is trying to say is
> > "do not use enforce in contracts; use assert in contracts" and
> > that's exactly the idea.
>
> I can't see a problem which would be solved by following this
> advice. It distracts the reader (me) from gettin his (my) work
> done. If I compile not for release both, enforce and assert, are
> in effect. If I compile for release both, enforce and assert, are
> disabled. So by replacing enforce with assert I gain nothing.

No, enforce is _not_ disabled with -release. e.g.

void foo(int i)
{
enforce(i > 42);
}

void main()
{
foo(0);
}

will throw an exception even when you compile with -release. The problem is
that you're using enforce inside a contract instead of inside the function's
body.

Contracts are specifically for asserting pre and post conditions. It is
expected that they only be used for assertions or for code which is going to
be run in preparation for running an assertion. They are _not_ for code
which is intended to be part of the final program, and they are compiled out
with -release, just like assertions are compiled out elsewhere in the code.
As such, any code in a contract - be it an assertion, a call to enforce, or
any arbitarily complex piece of code - will not be in the final program.

Anything that you want in your final program should not be in a contract. If
you want to use exceptions - be it with enforce or with an if statement and
explicitly throwing - then don't put them in any contracts. They _will_ get
compiled out. As such, it makes no sense to use enforce in a contract. It
should go in the function body.

- Jonathan M Davis




Re: assert and enforce both compiled out with -release

2018-01-27 Thread kdevel via Digitalmars-d-learn

On Saturday, 27 January 2018 at 14:51:23 UTC, Ali Çehreli wrote:

On 01/27/2018 06:36 AM, kdevel wrote:
On Saturday, 27 January 2018 at 14:31:13 UTC, Ali Çehreli 
wrote:

> But assert is also ignored in release mode:

The documentation is not clear. "they will be compiled out" 
means "contracts are compiled out". So, an enforce() would 
disappear if it's inside such a block, which should not be 
what the programmer wants for an enforce().


The documentation was clear as glass (but wrong): "Use assert 
in contracts."


Fixed it through the "Improve this page" link on that Phobos 
page:


  https://github.com/dlang/phobos/blob/master/std/exception.d


"Use $(D assert) in contracts." is still in there.


What's wrong with that? What documentation is trying to say is 
"do not use enforce in contracts; use assert in contracts" and 
that's exactly the idea.


I can't see a problem which would be solved by following this 
advice. It distracts the reader (me) from gettin his (my) work 
done. If I compile not for release both, enforce and assert, are 
in effect. If I compile for release both, enforce and assert, are 
disabled. So by replacing enforce with assert I gain nothing.


Re: assert and enforce both compiled out with -release

2018-01-27 Thread Ali Çehreli via Digitalmars-d-learn

On 01/27/2018 06:36 AM, kdevel wrote:

On Saturday, 27 January 2018 at 14:31:13 UTC, Ali Çehreli wrote:

> But assert is also ignored in release mode:

The documentation is not clear. "they will be compiled out" means 
"contracts are compiled out". So, an enforce() would disappear if it's 
inside such a block, which should not be what the programmer wants for 
an enforce().


The documentation was clear as glass (but wrong): "Use assert in 
contracts."



Fixed it through the "Improve this page" link on that Phobos page:

  https://github.com/dlang/phobos/blob/master/std/exception.d


"Use $(D assert) in contracts." is still in there.


What's wrong with that? What documentation is trying to say is "do not 
use enforce in contracts; use assert in contracts" and that's exactly 
the idea.


Ali


Re: assert and enforce both compiled out with -release

2018-01-27 Thread kdevel via Digitalmars-d-learn

On Saturday, 27 January 2018 at 14:31:13 UTC, Ali Çehreli wrote:

> But assert is also ignored in release mode:

The documentation is not clear. "they will be compiled out" 
means "contracts are compiled out". So, an enforce() would 
disappear if it's inside such a block, which should not be what 
the programmer wants for an enforce().


The documentation was clear as glass (but wrong): "Use assert in 
contracts."


Fixed it through the "Improve this page" link on that Phobos 
page:


  https://github.com/dlang/phobos/blob/master/std/exception.d


"Use $(D assert) in contracts." is still in there.


Re: assert and enforce both compiled out with -release

2018-01-27 Thread Ali Çehreli via Digitalmars-d-learn

On 01/27/2018 05:52 AM, kdevel wrote:
> https://dlang.org/phobos/std_exception.html#enforce states:
>
> | Also, do not use enforce inside of contracts (i.e. inside of in and
> out blocks
> | and invariants), because they will be compiled out when compiling with
> -release.
> | Use assert in contracts.
>
> But assert is also ignored in release mode:

The documentation is not clear. "they will be compiled out" means 
"contracts are compiled out". So, an enforce() would disappear if it's 
inside such a block, which should not be what the programmer wants for 
an enforce().


Fixed it through the "Improve this page" link on that Phobos page:

  https://github.com/dlang/phobos/blob/master/std/exception.d

Ali



Re: assert and enforce both compiled out with -release

2018-01-27 Thread rjframe via Digitalmars-d-learn
On Sat, 27 Jan 2018 13:52:47 +, kdevel wrote:

> https://dlang.org/phobos/std_exception.html#enforce states:
> 
> | Also, do not use enforce inside of contracts (i.e. inside of in and
> out blocks | and invariants), because they will be compiled out when
> compiling with -release.
> | Use assert in contracts.
> 
> But assert is also ignored in release mode:
> 

enforce is a wrapper around try/catch (I don't know if that's technically 
true, but it is pragmatically true); assert is a debug tool. Contracts and 
assertions are removed for release builds, which means if you place an 
enforce in a contract, it's removed - but the same enforce placed in the 
function body would remain. You don't want the enforce stripped from the 
exe (if you are OK with that, it should be an assertion), so it shouldn't 
be in the contract.

Use assertions to catch programming bugs, and enforce or try/catch for 
exceptions.

If DIP 1006[0] is accepted, we'll have greater control over the removal of 
asserts and contracts in release mode.


[0]: https://github.com/dlang/DIPs/blob/master/DIPs/DIP1006.md


assert and enforce both compiled out with -release

2018-01-27 Thread kdevel via Digitalmars-d-learn

https://dlang.org/phobos/std_exception.html#enforce states:

| Also, do not use enforce inside of contracts (i.e. inside of in 
and out blocks
| and invariants), because they will be compiled out when 
compiling with -release.

| Use assert in contracts.

But assert is also ignored in release mode:

ass.d
---
void foo (int i)
in {
   assert (i < 0);
}
body {
}

void main ()
{
   foo (1);
}
---

$ dmd ass
$ ./ass
core.exception.AssertError@ass.d(3): Assertion failure

??:? _d_assertp [0x42a065]
??:? void ass.foo(int) [0x429f9d]
??:? _Dmain [0x429fad]

$ dmd -release ass
$ ./ass
[nothing]



Re: Confusion over enforce and assert - both are compiled out in release mode

2017-08-27 Thread Moritz Maxeiner via Digitalmars-d-learn

On Sunday, 27 August 2017 at 10:46:53 UTC, Andrew Chapman wrote:

[...]

Oh interesting.  Does DUB support passing through the 
--enable-contracts flag to ldc?  Also, if this is an ldc 
specific thing it's probably not a good idea i'd imagine, since 
in the future one may want to use a GDC, or DMD?


Also, with regards to gdc, its release mode `-frelease` option is 
explicitly specified in the manual as being shorthand for a 
specific set of options:



This is equivalent to compiling with the following options:

gdc -fno-assert -fbounds-check=safe -fno-invariants \
-fno-postconditions -fno-preconditions -fno-switch-errors


As it doesn't seem to turn on/off any other options / 
optimizations, you can use `"dflags-gdc": [...]` to specify your 
own set of "release" options without losing anything.
In particular, I would overwrite dub's default "release" build 
type [1] and add your own per compiler build settings, so dub 
won't pass `-frelease` to gdc when using `dub --build=release`.


[1] https://code.dlang.org/package-format?lang=json#build-types


Re: Confusion over enforce and assert - both are compiled out in release mode

2017-08-27 Thread Moritz Maxeiner via Digitalmars-d-learn

On Sunday, 27 August 2017 at 10:46:53 UTC, Andrew Chapman wrote:
On Sunday, 27 August 2017 at 10:37:50 UTC, Moritz Maxeiner 
wrote:

[...]


Oh interesting.  Does DUB support passing through the 
--enable-contracts flag to ldc?


Sure, using platform specific build settings [1] such as 
`"dflags-ldc": ["--enable-contracts"]`.


Also, if this is an ldc specific thing it's probably not a good 
idea i'd imagine, since in the future one may want to use a 
GDC, or DMD?


If you want to use another compiler that supports it, add the 
appropriate "dflags-COMPILER" setting to your package file.
With regards to dmd: Don't use it for release builds, use gdc or 
ldc (better optimizations).


https://code.dlang.org/package-format?lang=json#build-settings


Re: Confusion over enforce and assert - both are compiled out in release mode

2017-08-27 Thread Andrew Chapman via Digitalmars-d-learn

On Sunday, 27 August 2017 at 10:37:50 UTC, Moritz Maxeiner wrote:

On Sunday, 27 August 2017 at 10:17:47 UTC, Andrew Chapman wrote:

On Sunday, 27 August 2017 at 10:08:15 UTC, ag0aep6g wrote:

[...]


Thanks, that explains it.  I think it's a bit of a shame that 
the "in" blocks can't be used in release mode as the clarity 
they provide for precondition logic is wonderful.


If you need that, you could compile using ldc in release mode 
(which you probably want to do anyway):


--- test.d ---
import std.exception;
import std.stdio;

void foo(int x) in { enforce(x > 0); } body
{

}

void bar(int x) in { assert(x > 0); } body
{

}

void baz(int x) in { if (!(x > 0)) assert(0); } body
{

}

void main()
{
(-1).foo.assertThrown;
(-1).bar;
(-1).baz;
}
--

$ ldc2 test.d
-> failed assert in bar's in contract terminates the program

$ ldc2 -release test.d
-> failed assertThrown in main terminates the program

$ ldc2 -release -enable-contracts test.d
-> failed assert in baz's in contract terminates the program

$ ldc2 -release -enable-contracts -enable-asserts test.d
-> failed assert in bar's in contract terminates the program


Oh interesting.  Does DUB support passing through the 
--enable-contracts flag to ldc?  Also, if this is an ldc specific 
thing it's probably not a good idea i'd imagine, since in the 
future one may want to use a GDC, or DMD?


Re: Confusion over enforce and assert - both are compiled out in release mode

2017-08-27 Thread Moritz Maxeiner via Digitalmars-d-learn

On Sunday, 27 August 2017 at 10:17:47 UTC, Andrew Chapman wrote:

On Sunday, 27 August 2017 at 10:08:15 UTC, ag0aep6g wrote:

On 08/27/2017 12:02 PM, Andrew Chapman wrote:
However, I am finding that BOTH enforce and assert are 
compiled out by dmd and ldc in release mode.  Is there a 
standard way of doing what enforce does inside an "in" 
contract block that will work in release mode?


I'm guessing I should write my own function for now.
The whole `in` block is ignored in release mode. Doesn't 
matter what you put in there. Nothing of it will be compiled.


Thanks, that explains it.  I think it's a bit of a shame that 
the "in" blocks can't be used in release mode as the clarity 
they provide for precondition logic is wonderful.


If you need that, you could compile using ldc in release mode 
(which you probably want to do anyway):


--- test.d ---
import std.exception;
import std.stdio;

void foo(int x) in { enforce(x > 0); } body
{

}

void bar(int x) in { assert(x > 0); } body
{

}

void baz(int x) in { if (!(x > 0)) assert(0); } body
{

}

void main()
{
(-1).foo.assertThrown;
(-1).bar;
(-1).baz;
}
--

$ ldc2 test.d
-> failed assert in bar's in contract terminates the program

$ ldc2 -release test.d
-> failed assertThrown in main terminates the program

$ ldc2 -release -enable-contracts test.d
-> failed assert in baz's in contract terminates the program

$ ldc2 -release -enable-contracts -enable-asserts test.d
-> failed assert in bar's in contract terminates the program


Re: Confusion over enforce and assert - both are compiled out in release mode

2017-08-27 Thread Andrew Chapman via Digitalmars-d-learn

On Sunday, 27 August 2017 at 10:08:15 UTC, ag0aep6g wrote:

On 08/27/2017 12:02 PM, Andrew Chapman wrote:
However, I am finding that BOTH enforce and assert are 
compiled out by dmd and ldc in release mode.  Is there a 
standard way of doing what enforce does inside an "in" 
contract block that will work in release mode?


I'm guessing I should write my own function for now.
The whole `in` block is ignored in release mode. Doesn't matter 
what you put in there. Nothing of it will be compiled.


Thanks, that explains it.  I think it's a bit of a shame that the 
"in" blocks can't be used in release mode as the clarity they 
provide for precondition logic is wonderful.


Re: Confusion over enforce and assert - both are compiled out in release mode

2017-08-27 Thread ag0aep6g via Digitalmars-d-learn

On 08/27/2017 12:02 PM, Andrew Chapman wrote:
However, I am finding that BOTH enforce and assert are compiled out by 
dmd and ldc in release mode.  Is there a standard way of doing what 
enforce does inside an "in" contract block that will work in release mode?


I'm guessing I should write my own function for now.
The whole `in` block is ignored in release mode. Doesn't matter what you 
put in there. Nothing of it will be compiled.


Confusion over enforce and assert - both are compiled out in release mode

2017-08-27 Thread Andrew Chapman via Digitalmars-d-learn
In the docs regarding contract programming and the use of enforce 
/ assert:

https://dlang.org/library/std/exception/enforce.html

it says:

"enforce is used to throw exceptions and is therefore intended to 
aid in error handling. It is not intended for verifying the logic 
of your program. That is what assert is for. Also, do not use 
enforce inside of contracts (i.e. inside of in and out blocks and 
invariants), because they will be compiled out when compiling 
with -release. Use assert in contracts."


However, I am finding that BOTH enforce and assert are compiled 
out by dmd and ldc in release mode.  Is there a standard way of 
doing what enforce does inside an "in" contract block that will 
work in release mode?


I'm guessing I should write my own function for now.


Re: in/out with -release

2011-03-07 Thread Kai Meyer

On 03/05/2011 11:14 AM, Lars T. Kyllingstad wrote:

On Sat, 05 Mar 2011 18:12:30 +, Lars T. Kyllingstad wrote:


On Sat, 05 Mar 2011 10:15:48 -0700, user wrote:


On 03/04/2011 09:22 PM, Jonathan M Davis wrote:

On Friday 04 March 2011 20:14:32 Kai Meyer wrote:

I have an 'enforce' function call in an 'in' block for a function.
When I compile with -release -O -inline, the in/out blocks appear
to be skipped. It's a simple verification for a dynamic array to not
have a length of 0. In debug mode, the test condition hits the
enforce in the 'in' block, but in release mode it does not. In both
release and debug mode, the same exact enforce function works
properly.

So am I to understand that -release will skip in/out blocks entirely?


Of course. It uses asserts. asserts are disabled in -release. Asserts
are for debugging, testing, and verifying code when developing, not
for code which is released. So, you get the benefit of the test when
you don't have -release and the benefit of speed when you do have
-release. If an assertion fails, your code logic is invalid. It's for
validating your code, not user input or whatnot.

enforce, on the other hand, is not a language primitive. It's not
intended for testing or debugging. It's intended to be used in
production code to throw an exception when its condition fails. If an
enforce fails, that generally means that you had bad input somewhere
or that an operation failed or whatnot. It's not intended for testing
the logic of your code like assert is intended to do. It's simply a
shorthand way to throw an exception when your program runs into a
problem.

- Jonathan M Davis


I don't think I understand your response entirely. I understand that
asserts are disabled in -release mode. I understand that enforce is a
function that comes with std.exception, and the code isn't hard to
follow.

What I'm confused about is the in block, and why it is skipped in
-release mode. You say It uses asserts. I didn't put an assert in my
in block, I put an enforce. So I'm guessing that you are indicating
that the in block is treated like an assert, and is disabled with the
-release flag.

But I think after reading your post you've helped clarify that what I'm
checking (that you can't pop an empty stack) based on user input is
something I should be checking with an enforce inside the function, and
not an assert or enforce inside the in block.

I still think I would like it if you could be a little more explicit
about the in/out blocks. Are they always disabled entirely (skipped)
with -release, or just certain things?

Thanks for your help!

-Kai Meyer


That's right.  in, out and invariant blocks are not included in release
mode.

-Lars


It's documented here, by the way:
http://www.digitalmars.com/d/2.0/dmd-linux.html#switches

(Scroll down to -release.)

-Lars


All very welcome responses. Thanks for your time :) Got lots of reading 
to do.


-Kai Meyer


Re: in/out with -release

2011-03-06 Thread Jesse Phillips
user@domain.invalid Wrote:

 I still think I would like it if you could be a little more explicit 
 about the in/out blocks. Are they always disabled entirely (skipped) 
 with -release, or just certain things?
 
 Thanks for your help!
 
 -Kai Meyer

By definition, if a pre contract fails, then the body received bad parameters. 
An AssertError is thrown. If a post contract fails, then there is a bug in the 
body. An AssertError is thrown. 

http://www.digitalmars.com/d/2.0/dbc.html


Re: in/out with -release

2011-03-05 Thread bearophile
Jonathan M Davis:

 Asserts are for 
 debugging, testing, and verifying code when developing, not for code which is 
 released.

If you take a look at the dmd compiler, it's released with asserts in, and they 
give all those nice error messages I put in Bugzilla :-)

Bye,
bearophile


Re: in/out with -release

2011-03-05 Thread spir

On 03/05/2011 01:58 PM, bearophile wrote:

Jonathan M Davis:


Asserts are for
debugging, testing, and verifying code when developing, not for code which is
released.


If you take a look at the dmd compiler, it's released with asserts in, and they 
give all those nice error messages I put in Bugzilla :-)


lol!
I have a similar problem in designing the implementation of a toy language: the 
issue is that users of the runtime are, for instance, lib developpers, which 
own users are developpers in the source language beeing implemented, for their 
own final users...
This makes it rather abstract to think at what is, or should be, the 
realisation of an error spit by the runtime. It cannot be a normal error from 
the implementation language, and also not an error of the source language. I 
had to write my own // error system.


Denis
--
_
vita es estrany
spir.wikidot.com



Re: in/out with -release

2011-03-05 Thread Andrej Mitrovic
On 3/5/11, bearophile bearophileh...@lycos.com wrote:
 Jonathan M Davis:

 Asserts are for
 debugging, testing, and verifying code when developing, not for code which
 is
 released.

 If you take a look at the dmd compiler, it's released with asserts in, and
 they give all those nice error messages I put in Bugzilla :-)

 Bye,
 bearophile


Hmm. Are those shown when compiling a file with -debug? Or do I need
to compile DMD itself in debug/nonrelease mode to activate those error
messages?


Re: in/out with -release

2011-03-05 Thread Lars T. Kyllingstad
On Sat, 05 Mar 2011 18:12:30 +, Lars T. Kyllingstad wrote:

 On Sat, 05 Mar 2011 10:15:48 -0700, user wrote:
 
 On 03/04/2011 09:22 PM, Jonathan M Davis wrote:
 On Friday 04 March 2011 20:14:32 Kai Meyer wrote:
 I have an 'enforce' function call in an 'in' block for a function.
 When I compile with -release -O -inline, the in/out blocks appear
 to be skipped. It's a simple verification for a dynamic array to not
 have a length of 0. In debug mode, the test condition hits the
 enforce in the 'in' block, but in release mode it does not. In both
 release and debug mode, the same exact enforce function works
 properly.

 So am I to understand that -release will skip in/out blocks entirely?

 Of course. It uses asserts. asserts are disabled in -release. Asserts
 are for debugging, testing, and verifying code when developing, not
 for code which is released. So, you get the benefit of the test when
 you don't have -release and the benefit of speed when you do have
 -release. If an assertion fails, your code logic is invalid. It's for
 validating your code, not user input or whatnot.

 enforce, on the other hand, is not a language primitive. It's not
 intended for testing or debugging. It's intended to be used in
 production code to throw an exception when its condition fails. If an
 enforce fails, that generally means that you had bad input somewhere
 or that an operation failed or whatnot. It's not intended for testing
 the logic of your code like assert is intended to do. It's simply a
 shorthand way to throw an exception when your program runs into a
 problem.

 - Jonathan M Davis
 
 I don't think I understand your response entirely. I understand that
 asserts are disabled in -release mode. I understand that enforce is a
 function that comes with std.exception, and the code isn't hard to
 follow.
 
 What I'm confused about is the in block, and why it is skipped in
 -release mode. You say It uses asserts. I didn't put an assert in my
 in block, I put an enforce. So I'm guessing that you are indicating
 that the in block is treated like an assert, and is disabled with the
 -release flag.
 
 But I think after reading your post you've helped clarify that what I'm
 checking (that you can't pop an empty stack) based on user input is
 something I should be checking with an enforce inside the function, and
 not an assert or enforce inside the in block.
 
 I still think I would like it if you could be a little more explicit
 about the in/out blocks. Are they always disabled entirely (skipped)
 with -release, or just certain things?
 
 Thanks for your help!
 
 -Kai Meyer
 
 That's right.  in, out and invariant blocks are not included in release
 mode.
 
 -Lars

It's documented here, by the way:
http://www.digitalmars.com/d/2.0/dmd-linux.html#switches

(Scroll down to -release.)

-Lars


Re: in/out with -release

2011-03-05 Thread Jonathan M Davis
On Saturday 05 March 2011 05:30:23 Andrej Mitrovic wrote:
 On 3/5/11, bearophile bearophileh...@lycos.com wrote:
  Jonathan M Davis:
  Asserts are for
  debugging, testing, and verifying code when developing, not for code
  which is
  released.
  
  If you take a look at the dmd compiler, it's released with asserts in,
  and they give all those nice error messages I put in Bugzilla :-)
  
  Bye,
  bearophile
 
 Hmm. Are those shown when compiling a file with -debug? Or do I need
 to compile DMD itself in debug/nonrelease mode to activate those error
 messages?

You would need to compile dmd in debug mode if you wanted it to have assertions 
enabled, the same as any other C or C++ program in existence. That's the way 
that C/C++'s assert library works.

- Jonathan M Davis


Re: in/out with -release

2011-03-05 Thread Jonathan M Davis
On Saturday 05 March 2011 13:54:08 Jonathan M Davis wrote:
 On Saturday 05 March 2011 05:30:23 Andrej Mitrovic wrote:
  On 3/5/11, bearophile bearophileh...@lycos.com wrote:
   Jonathan M Davis:
   Asserts are for
   debugging, testing, and verifying code when developing, not for code
   which is
   released.
   
   If you take a look at the dmd compiler, it's released with asserts in,
   and they give all those nice error messages I put in Bugzilla :-)
   
   Bye,
   bearophile
  
  Hmm. Are those shown when compiling a file with -debug? Or do I need
  to compile DMD itself in debug/nonrelease mode to activate those error
  messages?
 
 You would need to compile dmd in debug mode if you wanted it to have
 assertions enabled, the same as any other C or C++ program in existence.
 That's the way that C/C++'s assert library works.

Actually, I take that back. The way that C/C++'s assert library works is that 
assertions are compiled in if NDEBUG is _not_ defined. What the debug build 
of 
a project does is entirely up to the project. The concept of debug and release 
versions isn't really built in to the language per se. Normally, debug versions 
compile in the debug symbols and release versions do not, and release versions 
typically are set up such that they don't run unnecessary stuff which would 
harm 
efficiency (such as assertions). But _exactly_ how debug and release versions 
are 
set up depends on the project.

In the case of dmd, it may be that some assertions are left in on the theory 
that this it's _really_ critical code and you _still_ want it to fail 
immediately when an assertion would have failed (whereas more typically, you'd 
compile out the assertions in release mode, assuming that you'd done enough 
testing in debug mode to find and fix all the bugs that they relate to). But to 
know exactly what dmd does with assertions, you'd have to look at its makefiles 
and possibly the code itself.

- Jonathan M Davis


Re: in/out with -release

2011-03-05 Thread Jonathan M Davis
On Saturday 05 March 2011 09:15:48 user@domain.invalid wrote:
 On 03/04/2011 09:22 PM, Jonathan M Davis wrote:
  On Friday 04 March 2011 20:14:32 Kai Meyer wrote:
  I have an 'enforce' function call in an 'in' block for a function. When
  I compile with -release -O -inline, the in/out blocks appear to be
  skipped. It's a simple verification for a dynamic array to not have a
  length of 0. In debug mode, the test condition hits the enforce in the
  'in' block, but in release mode it does not. In both release and debug
  mode, the same exact enforce function works properly.
  
  So am I to understand that -release will skip in/out blocks entirely?
  
  Of course. It uses asserts. asserts are disabled in -release. Asserts are
  for debugging, testing, and verifying code when developing, not for code
  which is released. So, you get the benefit of the test when you don't
  have -release and the benefit of speed when you do have -release. If an
  assertion fails, your code logic is invalid. It's for validating your
  code, not user input or whatnot.
  
  enforce, on the other hand, is not a language primitive. It's not
  intended for testing or debugging. It's intended to be used in
  production code to throw an exception when its condition fails. If an
  enforce fails, that generally means that you had bad input somewhere or
  that an operation failed or whatnot. It's not intended for testing the
  logic of your code like assert is intended to do. It's simply a
  shorthand way to throw an exception when your program runs into a
  problem.
  
  - Jonathan M Davis
 
 I don't think I understand your response entirely. I understand that
 asserts are disabled in -release mode. I understand that enforce is a
 function that comes with std.exception, and the code isn't hard to follow.
 
 What I'm confused about is the in block, and why it is skipped in
 -release mode. You say It uses asserts. I didn't put an assert in my
 in block, I put an enforce. So I'm guessing that you are indicating that
 the in block is treated like an assert, and is disabled with the
 -release flag.
 
 But I think after reading your post you've helped clarify that what I'm
 checking (that you can't pop an empty stack) based on user input is
 something I should be checking with an enforce inside the function, and
 not an assert or enforce inside the in block.
 
 I still think I would like it if you could be a little more explicit
 about the in/out blocks. Are they always disabled entirely (skipped)
 with -release, or just certain things?
 
 Thanks for your help!

You're not really supposed to throw exceptions from in, out, or invariant 
blocks. You're supposed to use assertions in there. That's how the whole DbC 
thing is designed in D ( http://www.digitalmars.com/d/2.0/dbc.html ). So, while 
you _can_ throw exceptions from in, out, and invariant blocks, they _will_ be 
compiled out when compiling with -release. in, out, invariant just aren't 
intended for exceptions.

- Jonathan M Davis


in/out with -release

2011-03-04 Thread Kai Meyer
I have an 'enforce' function call in an 'in' block for a function. When I
compile with -release -O -inline, the in/out blocks appear to be skipped.
It's a simple verification for a dynamic array to not have a length of 0. In
debug mode, the test condition hits the enforce in the 'in' block, but in
release mode it does not. In both release and debug mode, the same exact
enforce function works properly.

So am I to understand that -release will skip in/out blocks entirely?


Re: in/out with -release

2011-03-04 Thread Jonathan M Davis
On Friday 04 March 2011 20:14:32 Kai Meyer wrote:
 I have an 'enforce' function call in an 'in' block for a function. When I
 compile with -release -O -inline, the in/out blocks appear to be skipped.
 It's a simple verification for a dynamic array to not have a length of 0.
 In debug mode, the test condition hits the enforce in the 'in' block, but
 in release mode it does not. In both release and debug mode, the same
 exact enforce function works properly.
 
 So am I to understand that -release will skip in/out blocks entirely?

Of course. It uses asserts. asserts are disabled in -release. Asserts are for 
debugging, testing, and verifying code when developing, not for code which is 
released. So, you get the benefit of the test when you don't have -release and 
the benefit of speed when you do have -release. If an assertion fails, your 
code 
logic is invalid. It's for validating your code, not user input or whatnot.

enforce, on the other hand, is not a language primitive. It's not intended for 
testing or debugging. It's intended to be used in production code to throw an 
exception when its condition fails. If an enforce fails, that generally means 
that you had bad input somewhere or that an operation failed or whatnot. It's 
not intended for testing the logic of your code like assert is intended to do. 
It's simply a shorthand way to throw an exception when your program runs into a 
problem.

- Jonathan M Davis