August 01, 2014
On 08/02/2014 12:58 AM, Jonathan M Davis wrote:
> something like --remove-assertions.

What would that do?
August 01, 2014
On 08/02/2014 01:03 AM, H. S. Teoh via Digitalmars-d wrote:
> Actually, I'm thinking of ways of extending this even further, ...

Note that the official stance has been that such things are obviously ridiculous if not checked dynamically in non-release mode.
August 01, 2014
On Fri, Aug 01, 2014 at 11:24:29PM +0000, bearophile via Digitalmars-d wrote:
> H. S. Teoh:
> 
> >IMO the correct solution is for the compiler to insert preconditions at the calling site,
> 
> I have seen this suggestion tens of times, but nothing has happened. (delegates make the management of contract blame more compex).
[...]

I know, I wish I had the time and the know-how to actually implement this in dmd. I'm tired of the all-talk-and-no-action on the forum. Is there at least an enhancement request for this though?

The point about delegates is kinda interesting, though. Can they actually have contracts attached to them? I'd like to think that the contracts really ought to attach to the *type* of the delegate rather than the delegate itself. The reason is that I don't see how it would make sense if you had something like this:

	alias DgType = int delegate(int);

	int f1(int x) in { assert(x < 0); } body { ... }
	int f2(int x) in { assert(x > 0); } body { ... }

	// How does the following make any sense?
	void func(DgType dg, int x) {
		// How are we supposed to know what values of x are
		// acceptable?
		dg(x);
	}

	func(&f1, 1);	// oops
	func(&f2, -1);	// oops

Basically, given a DgType of unknown origin, it's impossible to reliably tell what arguments you ought to pass to it. So the compiler wouldn't know which in-contract to insert in func().

OTOH, perhaps one way to work around this, is to have a function with an in-contract compile into a preamble and a body:

	int func(int x)
	in { assert(x > 5); }
	body {
		return computeResult(x);
	}

would compile to the equivalent of:

	int __func_incontract(int x) {
		assert(x > 5);
		goto __func_body;	// fall through to __func_body
	}
	int __func_body(int x) {
		return computeResult(x);
	}

In non-release mode, calls to func would get translated into calls to __func_incontract, but in release mode, calls to func get translated into direct calls to __func_body. In both cases, the compiler always emits both __func_incontract and __func_body. If the ..._incontract symbols are never referenced by the final program, the linker discards them at link time.

This can be applied to both normal functions and delegates. In non-release mode, the (address of the) delegate would point to its ..._incontract portion, whereas in release mode, the (address of the) delegate would point directly to its ..._body portion. This way, if the caller is compiled in release mode, it will skip the contract, but if called in non-release mode, it will run the contract.


T

-- 
MACINTOSH: Most Applications Crash, If Not, The Operating System Hangs
August 01, 2014
On Sat, Aug 02, 2014 at 01:46:44AM +0200, Timon Gehr via Digitalmars-d wrote:
> On 08/02/2014 12:58 AM, Jonathan M Davis wrote:
> >something like --remove-assertions.
> 
> What would that do?

Automatically edit your source files and delete all assert expressions for you.

:-D


T

-- 
Why waste time learning, when ignorance is instantaneous? -- Hobbes, from Calvin & Hobbes
August 01, 2014
On 08/02/2014 01:51 AM, H. S. Teoh via Digitalmars-d wrote:
> On Sat, Aug 02, 2014 at 01:46:44AM +0200, Timon Gehr via Digitalmars-d wrote:
>> On 08/02/2014 12:58 AM, Jonathan M Davis wrote:
>>> something like --remove-assertions.
>>
>> What would that do?
>
> Automatically edit your source files and delete all assert expressions
> for you.
>
> :-D
>
>
> T
>

I feared it would!
August 01, 2014
On Sat, Aug 02, 2014 at 01:47:42AM +0200, Timon Gehr via Digitalmars-d wrote:
> On 08/02/2014 01:03 AM, H. S. Teoh via Digitalmars-d wrote:
> >Actually, I'm thinking of ways of extending this even further, ...
> 
> Note that the official stance has been that such things are obviously ridiculous if not checked dynamically in non-release mode.

