www.digitalmars.com         C & C++   DMDScript  

digitalmars.D - Attribute inference for non-templated functions

reply Seb <seb wilzba.ch> writes:
Hey while I was writing the contribution guide I stumbled over 
the issue that dmd will automatically infer attributes like  safe 
or pure in templated functions, but not in non-templated ones. 
Consider this example:

```
size_t inc(size_t a)
{
     return a + 1;
}

pure unittest
{
     assert(1.inc == 2);
}
```

It will not compile and yield and and error like "pure function 
'foo.__unittestL7_1' cannot call impure function 'foo.inc'".

Whereas the following compiles:

```
size_t incT(T = size_t)(size_t a)
{
     return a + 1;
}

pure unittest
{
     assert(1.incT == 2);
}
```

My question is whether this is just an open issue (I couldn't 
find it) or a design decision?
Mar 30 2016
parent reply Mathias Lang <pro.mathias.lang gmail.com> writes:
On Wednesday, 30 March 2016 at 12:42:42 UTC, Seb wrote:
 Hey while I was writing the contribution guide I stumbled over 
 the issue that dmd will automatically infer attributes like 
  safe or pure in templated functions, but not in non-templated 
 ones. Consider this example:

 ```
 size_t inc(size_t a)
 {
     return a + 1;
 }

 pure unittest
 {
     assert(1.inc == 2);
 }
 ```

 It will not compile and yield and and error like "pure function 
 'foo.__unittestL7_1' cannot call impure function 'foo.inc'".

 Whereas the following compiles:

 ```
 size_t incT(T = size_t)(size_t a)
 {
     return a + 1;
 }

 pure unittest
 {
     assert(1.incT == 2);
 }
 ```

 My question is whether this is just an open issue (I couldn't 
 find it) or a design decision?
It's a design decision. You want to be able to fix the exact type of your function, in order to provide headers for them for example (so you can work with libraries for which the source code is not available). If you want attribute inference, you can either make it a dummy template or, with a recent enough compiler, use `auto` return type.
Mar 30 2016
next sibling parent reply Meta <jared771 gmail.com> writes:
On Wednesday, 30 March 2016 at 12:57:56 UTC, Mathias Lang wrote:
 It's a design decision. You want to be able to fix the exact 
 type of your function, in order to provide headers for them for 
 example (so you can work with libraries for which the source 
 code is not available).

 If you want attribute inference, you can either make it a dummy 
 template or, with a recent enough compiler, use `auto` return 
 type.
Note that giving your function an `auto` return type is the same as making it template function with no template args.
Mar 30 2016
parent Artur Skawina via Digitalmars-d <digitalmars-d puremagic.com> writes:
On 03/30/16 16:20, Meta via Digitalmars-d wrote:
 On Wednesday, 30 March 2016 at 12:57:56 UTC, Mathias Lang wrote:
 It's a design decision. You want to be able to fix the exact type of your
function, in order to provide headers for them for example (so you can work
with libraries for which the source code is not available).

 If you want attribute inference, you can either make it a dummy template or,
with a recent enough compiler, use `auto` return type.
And making an inferred return type imply attribute inference was a serious design mistake (there is no such thing as an 'auto' type in D). Overloading ret-type inference like that, w/o any way to opt-out, means that ret-type inference became impossible in some situations, at least w/o ugly hacks to fool the compiler. Keep in mind that we're talking about a language that lacks a way to name certain classes of symbols, which makes inference unavoidable...
 Note that giving your function an `auto` return type is the same as making it
template function with no template args.
No, it's not. A template is a template, and a function with an inferred return type is still a function (eg you can instantiate the former and you can take the address of the latter). artur
Mar 30 2016
prev sibling parent reply Seb <seb wilzba.ch> writes:
On Wednesday, 30 March 2016 at 12:57:56 UTC, Mathias Lang wrote:
 My question is whether this is just an open issue (I couldn't 
 find it) or a design decision?
