www.digitalmars.com         C & C++   DMDScript  

digitalmars.D - Why isn't purity & co. inferred for all functions?

reply Trass3r <un known.com> writes:
It's already inferred for templated functions, so it's perfectly possible.
Also it should be checked anyway, so I get an error message if I marked  
something pure or whatever while it actually isn't.

The only functions where it can't be inferred and manual attributes are  
really needed are function definitions (i.e. no body available).

What speaks against it?
May 11 2012
next sibling parent reply Walter Bright <newshound2 digitalmars.com> writes:
On 5/11/2012 11:53 AM, Trass3r wrote:
 It's already inferred for templated functions, so it's perfectly possible.
 Also it should be checked anyway, so I get an error message if I marked
 something pure or whatever while it actually isn't.

 The only functions where it can't be inferred and manual attributes are really
 needed are function definitions (i.e. no body available).

 What speaks against it?

Separate compilation. I.e. given modules A and B: A === int foo() { return 3; } === B === import A; pure int bar() { return foo(); } === and the compiler infers purity, so it compiles. Then, maintenance programmer Fred updates module A to be: A === int x; int foo() { return x; } === and now foo() is no longer pure. He recompiles A, links with existing B.obj, and now whoops! bar() is marked as pure, but is not pure. This issue does not exist for templates & literals & auto funcs, because already A must be recompiled if B is modified.
May 11 2012
next sibling parent Trass3r <un known.com> writes:
Thanks for the explanation.
Should be somewhere in the docs :)
May 11 2012
prev sibling next sibling parent reply "Robert DaSilva" <spunit262 yahoo.com> writes:
On Friday, 11 May 2012 at 20:29:45 UTC, Walter Bright wrote:
 On 5/11/2012 11:53 AM, Trass3r wrote:
 It's already inferred for templated functions, so it's 
 perfectly possible.
 Also it should be checked anyway, so I get an error message if 
 I marked
 something pure or whatever while it actually isn't.

 The only functions where it can't be inferred and manual 
 attributes are really
 needed are function definitions (i.e. no body available).

 What speaks against it?

Separate compilation. I.e. given modules A and B: A === int foo() { return 3; } === B === import A; pure int bar() { return foo(); } === and the compiler infers purity, so it compiles. Then, maintenance programmer Fred updates module A to be: A === int x; int foo() { return x; } === and now foo() is no longer pure. He recompiles A, links with existing B.obj, and now whoops! bar() is marked as pure, but is not pure. This issue does not exist for templates & literals & auto funcs, because already A must be recompiled if B is modified.

I thought Purity was marked in the mangled name, so that should give a link error.
May 11 2012
parent reply Walter Bright <newshound2 digitalmars.com> writes:
On 5/11/2012 4:48 PM, Trass3r wrote:
 I thought Purity was marked in the mangled name, so that should give a link
 error.

Good point.

Doesn't work if any modules declare: extern int foo();
May 11 2012
parent reply Paulo Pinto <pjmlp progtools.org> writes:
Am 12.05.2012 05:33, schrieb Walter Bright:
 On 5/11/2012 4:48 PM, Trass3r wrote:
 I thought Purity was marked in the mangled name, so that should give
 a link
 error.

Good point.

Doesn't work if any modules declare: extern int foo();

Those functions would always be considered impure, unless the programmer says otherwise in the extern declaration.
May 12 2012
parent Walter Bright <newshound2 digitalmars.com> writes:
On 5/12/2012 1:12 AM, Paulo Pinto wrote:
 Am 12.05.2012 05:33, schrieb Walter Bright:
 On 5/11/2012 4:48 PM, Trass3r wrote:
 I thought Purity was marked in the mangled name, so that should give
 a link
 error.

Good point.

Doesn't work if any modules declare: extern int foo();

Those functions would always be considered impure, unless the programmer says otherwise in the extern declaration.

Sure, but if foo() is defined in A, imported in B, and just extern declared in C, then it won't link. I.e. the name mangling shouldn't change whether or not the compiler sees the source.
May 12 2012
prev sibling next sibling parent Trass3r <un known.com> writes:
 I thought Purity was marked in the mangled name, so that should give a  
 link error.

Good point.
May 11 2012
prev sibling parent reply deadalnix <deadalnix gmail.com> writes:
Le 11/05/2012 22:29, Walter Bright a écrit :
 On 5/11/2012 11:53 AM, Trass3r wrote:
 It's already inferred for templated functions, so it's perfectly
 possible.
 Also it should be checked anyway, so I get an error message if I marked
 something pure or whatever while it actually isn't.

 The only functions where it can't be inferred and manual attributes
 are really
 needed are function definitions (i.e. no body available).

 What speaks against it?

Separate compilation. I.e. given modules A and B: A === int foo() { return 3; } === B === import A; pure int bar() { return foo(); } === and the compiler infers purity, so it compiles. Then, maintenance programmer Fred updates module A to be: A === int x; int foo() { return x; } === and now foo() is no longer pure. He recompiles A, links with existing B.obj, and now whoops! bar() is marked as pure, but is not pure. This issue does not exist for templates & literals & auto funcs, because already A must be recompiled if B is modified.

I did considered that quite a lot. I came to the conclusion that function should have explicit and infered attributes. For simplicity, I will limit myself to pure here, the same can be extended to other attributes. So, if a function is marked as pure, this function is EXPLICITELY pure. It means that the compiler ensure it is pure. Otherwise, the function is marked as not explicitly pure, and purity is inferred unknown. When using such a function in a way that require a pure function, if nothing is explicitly stated, the inferred attribute is used. If the inferred attribute is unknown, the function body is used to infer it. With such a mechanism, attribute are inferred when needed (otherwise, the calculation can become quite expansive). If the function body is unknown (separate compilation model). Inference is impossible. Alternatively, the DI generation could make inferred attributes explicit. Such inference is very important for D. We have many qualifier, and it is unlikely that every programmer mark everything as it should. Just consider the state of druntime in that regard, and it have been done by experienced D programmers.
May 12 2012
parent Timon Gehr <timon.gehr gmx.ch> writes:
On 05/12/2012 04:46 PM, deadalnix wrote:
 Just consider the state of druntime in that regard, and it have been done by
 experienced D programmers.

... before the attributes were introduced.
May 12 2012
prev sibling parent =?UTF-8?B?QWxleCBSw7hubmUgUGV0ZXJzZW4=?= <xtzgzorex gmail.com> writes:
On 11-05-2012 20:53, Trass3r wrote:
 It's already inferred for templated functions, so it's perfectly possible.
 Also it should be checked anyway, so I get an error message if I marked
 something pure or whatever while it actually isn't.

 The only functions where it can't be inferred and manual attributes are
 really needed are function definitions (i.e. no body available).

 What speaks against it?

Purity is part of the API. If, in version $a of an API, your function just happens to be inferred as pure and your users rely on it, you'll break their code if you change your function's code in version $b and it's no longer pure without you noticing. This effectively defeats the purpose of inferred purity because you cannot rely on it. It's as simple as that. -- - Alex
May 12 2012