Nothing stops the compiler in non-release mode from computing the expression both ways and comparing them to see if they match.


T

-- 
He who does not appreciate the beauty of language is not worthy to bemoan its flaws.
August 01, 2014
On 08/02/2014 01:46 AM, H. S. Teoh via Digitalmars-d wrote:
> OTOH, perhaps one way to work around this, is to have a function with an
> in-contract compile into a preamble and a body:
>
> 	int func(int x)
> 	in { assert(x > 5); }
> 	body {
> 		return computeResult(x);
> 	}
>
> would compile to the equivalent of:
>
> 	int __func_incontract(int x) {
> 		assert(x > 5);
> 		goto __func_body;	// fall through to __func_body
> 	}
> 	int __func_body(int x) {
> 		return computeResult(x);
> 	}
>
> In non-release mode, calls to func would get translated into calls to
> __func_incontract,

What if a library function was compiled in release mode?

August 02, 2014
On 08/02/2014 01:52 AM, H. S. Teoh via Digitalmars-d wrote:
> On Sat, Aug 02, 2014 at 01:47:42AM +0200, Timon Gehr via Digitalmars-d wrote:
>> On 08/02/2014 01:03 AM, H. S. Teoh via Digitalmars-d wrote:
>>> Actually, I'm thinking of ways of extending this even further, ...
>>
>> Note that the official stance has been that such things are obviously
>> ridiculous if not checked dynamically in non-release mode.
>
> Nothing stops the compiler in non-release mode from computing the
> expression both ways and comparing them to see if they match.
>
>
> T
>

Side effects. Multiplication of the runtime in non-release builds.

Btw, I don't think one can use == to express those rewrites.
August 02, 2014
On Sat, Aug 02, 2014 at 01:59:29AM +0200, Timon Gehr via Digitalmars-d wrote:
> On 08/02/2014 01:46 AM, H. S. Teoh via Digitalmars-d wrote:
> >OTOH, perhaps one way to work around this, is to have a function with an in-contract compile into a preamble and a body:
> >
> >	int func(int x)
> >	in { assert(x > 5); }
> >	body {
> >		return computeResult(x);
> >	}
> >
> >would compile to the equivalent of:
> >
> >	int __func_incontract(int x) {
> >		assert(x > 5);
> >		goto __func_body;	// fall through to __func_body
> >	}
> >	int __func_body(int x) {
> >		return computeResult(x);
> >	}
> >
> >In non-release mode, calls to func would get translated into calls to __func_incontract,
> 
> What if a library function was compiled in release mode?

The compiler always emits the in-contract, so the library would carry all the in-contracts. If the user code doesn't actually use them, then the linker just doesn't link them in at link time.


T


-- 
Живёшь только однажды.
August 02, 2014
On Sat, Aug 02, 2014 at 02:04:22AM +0200, Timon Gehr via Digitalmars-d wrote:
> On 08/02/2014 01:52 AM, H. S. Teoh via Digitalmars-d wrote:
> >On Sat, Aug 02, 2014 at 01:47:42AM +0200, Timon Gehr via Digitalmars-d wrote:
> >>On 08/02/2014 01:03 AM, H. S. Teoh via Digitalmars-d wrote:
> >>>Actually, I'm thinking of ways of extending this even further, ...
> >>
> >>Note that the official stance has been that such things are obviously ridiculous if not checked dynamically in non-release mode.
> >
> >Nothing stops the compiler in non-release mode from computing the expression both ways and comparing them to see if they match.
> >
> >
> >T
> >
> 
> Side effects. Multiplication of the runtime in non-release builds.

True. I haven't really thought through how to address all those details yet. The final design may not quite behave exactly the way I described. But it's a direction I'd like to go in, because I think there's a lot of potential here.


> Btw, I don't think one can use == to express those rewrites.

It's just hypothetical syntax.  The point is that it's a hinting system to provide extra reduction rules to the optimizer that is impractical for the compiler to automatically deduce.


T

-- 
Claiming that your operating system is the best in the world because more people use it is like saying McDonalds makes the best food in the world. -- Carl B. Constantine