It's a design decision. You want to be able to fix the exact type of your function, in order to provide headers for them for example (so you can work with libraries for which the source code is not available). If you want attribute inference, you can either make it a dummy template or, with a recent enough compiler, use `auto` return type.
OK so it makes sense to recommend to always use `auto` for non-templated functions in high-level parts of Phobos? The current guideline recommends to specify the return type for better readability in the code and documentation, but I guess the latter can be eventually fixed and having automatic attribute inference is way more important than the first point? (given that most of Phobos makes extensive use of templates, this shouldn't be a huge issue anyway)
Mar 30 2016
next sibling parent jmh530 <john.michael.hall gmail.com> writes:
On Wednesday, 30 March 2016 at 15:26:21 UTC, Seb wrote:
 OK so it makes sense to recommend to always use `auto` for 
 non-templated functions in high-level parts of Phobos?
 The current guideline recommends to specify the return type for 
 better readability in the code and documentation, but I guess 
 the latter can be eventually fixed and having automatic 
 attribute inference is way more important than the first point?
This is why I was posting about the inconsistency in the Better Phobos Contribution guide. I don't have an opinion on what should be the recommendation, just that it should be easy to follow.
Mar 30 2016
prev sibling next sibling parent Anon <anon anon.anon> writes:
On Wednesday, 30 March 2016 at 15:26:21 UTC, Seb wrote:
 On Wednesday, 30 March 2016 at 12:57:56 UTC, Mathias Lang wrote:
 My question is whether this is just an open issue (I couldn't 
 find it) or a design decision?
It's a design decision. You want to be able to fix the exact type of your function, in order to provide headers for them for example (so you can work with libraries for which the source code is not available). If you want attribute inference, you can either make it a dummy template or, with a recent enough compiler, use `auto` return type.
OK so it makes sense to recommend to always use `auto` for non-templated functions in high-level parts of Phobos?
No. Non-templated public API should make it clear what guarantees it has. The easiest way to do this is explicitly mark any safe, pure, etc, just as you explicitly mark the type.
 The current guideline recommends to specify the return type for 
 better readability in the code and documentation, but I guess 
 the latter can be eventually fixed and having automatic 
 attribute inference is way more important than the first point?
Being able to tell what guarantees a method has (and ensure they can't accidentally be broken in updates) is way more important than automatic inference. If you use automatic inference for a public API, you then need to write unittests to make sure it stays safe, pure, etc. If you mark things explicitly, the compiler does those tests for you at compile-time.
 (given that most of Phobos makes extensive use of templates, 
 this shouldn't be a huge issue anyway)
Templates have little choice but to infer attributes. A bit more rigor in public-facing non-templates is affordable and desirable.
Mar 30 2016
prev sibling parent Jonathan M Davis via Digitalmars-d <digitalmars-d puremagic.com> writes:
On Wednesday, March 30, 2016 15:26:21 Seb via Digitalmars-d wrote:
 On Wednesday, 30 March 2016 at 12:57:56 UTC, Mathias Lang wrote:
 My question is whether this is just an open issue (I couldn't
 find it) or a design decision?
It's a design decision. You want to be able to fix the exact type of your function, in order to provide headers for them for example (so you can work with libraries for which the source code is not available). If you want attribute inference, you can either make it a dummy template or, with a recent enough compiler, use `auto` return type.
OK so it makes sense to recommend to always use `auto` for non-templated functions in high-level parts of Phobos? The current guideline recommends to specify the return type for better readability in the code and documentation, but I guess the latter can be eventually fixed and having automatic attribute inference is way more important than the first point? (given that most of Phobos makes extensive use of templates, this shouldn't be a huge issue anyway)
There is no reason for non-templated functions to infer attributes other than because people don't feel like typing. And by making them explicit, it's clear in the documentation what the attributes are, and it's guaranteed not to change just because some tweak in the implementation was made which happened to change the attribute inference. For templated functions, on the other hand, attribute inference is a must, because it usually depends on the template arguments, which means that without attribute inference, you're either forced to pick a set of attributes (thereby limiting the arguments which will work with that template), or you have to duplicate the template for each possible combination of attributes. So, attribute inference for templates solves a real practical problem, whereas for non-templated functions, all it does is save typing. And actually, in cases where you have a template function, but an attribute does _not_ depend on the template arguments, then I'd argue that it should have explicit attributes as well. It's when the attributes really depend on the template arguments that it matters. In the general case though, the big reason that normal functions don't do attribute inference now that we have it for templates is because D allows for linking against function prototypes without having the source code, in which case, infering attributes isn't possible. However, both templates and auto return functions are guaranteed to have their bodies present, so they don't have that problem. Regardless, I would argue that the rule of thumb for attributes is to be explicit about them except when they need to be infered because of template arguments. Some folks would prefer to drop them to save typing for auto functions, but doing that makes the documentation less clear and increases the risk that the attributes will accidentally change - which is part of why it can be critical to have unit tests which verify that the correct attributes are infered for a given block of code. - Jonathan M Davis
Mar 30 2016