digitalmars.D - Attribute inference for non-templated functions
- Seb (29/29) Mar 30 2016 Hey while I was writing the contribution guide I stumbled over
- Mathias Lang (8/37) Mar 30 2016 It's a design decision. You want to be able to fix the exact type
- Meta (3/10) Mar 30 2016 Note that giving your function an `auto` return type is the same
- Artur Skawina via Digitalmars-d (12/17) Mar 30 2016 And making an inferred return type imply attribute inference was a serio...
- Seb (9/18) Mar 30 2016 OK so it makes sense to recommend to always use `auto` for
- jmh530 (4/10) Mar 30 2016 This is why I was posting about the inconsistency in the Better
- Anon (12/32) Mar 30 2016 No. Non-templated public API should make it clear what guarantees
- Jonathan M Davis via Digitalmars-d (31/51) Mar 30 2016 There is no reason for non-templated functions to infer attributes other
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
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
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
On 03/30/16 16:20, Meta via Digitalmars-d wrote:On Wednesday, 30 March 2016 at 12:57:56 UTC, Mathias Lang wrote: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...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.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
On Wednesday, 30 March 2016 at 12:57:56 UTC, Mathias Lang 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? (given that most of Phobos makes extensive use of templates, this shouldn't be a huge issue anyway)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
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
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: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.OK so it makes sense to recommend to always use `auto` for non-templated functions in high-level parts of Phobos?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.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
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: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 DavisOK 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)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