Re: How to enforce compile time evaluation (and test if it was done at compile time)

2017-03-01 Thread Jonathan M Davis via Digitalmars-d-learn
On Wednesday, March 01, 2017 17:02:37 Dukc via Digitalmars-d-learn wrote:
> On Wednesday, 1 March 2017 at 16:43:41 UTC, Jonathan M Davis
>
> wrote:
> > Assert is for program invariants. If the condition is true,
> > your program is outright broken.
>
> Error: He meant that if the condition is FALSE, the program is
> faulty.

LOL. True. Sorry about that. Invariants must be true, not false. I should
have caught that.

- Jonathan M Davis



Re: How to enforce compile time evaluation (and test if it was done at compile time)

2017-03-01 Thread XavierAP via Digitalmars-d-learn
On Wednesday, 1 March 2017 at 09:19:53 UTC, Christian Köstlin 
wrote:

On 01/03/2017 00:09, Joseph Rushton Wakeling wrote:

if (!__ctfe) assert(false);

... might be the best option.  That shouldn't be compiled out 
even in -release builds.
thats a nice idea! is this happening because of assert(false) 
being always part of release builds (as mentioned here: 
https://dlang.org/spec/contracts.html#assert_contracts) or 
because the if would have no instructions anymore if this is 
removed.


Yes assert(false) or assert(0) is a special case according to the 
specification. At least in the DMD implementation it is not 
removed for -release. If reached it throws an "object.Error@(0): 
assert(0) or HLT instruction" instead of 
core.exception.AssertError


Re: How to enforce compile time evaluation (and test if it was done at compile time)

2017-03-01 Thread Dukc via Digitalmars-d-learn
On Wednesday, 1 March 2017 at 16:43:41 UTC, Jonathan M Davis 
wrote:
Assert is for program invariants. If the condition is true, 
your program is outright broken.


Error: He meant that if the condition is FALSE, the program is 
faulty.





Re: How to enforce compile time evaluation (and test if it was done at compile time)

2017-03-01 Thread Jonathan M Davis via Digitalmars-d-learn
On Tuesday, February 28, 2017 09:16:47 sarn via Digitalmars-d-learn wrote:
> On Tuesday, 28 February 2017 at 07:41:36 UTC, Christian Köstlin
>
> wrote:
> > As I understand the only difference between assert and enforce
> > is, that
> > assert is not compiled into releases?
> >
> > Thanks!
> > Christian
>
> Pretty much so.  The intention is that assert means something
> that's supposed to be true (and can be assumed in release) while
> enforce means something you want to be true (but can't guarantee).
>
> E.g., you can assert that a list is sorted after running heapsort
> on it, but you need to enforce that a file is in the correct
> format.

I'd put it more strongly than that. assert is for program invariants. If the
condition is true, your program is outright broken. For performance reasons,
assertions are removed in release builds, but many folks think that they
should be left in and kill our program if they fail in release (and would be
why some folks won't compile with -release even in production). assert(0)
_does_ stay in your program in release mode and could be used in conjuction
with an if statement (since it doesn't have a condition to test), but it's
intended for unreachable code. Normally, assert throws an AssertError on
failure (assert(0) becomes an HLT instruction in release), and types derived
from Error are intended to kill your program on failure, precisely because
they indicate a bug in your program and if they fail, it means that your
program is in an undefined state (RangeError, which is use a failed bounds
check for an array would be another example of an Error).

Exceptions - specifically Exception or any type derived from it - are for
general error conditions that occur while a program is running but do not
necessarily indicate a bug in the program. Bad user input, stuff on disk,
anything in the environment, etc. - i.e. anything over which you have no
control -  generally would be the sort of thing that triggers an exception
when the program hits them. Exceptions are part of the normal operation of
your program and are expected to be recoverable (though a typical program
that hits no bad input would typically never need to throw an exception).

In general, the distinction between assertions and exceptions should be very
clear: assertions are for program invariants and exceptions are for when
your program encounters bad input or any other error condition that does not
indicate a bug in your program. Unfortunately however, the fact that enforce
looks the same as assert does seem to confuse some folks.

The only place that gets a bit debatable is testing arguments to a function,
and that really depends on the function's contract. If the function requires
that its input meet some conditions, and it's a bug if the caller does not
meet them, then an assertion should be used, whereas if it's not a bug in
the program if the caller provides bad input, then an exception is
appropriate. And when it should be considered a program bug and when it
should just be considered normal program execution depends on exactly what
the function is doing as well as your programming style (e.g. some folks
prefer that the caller be required to verify the correct input, whereas
others prefer that the callee do that; there are pros and cons to both). So,
that can get subjective. But ultimately, assertions are still for program
bugs, whereas exceptions are for normal error conditions that do not
indicate a bug in the program.

- Jonathan M Davis




Re: How to enforce compile time evaluation (and test if it was done at compile time)

2017-03-01 Thread Christian Köstlin via Digitalmars-d-learn
On 01/03/2017 00:09, Joseph Rushton Wakeling wrote:
> On Tuesday, 28 February 2017 at 00:22:28 UTC, sarn wrote:
>>> If you ever have doubts, you can always use something like this to
>>> check:
>>>
>>> assert (__ctfe);
>>
>> Sorry, "enforce" would more appropriate if you're really checking.
> 
> if (!__ctfe) assert(false);
> 
> ... might be the best option.  That shouldn't be compiled out even in
> -release builds.
thats a nice idea! is this happening because of assert(false) being
always part of release builds (as mentioned here:
https://dlang.org/spec/contracts.html#assert_contracts) or because the
if would have no instructions anymore if this is removed.

cK



Re: How to enforce compile time evaluation (and test if it was done at compile time)

2017-02-28 Thread Joseph Rushton Wakeling via Digitalmars-d-learn

On Tuesday, 28 February 2017 at 00:22:28 UTC, sarn wrote:
If you ever have doubts, you can always use something like 
this to check:


assert (__ctfe);


Sorry, "enforce" would more appropriate if you're really 
checking.


if (!__ctfe) assert(false);

... might be the best option.  That shouldn't be compiled out 
even in -release builds.


Re: How to enforce compile time evaluation (and test if it was done at compile time)

2017-02-28 Thread sarn via Digitalmars-d-learn
On Tuesday, 28 February 2017 at 07:41:36 UTC, Christian Köstlin 
wrote:
As I understand the only difference between assert and enforce 
is, that

assert is not compiled into releases?

Thanks!
Christian


Pretty much so.  The intention is that assert means something 
that's supposed to be true (and can be assumed in release) while 
enforce means something you want to be true (but can't guarantee).


E.g., you can assert that a list is sorted after running heapsort 
on it, but you need to enforce that a file is in the correct 
format.


Re: How to enforce compile time evaluation (and test if it was done at compile time)

2017-02-27 Thread Christian Köstlin via Digitalmars-d-learn
On 28/02/2017 01:20, sarn wrote:
> On Monday, 27 February 2017 at 19:26:06 UTC, Christian Köstlin wrote:
>> How can I make sure, that the calculations are done at compile time?
> 
> If you ever have doubts, you can always use something like this to check:
> 
> assert (__ctfe);
Thanks a lot, actually works as you describe it!
As I understand the only difference between assert and enforce is, that
assert is not compiled into releases?

Thanks!
Christian



Re: How to enforce compile time evaluation (and test if it was done at compile time)

2017-02-27 Thread sarn via Digitalmars-d-learn

On Tuesday, 28 February 2017 at 00:20:05 UTC, sarn wrote:
On Monday, 27 February 2017 at 19:26:06 UTC, Christian Köstlin 
wrote:
How can I make sure, that the calculations are done at compile 
time?


If you ever have doubts, you can always use something like this 
to check:


assert (__ctfe);


Sorry, "enforce" would more appropriate if you're really checking.


Re: How to enforce compile time evaluation (and test if it was done at compile time)

2017-02-27 Thread sarn via Digitalmars-d-learn
On Monday, 27 February 2017 at 19:26:06 UTC, Christian Köstlin 
wrote:
How can I make sure, that the calculations are done at compile 
time?


If you ever have doubts, you can always use something like this 
to check:


assert (__ctfe);


Re: How to enforce compile time evaluation (and test if it was done at compile time)

2017-02-27 Thread Dukc via Digitalmars-d-learn
On Monday, 27 February 2017 at 19:26:06 UTC, Christian Köstlin 
wrote:

Is it enough to put up static immutable modifiers?
How can I make sure, that the calculations are done at compile 
time?


...
static immutable time = Unit("time", [Unit.Scale("ms", 1),
...


An initialization of a static variable (or constant, as in this 
case) is indeed always done at compile time. Another option would 
be using an enum storage class. Difference between enum and 
static or shared immutable is that enum IS a compile time 
constant, not just a runtime constant initialized at 
compile-time. That means you can use enums to calculate other 
compile-time stuff.


Template parameters are also calculated at compile time. If they 
take a value, they are enum values, only difference to normal 
enums being that their values are defined at template call site. 
Thus, if you pass an expression to a template argument, you can 
be sure it's calculated at compile time.