digitalmars.D - Attribute inference for auto functions?
- Andrei Alexandrescu (3/3) Apr 16 2013 There's a discussion that may be of interest to the larger community:
- Regan Heath (36/38) Apr 16 2013 I read the whole thing and IMO this pull request is a good idea.
- Dmitry Olshansky (17/20) Apr 16 2013 In the same vane - how about attribute inference for "ordinary" function...
- Peter Alexander (10/13) Apr 16 2013 I find this unacceptable. Thanks to the proliferation of template
- Jesse Phillips (5/15) Apr 16 2013 How frequently do you write a non-templated function which
- Peter Alexander (7/25) Apr 17 2013 Often enough. I often find myself returning ranges, which are
- deadalnix (20/27) Apr 17 2013 Note that this is consistent with many choice D made.
- Peter Alexander (27/41) Apr 17 2013 I disagree. Attributes are completely separate from return value,
- Andrej Mitrovic (10/12) Apr 17 2013 That's not true, you still need to use auto. This function definition
- Peter Alexander (13/31) Apr 17 2013 You don't need to use auto. Any storage class will do.
- Rob T (15/22) Apr 17 2013 On Wednesday, 17 April 2013 at 13:59:05 UTC, Peter Alexander
- Andrej Mitrovic (6/8) Apr 17 2013 Actually I'm wrong about this now that I've re-read the spec. You can
- Peter Alexander (3/15) Apr 17 2013 Sorry, just saw this. Ignore previous reply.
- deadalnix (13/52) Apr 17 2013 auto is generally understood as type inference, so ti isn't an
- Rob T (17/79) Apr 17 2013 It's certainly not helpful if we keep on blurring the concepts.
- Jesse Phillips (10/20) Apr 17 2013 This is a very good description of the change.
- Walter Bright (2/6) Apr 17 2013 Yes, the pull request does that, too.
- Andrei Alexandrescu (4/22) Apr 17 2013 I think this is a solid argument. You may want to paste it in the github...
- Walter Bright (6/11) Apr 17 2013 'auto', like all storage class annotations such as 'const', binds to the...
- deadalnix (8/23) Apr 17 2013 Yes I know. That was my point : auto bind to the function
- Walter Bright (6/9) Apr 17 2013 To annotate the return type specifically with, say, const:
- deadalnix (2/8) Apr 17 2013 This doesn't work with many attributes.
- qznc (10/38) Apr 17 2013 I strongly believe you should never use "auto" for API types,
- David Nadlinger (5/9) Apr 17 2013 LDC/LLVM does something very similar already (on the IR level),
- Jesse Phillips (11/13) Apr 17 2013 Hmm, I'm still trying to decide if this is a major concern.
- Andrej Mitrovic (11/13) Apr 17 2013 This can be common if the function is a member function that returns
- Regan Heath (17/28) Apr 17 2013 Solution: You use 'auto' and compile the code producing a .di. With th...
- Andrej Mitrovic (2/5) Apr 17 2013 This doesn't work with voldemort types.
- Andrei Alexandrescu (3/8) Apr 17 2013 It's not supposed to; voldemort functions are by definition non-modular.
- Walter Bright (4/12) Apr 17 2013 The whole point of voldemort functions is that you cannot name the retur...
- Andrei Alexandrescu (3/9) Apr 17 2013 Attribute inference is always done for templates.
- Walter Bright (2/12) Apr 17 2013 And, I might add, I cannot recall a single adverse issue that has caused...
- Jonathan M Davis (16/30) Apr 22 2013 If anything, the fact that it doesn't infer more is the problem.
- Timon Gehr (3/15) Apr 16 2013 This should not be an issue any more.
- Dmitry Olshansky (4/23) Apr 17 2013 So it was a bug after all. Good to see it fixed.
- Timon Gehr (11/14) Apr 16 2013 I think inferring the return type and inferring the attributes are
- deadalnix (7/12) Apr 16 2013 auto is a storage class, so it should be possible to explicitly
- deadalnix (5/9) Apr 16 2013 Oh Yes, Yes, Yes, god Yes !
- Walter Bright (2/10) Apr 16 2013 Not sure what you're saying yes to - the pro or the con?
- deadalnix (4/18) Apr 16 2013 Yes to the pull request, yes to the inference. I agree with you,
- Walter Bright (3/5) Apr 16 2013 I'll mark it on my calendar!
- deadalnix (2/8) Apr 16 2013 Don't this risk to conflict with LTO ?
- Walter Bright (2/5) Apr 16 2013 How so?
- deadalnix (2/10) Apr 16 2013 Never mind, I think I was wrong. It is a good idea.
- Jesse Phillips (14/18) Apr 16 2013 I'm not convinced that specifying the exact return type is such a
- Piotr Szturmaj (8/10) Apr 17 2013 On demand inference FTW!
- Jacob Carlborg (4/11) Apr 17 2013 Double auto, hehe.
- Andrei Alexandrescu (5/15) Apr 17 2013 I think this is a bit much. Simplicity is a good commodity to allow
- Walter Bright (3/5) Apr 17 2013 It also goes back to your discussion of the observation that programmers...
- Michel Fortin (32/34) Apr 17 2013 I agree attribute inference is needed. I don't think 'auto' is a
- Walter Bright (4/6) Apr 17 2013 It is not a problem right now because the compiler has to semantically a...
- Michel Fortin (15/23) Apr 17 2013 True, but beside the point.
- Jesse Phillips (12/16) Apr 17 2013 I wish to bring Someboddies consern to this form.
- Walter Bright (5/7) Apr 17 2013 I specifically addressed his concern in the git page:
- Walter Bright (3/11) Apr 17 2013 His followup doesn't change that. It's still the same issue (covariance)...
- Minas Mina (1/1) Apr 17 2013 Yes, please do attribute inference!
- Jesse Phillips (5/14) Apr 17 2013 Initially I thought you were replying to something further up in
- Timon Gehr (11/19) Apr 17 2013 Why is this a valid form of reasoning? The signature of a function that
- Walter Bright (4/18) Apr 17 2013 Pure and nothrow provide more guarantees, hence covariance.
- deadalnix (7/25) Apr 17 2013 No : if a super function suddenly become pure because its
- Walter Bright (3/8) Apr 17 2013 Of course.
- Timon Gehr (26/52) Apr 17 2013 No. In one case you infer guarantees only. (those restrict what can be
- Walter Bright (5/18) Apr 18 2013 If you want a precise signature, don't use auto. It's the same case as
- Andrei Alexandrescu (5/9) Apr 18 2013 I think he means subtyping. An attributed function (pure, nothrow) is a
- Walter Bright (4/6) Apr 17 2013 What do you think of this:
- deadalnix (2/9) Apr 17 2013 Very nice !
- Zach the Mystic (5/12) Apr 17 2013 I don't actually have an opinion on whether attributes should be
- Walter Bright (2/15) Apr 17 2013 Except that we already support typeof(return) inside of a function.
- Zach the Mystic (9/30) Apr 17 2013 Yeah, I basically agree. If I had to choose right now,
- Piotr Szturmaj (2/15) Apr 17 2013 And this can apply to whole scopes.
- Zach the Mystic (9/29) Apr 17 2013 Yeah, that's true... 'typeof(return):' would not look good at the
- kenji hara (8/15) Apr 17 2013 It will break existing code.
- deadalnix (2/8) Apr 17 2013 That is true :( Don't seem fixable.
- Walter Bright (2/13) Apr 17 2013 It is fixable if it is special cased, but special cases stink.
- Andrei Alexandrescu (3/17) Apr 18 2013 Thanks Kenji for a surgical destruction.
- Piotr Szturmaj (22/39) Apr 19 2013 What about this:
- John Colvin (3/26) Apr 19 2013 I like this. It provides a good balance of control and automation.
- Piotr Szturmaj (5/7) Apr 19 2013 I see no need for special treating of template functions. In this case
- deadalnix (8/31) Apr 19 2013 Except for 2, this is already what is proposed.
- Walter Bright (6/11) Apr 19 2013 I'm not understanding it being a recurring problem. There is a recurring...
- deadalnix (3/12) Apr 19 2013 What is type of an impure function that return a pure, extern(C)
- Timon Gehr (7/21) Apr 19 2013 Currently, it exists, yet cannot be named, and the formatted output of
- deadalnix (4/10) Apr 19 2013 Yes you have to use a alias to do this kind of thing. But some
- Walter Bright (2/5) Apr 19 2013 Example, please.
- Mehrdad (7/11) Apr 20 2013 Here you go:
- Walter Bright (12/24) Apr 20 2013 What I've been trying to explain is that there's a difference between a ...
- Andrej Mitrovic (7/10) Apr 20 2013 I've mentioned this before, but we need a good definition of these on
- Walter Bright (5/16) Apr 19 2013 A function foo:
- deadalnix (5/9) Apr 19 2013 Same here.
- Walter Bright (6/13) Apr 19 2013 That is correct. I was thinking about the pure. The extern(C) can be don...
- deadalnix (4/7) Apr 19 2013 In general we lack a mechanism to choose what direction we turn
- Jesse Phillips (3/10) Apr 18 2013 It wouldn't break the code though. It would change the meaning,
- Zach the Mystic (12/16) Apr 21 2013 I just want to say I'm pretty gung-ho about the idea of attribute
There's a discussion that may be of interest to the larger community: https://github.com/D-Programming-Language/dmd/pull/1877 Andrei
Apr 16 2013
On Tue, 16 Apr 2013 16:22:56 +0100, Andrei Alexandrescu <SeeWebsiteForEmail erdani.org> wrote:There's a discussion that may be of interest to the larger community: https://github.com/D-Programming-Language/dmd/pull/1877I read the whole thing and IMO this pull request is a good idea. I think your last summary covers the various points well: https://github.com/D-Programming-Language/dmd/pull/1877#issuecomment-16403663 Should the first step here be to fix the issue described in 2.1? I agree with your reasoning that (b) seems a decent solution. We don't want 'auto' function bodies in .di files and /more importantly/ IMO interface definitions should be as precise as possible. I would almost suggest that good working practice may be to use auto in the .d file, generate the precise .di then back-port the precise .di definition to the .d file once development was complete (for any given version of the library). This would then make accidental changes to a library interface difficult because and change to the library source which conflicted with the now precise definition would be flagged by the compiler. That is, unless you're doing something nasty with void* and cast or similar. It seems the remaining complaint is the compilation speed issue. Do people recompile .di files with every change? I can imagine if you're in a development loop which involves updating a library, recompiling it, moving to a consumer of that library, updating that and recompiling, then testing the change, then looping back to make more changes, and so on. In this case it is conceivable that a library changes might result in a .di change, which would then result in more recompilation right through. But .. if the .di changes it will do so because the library interface has changed, and those changes are surely important to the consumer, aren't they? Or, is there a sufficiently large sub-set of possible changes you could make to the library which are irrelevant to the consumer? If that is the case, can .di generation from 'auto' leave these off the precise definition? I mean, if we're saying they're irrelevant to the consumer of the library, why put them there in the first place, right? R -- Using Opera's revolutionary email client: http://www.opera.com/mail/
Apr 16 2013
16-Apr-2013 19:22, Andrei Alexandrescu пишет:There's a discussion that may be of interest to the larger community: https://github.com/D-Programming-Language/dmd/pull/1877 AndreiIn the same vane - how about attribute inference for "ordinary" functions? I recall that just a month ago I had an interesting case - a normal function inside of a templated struct. The thing is that depending on some parameters (of struct) it could be safe or not. But it's not a template itself and its return type is always bool. In the end I just added an empty CT parameter set making it a template. Questions are - why are we hell bent on the `auto' return type being a marker? What are the other good markers out there? Should we pick anything else for this auto-magic or let the programmer use some wild-card marker explicitly? If we let a bunch of arcane rules govern the inference that would be a failure. On the other hand not doing it where makes sense would be a failure to realize the benefits of annotations ('cause nobody bothers adding them explicitly). -- Dmitry Olshansky
Apr 16 2013
This is the point I have a problem with:I find this unacceptable. Thanks to the proliferation of template code in D, it is often rather difficult to spell out return types. Indeed, this is part of the original reason for auto's existence. Denying return type deduction for this use case is a major inconvenience. As it stands, I am against this change. It is an unfortunate situation we are in, with D working best with everything inferred and CTFE-able, yet with those things completely at odds with modularity.2.2. One cannot opt out of nothrow or pure with auto functions.This argument has one solid answer: don't use auto when the need is to specify an attribute pattern explicitly.
Apr 16 2013
On Tuesday, 16 April 2013 at 20:21:00 UTC, Peter Alexander wrote:This is the point I have a problem with:How frequently do you write a non-templated function which returns a complex template type? It isn't something I really think about, but I'm pretty sure if I am returning a complex template type I've already got the function a template.I find this unacceptable. Thanks to the proliferation of template code in D, it is often rather difficult to spell out return types. Indeed, this is part of the original reason for auto's existence. Denying return type deduction for this use case is a major inconvenience.2.2. One cannot opt out of nothrow or pure with auto functions.This argument has one solid answer: don't use auto when the need is to specify an attribute pattern explicitly.
Apr 16 2013
On Wednesday, 17 April 2013 at 01:55:54 UTC, Jesse Phillips wrote:On Tuesday, 16 April 2013 at 20:21:00 UTC, Peter Alexander wrote:Often enough. I often find myself returning ranges, which are almost invariably complex template types. And, to be honest, I would just like to use auto without being locked into inferred attributes. It just feels wrong that these things should be conflated, and I get the feeling we will regret this later on when D starts to be used in larger projects.This is the point I have a problem with:How frequently do you write a non-templated function which returns a complex template type? It isn't something I really think about, but I'm pretty sure if I am returning a complex template type I've already got the function a template.I find this unacceptable. Thanks to the proliferation of template code in D, it is often rather difficult to spell out return types. Indeed, this is part of the original reason for auto's existence. Denying return type deduction for this use case is a major inconvenience.2.2. One cannot opt out of nothrow or pure with auto functions.This argument has one solid answer: don't use auto when the need is to specify an attribute pattern explicitly.
Apr 17 2013
On Wednesday, 17 April 2013 at 07:04:16 UTC, Peter Alexander wrote:Often enough. I often find myself returning ranges, which are almost invariably complex template types. And, to be honest, I would just like to use auto without being locked into inferred attributes. It just feels wrong that these things should be conflated, and I get the feeling we will regret this later on when D starts to be used in larger projects.Note that this is consistent with many choice D made. auto is a storage class. storage class usually stick to the function, not the return type : const Foo bar(); // Error as const qualify bar and not Foo. auto is about type inference. Attribute is part of the function type as much as it return type, and so it is expected that auto applied to a function infer its attributes and its return type. The problem you are talking about is very real, but much broader than this auto thing. The problem is that you have no control on what the storage classes bind on. Examples : extern(C) void function() foo; // does extern binds to foo, foo's type or both ? pure function() function() bar; // is bar a pure function ? is bar() pure ? Noth ? How to choose ? Back to the subject, if auto bind to the function it must infers attributes, if it binds to the return type, it mustn't. And right now, storage class bind to the function.
Apr 17 2013
On Wednesday, 17 April 2013 at 07:58:42 UTC, deadalnix wrote:auto is about type inference. Attribute is part of the function type as much as it return type, and so it is expected that auto applied to a function infer its attributes and its return type.I disagree. Attributes are completely separate from return value, and I do not think it is "expected" that auto should infer attributes.The problem you are talking about is very real, but much broader than this auto thing. The problem is that you have no control on what the storage classes bind on. Examples : extern(C) void function() foo; // does extern binds to foo, foo's type or both ? pure function() function() bar; // is bar a pure function ? is bar() pure ? Noth ? How to choose ?Yes, that is a problem, but not related to this change.Back to the subject, if auto bind to the function it must infers attributes, if it binds to the return type, it mustn't. And right now, storage class bind to the function.I think you are confusing separate things here. First, 'auto' is a storage class that means 'no other storage class'. It does NOT mean type inference. You do not need to use 'auto' to get type inference. You cannot use 'auto' in conjunction with other storage classes to get type inference. auto foo(); // type inference const foo(); // type inference auto const foo(); // illegal, two storage classes As you can see, auto is neither sufficient, nor required for type inference. The storage class you use has absolutely nothing to do with type inference. Type inference happens if and only if you do not specify a return type. Storage class and type inference are 100% orthogonal. With that matter cleared up, your argument no longer holds water. It doesn't matter what 'auto' binds to because 'auto' has nothing to do with return type inference, and shouldn't affect attribute inference either. The name of this thread is quite misleading. The proposal also has nothing to do with auto. The proposal is to infer attributes when the return type is inferred. I think it's worth being clear on that otherwise people will confuse storage classes with type/attribute inference.
Apr 17 2013
On 4/17/13, Peter Alexander <peter.alexander.au gmail.com> wrote:Type inference happens if and only if you do not specify a return type.That's not true, you still need to use auto. This function definition is illegal: x() { return 1; } As for being able to use 'const' for type inference it's completely an implementation issue. It's not by design at all. You can even substitute 'auto' for meaningless crap like this in module scope: static x() { return 1; } If return type inference is wanted then 'auto' should be required at all times. What's the point in writing obfuscated code like the above?
Apr 17 2013
On Wednesday, 17 April 2013 at 12:46:53 UTC, Andrej Mitrovic wrote:On 4/17/13, Peter Alexander <peter.alexander.au gmail.com> wrote:You don't need to use auto. Any storage class will do.Type inference happens if and only if you do not specify a return type.That's not true, you still need to use auto. This function definition is illegal: x() { return 1; }As for being able to use 'const' for type inference it's completely an implementation issue. It's not by design at all. You can even substitute 'auto' for meaningless crap like this in module scope: static x() { return 1; } If return type inference is wanted then 'auto' should be required at all times. What's the point in writing obfuscated code like the above?Because it's required? This is illegal: auto const foo(); If you want type inference then you just need to use: const foo(); And yes, it is by design. The spec is quite clear on this issue. Type inference is signalled by lack of return type -- not the presence of auto. auto is only required when no other storage class is wanted, to make the parser happy. auto is nothing whatsoever to do with type inference.
Apr 17 2013
On Wednesday, 17 April 2013 at 13:59:05 UTC, Peter Alexander wrote: [...]If you want type inference then you just need to use: const foo(); And yes, it is by design. The spec is quite clear on this issue. Type inference is signalled by lack of return type -- not the presence of auto. auto is only required when no other storage class is wanted, to make the parser happy. auto is nothing whatsoever to do with type inference.I think you've made some good clarification points. auto is used only when there is no other storage class, and "storage class" is a somewhat misleading term because some storage class's seem to have nothing to do with "storage". The point you made, is that what is being proposed is if or if not D should be extended to perform attribute inference along with type inference. The auto keyword is only required when no other storage class is specified, so it really means that attribute inference will be done all the time unless you specifically specify the attributes. Is this the case? --rt
Apr 17 2013
On 4/17/13, Andrej Mitrovic <andrej.mitrovich gmail.com> wrote:As for being able to use 'const' for type inference it's completely an implementation issue. It's not by design at all.Actually I'm wrong about this now that I've re-read the spec. You can use another storage class instead of auto (strangely I don't remember this being discussed in TDPL though). However there are too many things in DMD which are "storage classes", when they shouldn't be. E.g. property.
Apr 17 2013
On Wednesday, 17 April 2013 at 12:49:41 UTC, Andrej Mitrovic wrote:On 4/17/13, Andrej Mitrovic <andrej.mitrovich gmail.com> wrote:Sorry, just saw this. Ignore previous reply.As for being able to use 'const' for type inference it's completely an implementation issue. It's not by design at all.Actually I'm wrong about this now that I've re-read the spec. You can use another storage class instead of auto (strangely I don't remember this being discussed in TDPL though). However there are too many things in DMD which are "storage classes", when they shouldn't be. E.g. property.
Apr 17 2013
On Wednesday, 17 April 2013 at 12:22:21 UTC, Peter Alexander wrote:On Wednesday, 17 April 2013 at 07:58:42 UTC, deadalnix wrote:auto is generally understood as type inference, so ti isn't an heresy.auto is about type inference. Attribute is part of the function type as much as it return type, and so it is expected that auto applied to a function infer its attributes and its return type.I disagree. Attributes are completely separate from return value, and I do not think it is "expected" that auto should infer attributes.It is, because you can't express both "I want return type inference" and " want full type inference"The problem you are talking about is very real, but much broader than this auto thing. The problem is that you have no control on what the storage classes bind on. Examples : extern(C) void function() foo; // does extern binds to foo, foo's type or both ? pure function() function() bar; // is bar a pure function ? is bar() pure ? Noth ? How to choose ?Yes, that is a problem, but not related to this change.It is sufficient. It is true that it isn't required as absence of type + one storage class means type inference. I kind of oversimplyfied that part. The intent of auto is still type inference, as this is a storage class that mean nothing, except that it allow to omit the type.Back to the subject, if auto bind to the function it must infers attributes, if it binds to the return type, it mustn't. And right now, storage class bind to the function.I think you are confusing separate things here. First, 'auto' is a storage class that means 'no other storage class'. It does NOT mean type inference. You do not need to use 'auto' to get type inference. You cannot use 'auto' in conjunction with other storage classes to get type inference. auto foo(); // type inference const foo(); // type inference auto const foo(); // illegal, two storage classes As you can see, auto is neither sufficient, nor required for type inference. The storage class you use has absolutely nothing to do with type inference. Type inference happens if and only if you do not specify a return type. Storage class and type inference are 100% orthogonal.The name of this thread is quite misleading. The proposal also has nothing to do with auto. The proposal is to infer attributes when the return type is inferred. I think it's worth being clear on that otherwise people will confuse storage classes with type/attribute inference.What storage class stand for is already a blurry topic. I don't think any confusion can be added.
Apr 17 2013
On Wednesday, 17 April 2013 at 16:10:02 UTC, deadalnix wrote:On Wednesday, 17 April 2013 at 12:22:21 UTC, Peter Alexander wrote:It's certainly not helpful if we keep on blurring the concepts. The "auto" keyword currently means nothing except that when no other storage class is present you can specify it to allow the compiler to proceed without error, otherwise type inference is always performed unless inference is overridden with an explicit type. The proposal therefore seems to be about extending D to always perform attribute inference along with type inference unless the attributes are explicitly specified. The question I have is if the proposal wants to extend the meaning of the "auto' keyword so that it will be required in order for attribute inference to take place, but that indeed does confuse things because we're using the same keyword for two completely two different purposes, and it clashes with the use of auto in some cases. -rtOn Wednesday, 17 April 2013 at 07:58:42 UTC, deadalnix wrote:auto is generally understood as type inference, so ti isn't an heresy.auto is about type inference. Attribute is part of the function type as much as it return type, and so it is expected that auto applied to a function infer its attributes and its return type.I disagree. Attributes are completely separate from return value, and I do not think it is "expected" that auto should infer attributes.It is, because you can't express both "I want return type inference" and " want full type inference"The problem you are talking about is very real, but much broader than this auto thing. The problem is that you have no control on what the storage classes bind on. Examples : extern(C) void function() foo; // does extern binds to foo, foo's type or both ? pure function() function() bar; // is bar a pure function ? is bar() pure ? Noth ? How to choose ?Yes, that is a problem, but not related to this change.It is sufficient. It is true that it isn't required as absence of type + one storage class means type inference. I kind of oversimplyfied that part. The intent of auto is still type inference, as this is a storage class that mean nothing, except that it allow to omit the type.Back to the subject, if auto bind to the function it must infers attributes, if it binds to the return type, it mustn't. And right now, storage class bind to the function.I think you are confusing separate things here. First, 'auto' is a storage class that means 'no other storage class'. It does NOT mean type inference. You do not need to use 'auto' to get type inference. You cannot use 'auto' in conjunction with other storage classes to get type inference. auto foo(); // type inference const foo(); // type inference auto const foo(); // illegal, two storage classes As you can see, auto is neither sufficient, nor required for type inference. The storage class you use has absolutely nothing to do with type inference. Type inference happens if and only if you do not specify a return type. Storage class and type inference are 100% orthogonal.The name of this thread is quite misleading. The proposal also has nothing to do with auto. The proposal is to infer attributes when the return type is inferred. I think it's worth being clear on that otherwise people will confuse storage classes with type/attribute inference.What storage class stand for is already a blurry topic. I don't think any confusion can be added.
Apr 17 2013
On Wednesday, 17 April 2013 at 16:26:30 UTC, Rob T wrote:The proposal therefore seems to be about extending D to always perform attribute inference along with type inference unless the attributes are explicitly specified. The question I have is if the proposal wants to extend the meaning of the "auto' keyword so that it will be required in order for attribute inference to take place, but that indeed does confuse things because we're using the same keyword for two completely two different purposes, and it clashes with the use of auto in some cases. -rtThis is a very good description of the change. I don't think auto should be made specific to attribute inference. So I think the discussion should consider: const foo()//... would that be something that should also be a attribute inference. I think I'm still ok with that as it is still requesting inference. Note that you can not specify an inferred const return type. That is this makes a the function const (not valid as a free form function), and not the return type.
Apr 17 2013
On 4/17/2013 10:35 AM, Jesse Phillips wrote:I don't think auto should be made specific to attribute inference. So I think the discussion should consider: const foo()//... would that be something that should also be a attribute inference.Yes, the pull request does that, too.
Apr 17 2013
On 4/17/13 3:58 AM, deadalnix wrote:Note that this is consistent with many choice D made. auto is a storage class. storage class usually stick to the function, not the return type : const Foo bar(); // Error as const qualify bar and not Foo. auto is about type inference. Attribute is part of the function type as much as it return type, and so it is expected that auto applied to a function infer its attributes and its return type. The problem you are talking about is very real, but much broader than this auto thing. The problem is that you have no control on what the storage classes bind on. Examples : extern(C) void function() foo; // does extern binds to foo, foo's type or both ? pure function() function() bar; // is bar a pure function ? is bar() pure ? Noth ? How to choose ? Back to the subject, if auto bind to the function it must infers attributes, if it binds to the return type, it mustn't. And right now, storage class bind to the function.I think this is a solid argument. You may want to paste it in the github discussion for reference. Andrei
Apr 17 2013
On 4/17/2013 12:58 AM, deadalnix wrote:Back to the subject, if auto bind to the function it must infers attributes, if it binds to the return type, it mustn't. And right now, storage class bind to the function.'auto', like all storage class annotations such as 'const', binds to the declaration and the declaration's type. It is perfectly consistent.extern(C) void function() foo; // does extern binds to foo, foo's type or both ?foo is being declared, so it binds to foo.pure function() function() bar; // is bar a pure function ? is bar() pure ?Noth ? How to choose ? bar is being declared, so it binds to bar.
Apr 17 2013
On Wednesday, 17 April 2013 at 19:53:07 UTC, Walter Bright wrote:On 4/17/2013 12:58 AM, deadalnix wrote:Yes I know. That was my point : auto bind to the function according to current spec, so function type should be inferred, which imply both return type and attributes. Points raised in the thread show that people need in general to be able to annotate specifically the return type or whatever, and this is rather difficult with the current state of thing (and also it seems quite hard to fix).Back to the subject, if auto bind to the function it must infers attributes, if it binds to the return type, it mustn't. And right now, storage class bind to the function.'auto', like all storage class annotations such as 'const', binds to the declaration and the declaration's type. It is perfectly consistent.extern(C) void function() foo; // does extern binds to foo,foo's type or both ? foo is being declared, so it binds to foo.pure function() function() bar; // is bar a pure function ?is bar() pure ? Noth ? How to choose ? bar is being declared, so it binds to bar.
Apr 17 2013
On 4/17/2013 6:28 PM, deadalnix wrote:Points raised in the thread show that people need in general to be able to annotate specifically the return type or whatever, and this is rather difficult with the current state of thing (and also it seems quite hard to fix).To annotate the return type specifically with, say, const: const(T) foo(); And in fact const with parens works as a general type constructor: const(T)* foo(); // return mutable pointer to const T const without parens applies to the declaration.
Apr 17 2013
On Thursday, 18 April 2013 at 01:52:10 UTC, Walter Bright wrote:To annotate the return type specifically with, say, const: const(T) foo(); And in fact const with parens works as a general type constructor: const(T)* foo(); // return mutable pointer to const T const without parens applies to the declaration.This doesn't work with many attributes.
Apr 17 2013
On Wednesday, 17 April 2013 at 07:04:16 UTC, Peter Alexander wrote:On Wednesday, 17 April 2013 at 01:55:54 UTC, Jesse Phillips wrote:I strongly believe you should never use "auto" for API types, because it is too easy to break them. If Dont-Repeat-Yourself/complex types is a problem, they should be solved at the other end by enhancing function body type inference. An alternative approach would be to do this optimization during optimization. However, this means it has to be reimplemented in dmd, LLVM, GCC separately. This is e.g. the case for pure-inference in C code.On Tuesday, 16 April 2013 at 20:21:00 UTC, Peter Alexander wrote:Often enough. I often find myself returning ranges, which are almost invariably complex template types. And, to be honest, I would just like to use auto without being locked into inferred attributes. It just feels wrong that these things should be conflated, and I get the feeling we will regret this later on when D starts to be used in larger projects.This is the point I have a problem with:How frequently do you write a non-templated function which returns a complex template type? It isn't something I really think about, but I'm pretty sure if I am returning a complex template type I've already got the function a template.I find this unacceptable. Thanks to the proliferation of template code in D, it is often rather difficult to spell out return types. Indeed, this is part of the original reason for auto's existence. Denying return type deduction for this use case is a major inconvenience.2.2. One cannot opt out of nothrow or pure with auto functions.This argument has one solid answer: don't use auto when the need is to specify an attribute pattern explicitly.
Apr 17 2013
On Wednesday, 17 April 2013 at 08:39:37 UTC, qznc wrote:An alternative approach would be to do this optimization during optimization. However, this means it has to be reimplemented in dmd, LLVM, GCC separately. This is e.g. the case for pure-inference in C code.LDC/LLVM does something very similar already (on the IR level), but obviously not across multiple compilation units, as the function body has to be available to the optimizer. David
Apr 17 2013
On Wednesday, 17 April 2013 at 07:04:16 UTC, Peter Alexander wrote:Often enough. I often find myself returning ranges, which are almost invariably complex template types.Hmm, I'm still trying to decide if this is a major concern. Generally when returning a range, this is done because operations are being performed on a container, the specific container isn't important and many times nor is the type in the container. This means my function is a template. The times when I could see returning a complex type where the function isn't templates is when I'm loading the data to be consumed. In this case I generally will return the container itself (since ownership isn't with the called function).
Apr 17 2013
On 4/17/13, Jesse Phillips <Jessekphillips+d gmail.com> wrote:How frequently do you write a non-templated function which returns a complex template type?This can be common if the function is a member function that returns some kind of a range on internal data, for example: import std.range; struct S { int[] arr; auto range() { return cycle(arr).stride(2); } } There's no need to make "range" a template here, but specifying the return type isn't always possible or easy to do.
Apr 17 2013
On Tue, 16 Apr 2013 21:20:59 +0100, Peter Alexander <peter.alexander.au gmail.com> wrote:This is the point I have a problem with:Solution: You use 'auto' and compile the code producing a .di. With the fix Andrei mentioned the .di has the full and complete function signature, without 'auto', including return type and all deduced attributes etc. You alter the signature to suit and copy it back to the .d file. This is how it should be done, IMO, because now you've explicitly defined your library interface so when you accidentally change/break it by modifying the code in the library function body, the compiler will immediately tell you. It's win-win or so it seems to me.I find this unacceptable. Thanks to the proliferation of template code in D, it is often rather difficult to spell out return types. Indeed, this is part of the original reason for auto's existence. Denying return type deduction for this use case is a major inconvenience.2.2. One cannot opt out of nothrow or pure with auto functions.This argument has one solid answer: don't use auto when the need is to specify an attribute pattern explicitly.It is an unfortunate situation we are in, with D working best with everything inferred and CTFE-able, yet with those things completely at odds with modularity.I can't see how it can be any other way. An interface needs to be clearly defined or it's consumer can't use it. 'auto' does not suit that purpose at all, currently, and this doesn't change with this pull. R -- Using Opera's revolutionary email client: http://www.opera.com/mail/
Apr 17 2013
On 4/17/13, Regan Heath <regan netmail.co.nz> wrote:Solution: You use 'auto' and compile the code producing a .di. With the fix Andrei mentioned the .di has the full and complete function signature, without 'auto', including return type and all deduced attributes etc.This doesn't work with voldemort types.
Apr 17 2013
On 4/17/13 8:09 AM, Andrej Mitrovic wrote:On 4/17/13, Regan Heath<regan netmail.co.nz> wrote:It's not supposed to; voldemort functions are by definition non-modular. AndreiSolution: You use 'auto' and compile the code producing a .di. With the fix Andrei mentioned the .di has the full and complete function signature, without 'auto', including return type and all deduced attributes etc.This doesn't work with voldemort types.
Apr 17 2013
On 4/17/2013 8:14 AM, Andrei Alexandrescu wrote:On 4/17/13 8:09 AM, Andrej Mitrovic wrote:The whole point of voldemort functions is that you cannot name the return type, so there is no way to write a signature for it to put in the .di file. Hence, it not working with voldemort types is moot.On 4/17/13, Regan Heath<regan netmail.co.nz> wrote:It's not supposed to; voldemort functions are by definition non-modular.Solution: You use 'auto' and compile the code producing a .di. With the fix Andrei mentioned the .di has the full and complete function signature, without 'auto', including return type and all deduced attributes etc.This doesn't work with voldemort types.
Apr 17 2013
On 4/16/13 4:20 PM, Peter Alexander wrote:This is the point I have a problem with:Attribute inference is always done for templates. AndreiI find this unacceptable. Thanks to the proliferation of template code in D, it is often rather difficult to spell out return types.2.2. One cannot opt out of nothrow or pure with auto functions.This argument has one solid answer: don't use auto when the need is to specify an attribute pattern explicitly.
Apr 17 2013
On 4/17/2013 8:07 AM, Andrei Alexandrescu wrote:On 4/16/13 4:20 PM, Peter Alexander wrote:And, I might add, I cannot recall a single adverse issue that has caused.This is the point I have a problem with:Attribute inference is always done for templates.I find this unacceptable. Thanks to the proliferation of template code in D, it is often rather difficult to spell out return types.2.2. One cannot opt out of nothrow or pure with auto functions.This argument has one solid answer: don't use auto when the need is to specify an attribute pattern explicitly.
Apr 17 2013
On Wednesday, April 17, 2013 12:35:07 Walter Bright wrote:On 4/17/2013 8:07 AM, Andrei Alexandrescu wrote:If anything, the fact that it doesn't infer more is the problem. The primary risk is if a particular set of template arguments previously resulted in the function being pure, nothrow, or safe but no longer do so after some code changes, and code using the template which requires pure, nothrow, or safe then no longer compiles. But odds are that that's the fault changes to the template arguments and not the template, and requiring explict attributes wouldn't fix the problem anyway, because then you're either stuck with a combinatorial explosion of template declarations or making it so that the template always has the same set of attributes and therefore only works with code that works with that exact set of attributes. Non-templated auto functions are not generally in the same boat, because their types are usually well-known, and therefore explicitly marking the attributes that you want works, but it may still be reasonable to do attribute inferrence for them. - Jonathan M DavisOn 4/16/13 4:20 PM, Peter Alexander wrote:And, I might add, I cannot recall a single adverse issue that has caused.This is the point I have a problem with:Attribute inference is always done for templates.I find this unacceptable. Thanks to the proliferation of template code in D, it is often rather difficult to spell out return types.2.2. One cannot opt out of nothrow or pure with auto functions.This argument has one solid answer: don't use auto when the need is to specify an attribute pattern explicitly.
Apr 22 2013
On 04/16/2013 07:06 PM, Dmitry Olshansky wrote:16-Apr-2013 19:22, Andrei Alexandrescu пишет:This should not be an issue any more. http://d.puremagic.com/issues/show_bug.cgi?id=7511There's a discussion that may be of interest to the larger community: https://github.com/D-Programming-Language/dmd/pull/1877 AndreiIn the same vane - how about attribute inference for "ordinary" functions? I recall that just a month ago I had an interesting case - a normal function inside of a templated struct. The thing is that depending on some parameters (of struct) it could be safe or not. But it's not a template itself and its return type is always bool. In the end I just added an empty CT parameter set making it a template. ...
Apr 16 2013
17-Apr-2013 01:13, Timon Gehr пишет:On 04/16/2013 07:06 PM, Dmitry Olshansky wrote:So it was a bug after all. Good to see it fixed. -- Dmitry Olshansky16-Apr-2013 19:22, Andrei Alexandrescu пишет:This should not be an issue any more. http://d.puremagic.com/issues/show_bug.cgi?id=7511There's a discussion that may be of interest to the larger community: https://github.com/D-Programming-Language/dmd/pull/1877 AndreiIn the same vane - how about attribute inference for "ordinary" functions? I recall that just a month ago I had an interesting case - a normal function inside of a templated struct. The thing is that depending on some parameters (of struct) it could be safe or not. But it's not a template itself and its return type is always bool. In the end I just added an empty CT parameter set making it a template. ...
Apr 17 2013
On 04/16/2013 05:22 PM, Andrei Alexandrescu wrote:There's a discussion that may be of interest to the larger community: https://github.com/D-Programming-Language/dmd/pull/1877 AndreiI think inferring the return type and inferring the attributes are mostly orthogonal concerns. (and both are unrelated to the 'auto' storage class'.) But since there is precedent for conflating attribute inference with required function bodies, it might be fine. In order not to be hit by Kenji's worst case debug output scenario, use something like the following: void dw(T...)(T args)pure nothrow trusted{ debug try{writeln(args);}catch{assert(0);} else static assert(0); }
Apr 16 2013
On Tuesday, 16 April 2013 at 21:40:18 UTC, Timon Gehr wrote:I think inferring the return type and inferring the attributes are mostly orthogonal concerns. (and both are unrelated to the 'auto' storage class'.) But since there is precedent for conflating attribute inference with required function bodies, it might be fine.auto is a storage class, so it should be possible to explicitly specify the return type : auto ulong foo() { // Infered pure, nothrow and everything. Return type is ulong (would have been int if inferred). return 12; }
Apr 16 2013
On Tuesday, 16 April 2013 at 15:22:56 UTC, Andrei Alexandrescu wrote:There's a discussion that may be of interest to the larger community: https://github.com/D-Programming-Language/dmd/pull/1877 AndreiOh Yes, Yes, Yes, god Yes ! Yes, Yes, Yes ! Ho Yes !
Apr 16 2013
On 4/16/2013 7:01 PM, deadalnix wrote:On Tuesday, 16 April 2013 at 15:22:56 UTC, Andrei Alexandrescu wrote:Not sure what you're saying yes to - the pro or the con?There's a discussion that may be of interest to the larger community: https://github.com/D-Programming-Language/dmd/pull/1877 AndreiOh Yes, Yes, Yes, god Yes ! Yes, Yes, Yes ! Ho Yes !
Apr 16 2013
On Wednesday, 17 April 2013 at 02:22:31 UTC, Walter Bright wrote:On 4/16/2013 7:01 PM, deadalnix wrote:Yes to the pull request, yes to the inference. I agree with you, I know it may sound hard to believe, but it had to happen one day :DOn Tuesday, 16 April 2013 at 15:22:56 UTC, Andrei Alexandrescu wrote:Not sure what you're saying yes to - the pro or the con?There's a discussion that may be of interest to the larger community: https://github.com/D-Programming-Language/dmd/pull/1877 AndreiOh Yes, Yes, Yes, god Yes ! Yes, Yes, Yes ! Ho Yes !
Apr 16 2013
On 4/16/2013 7:30 PM, deadalnix wrote:I agree with you, I know it may sound hard to believe, but it had to happen one day :DI'll mark it on my calendar! BTW, I think we can do attribute inference for all private functions, too.
Apr 16 2013
On Wednesday, 17 April 2013 at 04:44:59 UTC, Walter Bright wrote:On 4/16/2013 7:30 PM, deadalnix wrote:Don't this risk to conflict with LTO ?I agree with you, I know it may sound hard to believe, but it had to happen one day :DI'll mark it on my calendar! BTW, I think we can do attribute inference for all private functions, too.
Apr 16 2013
On 4/16/2013 10:31 PM, deadalnix wrote:On Wednesday, 17 April 2013 at 04:44:59 UTC, Walter Bright wrote:How so?BTW, I think we can do attribute inference for all private functions, too.Don't this risk to conflict with LTO ?
Apr 16 2013
On Wednesday, 17 April 2013 at 05:55:07 UTC, Walter Bright wrote:On 4/16/2013 10:31 PM, deadalnix wrote:Never mind, I think I was wrong. It is a good idea.On Wednesday, 17 April 2013 at 04:44:59 UTC, Walter Bright wrote:How so?BTW, I think we can do attribute inference for all private functions, too.Don't this risk to conflict with LTO ?
Apr 16 2013
On Tuesday, 16 April 2013 at 15:22:56 UTC, Andrei Alexandrescu wrote:There's a discussion that may be of interest to the larger community: https://github.com/D-Programming-Language/dmd/pull/1877 AndreiI'm not convinced that specifying the exact return type is such a huge inconvenience to those who use separate compilation. I don't view this as an inconsistency, but definitely a change to why one might choose to use auto. I'm pretty much for this change. However, I also think it would be good to introduce attributes to specify a throwing function as it would have uses in a file headed with nothrow: I'd suggest the same for pure, but 'nopure' isn't the greatest of names. Anyway it is the same reason we have system, I'd just hope they don't get added as throws and nopure as that would be inconsistent.
Apr 16 2013
W dniu 16.04.2013 17:22, Andrei Alexandrescu pisze:There's a discussion that may be of interest to the larger community: https://github.com/D-Programming-Language/dmd/pull/1877On demand inference FTW! void fn() auto { ... } auto fn() auto { ... }
Apr 17 2013
On 2013-04-17 10:31, Piotr Szturmaj wrote:On demand inference FTW! void fn() auto { ... } auto fn() auto { ... }Double auto, hehe. -- /Jacob Carlborg
Apr 17 2013
On 4/17/13 4:31 AM, Piotr Szturmaj wrote:W dniu 16.04.2013 17:22, Andrei Alexandrescu pisze:I think this is a bit much. Simplicity is a good commodity to allow oneself of, and absorbing two different meanings of 'auto' in the same construct is not simple. AndreiThere's a discussion that may be of interest to the larger community: https://github.com/D-Programming-Language/dmd/pull/1877On demand inference FTW! void fn() auto { ... } auto fn() auto { ... }
Apr 17 2013
On 4/17/2013 8:12 AM, Andrei Alexandrescu wrote:I think this is a bit much. Simplicity is a good commodity to allow oneself of, and absorbing two different meanings of 'auto' in the same construct is not simple.It also goes back to your discussion of the observation that programmers do not go back and annotate the code, even for large benefits.
Apr 17 2013
On 2013-04-16 15:22:56 +0000, Andrei Alexandrescu <SeeWebsiteForEmail erdani.org> said:There's a discussion that may be of interest to the larger community: https://github.com/D-Programming-Language/dmd/pull/1877I agree attribute inference is needed. I don't think 'auto' is a suitable trigger. It'll encourage people to replace the return type on existing and new functions (making things more obscure) as a way get attribute inference. Instead, all functions should have the benefit of attribute inference. I'd rather have a marker to prevent it when needed than have to opt it. For instance, if providing a stable API for a library is a concern, put that marker on those exported functions. Perhaps "export" could be that marker. Unfortunately, that'll be slow. DMD will have to reprocess the function body for every called function transitively each time it compiles. The solution for that is to use .di files as a cache: in the process of creating a .di file the inferred attributes could be made explicit. Then disallow attribute inference for functions parsed from a .di file (so you can still provide a body for inlining). All this might pose a tricky cache-invalidation problem however: when a function somewhere changes you need to purge all the dependent di files *before* recompiling anything. :-/ Compilation speed is not a problem for functions with the "auto" return type because there are only a few of them. At least that's how it is right now. Allowing attribute inference only for this category of function might change those statistics after a few months in the wild, and then you'll have the compilation performance problems described above. Which might not be a bad thing, as then you'll need to overhaul the compilation model to fix this, and then you'll be able to enable it for all functions. ;-) -- Michel Fortin michel.fortin michelf.ca http://michelf.ca/
Apr 17 2013
On 4/17/2013 10:37 AM, Michel Fortin wrote:Compilation speed is not a problem for functions with the "auto" return type because there are only a few of them.It is not a problem right now because the compiler has to semantically analyze their function bodies already in order to determine the return type. It is insignificant to additionally gather the attribute information.
Apr 17 2013
On 2013-04-17 19:05:01 +0000, Walter Bright <newshound2 digitalmars.com> said:On 4/17/2013 10:37 AM, Michel Fortin wrote:True, but beside the point. My point was that if auto allows attribute inference people will be tempted to (and will do) change their return types to auto in their programs just to get that benefit (no one wants to annotate all their functions). Thus, as more and more functions become "auto" compile times will become slower. Pushed to the extreme, you'd get the same result as if you were inferring attributes for all functions, plus more confusion because all the return types are obfuscated. -- Michel Fortin michel.fortin michelf.ca http://michelf.ca/Compilation speed is not a problem for functions with the "auto" return type because there are only a few of them.It is not a problem right now because the compiler has to semantically analyze their function bodies already in order to determine the return type. It is insignificant to additionally gather the attribute information.
Apr 17 2013
On Tuesday, 16 April 2013 at 15:22:56 UTC, Andrei Alexandrescu wrote:There's a discussion that may be of interest to the larger community: https://github.com/D-Programming-Language/dmd/pull/1877 AndreiI wish to bring Someboddies consern to this form. What does attribute inference mean for inheritance? Do all derived classes need to be known for inference to take place? Not having the ability to claim a base function can be overridden with a throwing function could cause some issue... Hmm but we can still specify the type so I guess it still isn't a major, but I could see auto being used more causing a library writer to make restrictions on their function because what they write is applicable but not really considering derived classes could reasonably throw.
Apr 17 2013
On 4/17/2013 10:41 AM, Jesse Phillips wrote:I wish to bring Someboddies consern to this form. What does attribute inference mean for inheritance?I specifically addressed his concern in the git page: "This is the same issue as defining a function with 'auto' in one place and referring to it having a specific type/attribute in another. So I think all the same arguments and reasoning discussed above apply equally."
Apr 17 2013
On 4/17/2013 12:06 PM, Walter Bright wrote:On 4/17/2013 10:41 AM, Jesse Phillips wrote:His followup doesn't change that. It's still the same issue (covariance) which is discussed repeatedly.I wish to bring Someboddies consern to this form. What does attribute inference mean for inheritance?I specifically addressed his concern in the git page: "This is the same issue as defining a function with 'auto' in one place and referring to it having a specific type/attribute in another. So I think all the same arguments and reasoning discussed above apply equally."
Apr 17 2013
On Wednesday, 17 April 2013 at 19:06:42 UTC, Walter Bright wrote:On 4/17/2013 10:41 AM, Jesse Phillips wrote:Initially I thought you were replying to something further up in the thread as it seemed more applicable to something I read before, and I did feel the issue of inheritance was different. But I think you are correct, it is the same issue.I wish to bring Someboddies consern to this form. What does attribute inference mean for inheritance?I specifically addressed his concern in the git page: "This is the same issue as defining a function with 'auto' in one place and referring to it having a specific type/attribute in another. So I think all the same arguments and reasoning discussed above apply equally."
Apr 17 2013
Th On 04/17/2013 09:06 PM, Walter Bright wrote:On 4/17/2013 10:41 AM, Jesse Phillips wrote:Why is this a valid form of reasoning? The signature of a function that has its return type inferred includes the function body. Furthermore, it is not the same issue. It is the dual issue. The distinction is very relevant because pure and nothrow are designed in an asymmetric way, given inference. Attributes can force the specification in one direction only (provide more guarantees to callers), but not in the other one (require less from subclasses). The concerns the latter can certainly not be dismissed by using the same arguments and reasoning as for the former without any further examination.I wish to bring Someboddies consern to this form. What does attribute inference mean for inheritance?I specifically addressed his concern in the git page: "This is the same issue as defining a function with 'auto' in one place and referring to it having a specific type/attribute in another. So I think all the same arguments and reasoning discussed above apply equally."
Apr 17 2013
On 4/17/2013 3:20 PM, Timon Gehr wrote:They are the same - adding the attribute retains covariance."This is the same issue as defining a function with 'auto' in one place and referring to it having a specific type/attribute in another. So I think all the same arguments and reasoning discussed above apply equally."Why is this a valid form of reasoning? The signature of a function that has its return type inferred includes the function body. Furthermore, it is not the same issue. It is the dual issue. The distinction is very relevant because pure and nothrow are designed in an asymmetric way,given inference. Attributes can force the specification in one direction only (provide more guarantees to callers), but not in the other one (require less from subclasses).Pure and nothrow provide more guarantees, hence covariance.The concerns the latter can certainly not be dismissed by using the same arguments and reasoning as for the former without any further examination.They're both the same issue of covariance.
Apr 17 2013
On Wednesday, 17 April 2013 at 23:46:08 UTC, Walter Bright wrote:On 4/17/2013 3:20 PM, Timon Gehr wrote:No : if a super function suddenly become pure because its implementation changed, then all kind of subclasses can broke. Generally, it is a bad idea for a super class to be aware of its subclasses. But defining a function that is going to be overridden as auto is asking for trouble in the first place.They are the same - adding the attribute retains covariance."This is the same issue as defining a function with 'auto' in one place and referring to it having a specific type/attribute in another. So I think all the same arguments and reasoning discussed above apply equally."Why is this a valid form of reasoning? The signature of a function that has its return type inferred includes the function body. Furthermore, it is not the same issue. It is the dual issue. The distinction is very relevant because pure and nothrow are designed in an asymmetric way,
Apr 17 2013
On 4/17/2013 6:32 PM, deadalnix wrote:No : if a super function suddenly become pure because its implementation changed, then all kind of subclasses can broke. Generally, it is a bad idea for a super class to be aware of its subclasses.Yet this is the same issue as auto for other functions.But defining a function that is going to be overridden as auto is asking for trouble in the first place.Of course.
Apr 17 2013
On 04/18/2013 01:46 AM, Walter Bright wrote:On 4/17/2013 3:20 PM, Timon Gehr wrote:No. In one case you infer guarantees only. (those restrict what can be done in the future without potentially breaking code, but that's it.) In the other case you infer restrictions too, in an unsound way because the inference does not take into consideration the subclasses.They are the same"This is the same issue as defining a function with 'auto' in one place and referring to it having a specific type/attribute in another. So I think all the same arguments and reasoning discussed above apply equally."Why is this a valid form of reasoning? The signature of a function that has its return type inferred includes the function body. Furthermore, it is not the same issue. It is the dual issue. The distinction is very relevant because pure and nothrow are designed in an asymmetric way,- adding the attribute retains covariance.I am sorry, but I do not understand your notion of covariance. Covariance is a precise notion from category theory. (A mapping between categories that conserves morphisms is called a covariant functor.)class C{ final foo(){ ... } // <- this signature is foo's signature only auto bar(){ ... } // <- this signature has to fit all overrides } In the first case, inference is mostly fine because you cannot unduly restrict someone: The signature will actually match foo's implementation. In the second case you cannot infer the attributes because you do not know all subclasses. The signature will potentially not match all overrides. Case in point, I just noticed the following regression on git head: import std.stdio; class C(T){ T foo(){ return 2; } } class D : C!int{ override int foo(){ writeln(super.foo()); return 3; } // error } Inference shouldn't be done for virtual functions. http://d.puremagic.com/issues/show_bug.cgi?id=9952given inference. Attributes can force the specification in one direction only (provide more guarantees to callers), but not in the other one (require less from subclasses).Pure and nothrow provide more guarantees, hence covariance.The concerns the latter can certainly not be dismissed by using the same arguments and reasoning as for the former without any further examination.They're both the same issue of covariance.
Apr 17 2013
On 4/17/2013 11:49 PM, Timon Gehr wrote:I am sorry, but I do not understand your notion of covariance.Overriding functions can add pure or nothrow and remain covariant.In the second case you cannot infer the attributes because you do not know all subclasses. The signature will potentially not match all overrides.If you want a precise signature, don't use auto. It's the same case as everywhere else.Case in point, I just noticed the following regression on git head: import std.stdio; class C(T){ T foo(){ return 2; } } class D : C!int{ override int foo(){ writeln(super.foo()); return 3; } // error } Inference shouldn't be done for virtual functions. http://d.puremagic.com/issues/show_bug.cgi?id=9952This is not an auto issue.
Apr 18 2013
On 4/18/13 2:49 AM, Timon Gehr wrote:On 04/18/2013 01:46 AM, Walter Bright wrote:I think he means subtyping. An attributed function (pure, nothrow) is a subtype of a non-attributed function. That means it can substitute the non-attributed function. Andrei- adding the attribute retains covariance.I am sorry, but I do not understand your notion of covariance.
Apr 18 2013
On 4/16/2013 8:22 AM, Andrei Alexandrescu wrote:There's a discussion that may be of interest to the larger community: https://github.com/D-Programming-Language/dmd/pull/1877What do you think of this: typeof(return) foo(int x) { return x; } ? That would only infer the return type, not the attributes.
Apr 17 2013
On Thursday, 18 April 2013 at 02:40:42 UTC, Walter Bright wrote:On 4/16/2013 8:22 AM, Andrei Alexandrescu wrote:Very nice !There's a discussion that may be of interest to the larger community: https://github.com/D-Programming-Language/dmd/pull/1877What do you think of this: typeof(return) foo(int x) { return x; } ? That would only infer the return type, not the attributes.
Apr 17 2013
On Thursday, 18 April 2013 at 02:40:42 UTC, Walter Bright wrote:On 4/16/2013 8:22 AM, Andrei Alexandrescu wrote:I don't actually have an opinion on whether attributes should be inferred, but ' auto' (as opposed to ' infer') would be a relatively innocuous way to do it explicitly instead of implicitly.There's a discussion that may be of interest to the larger community: https://github.com/D-Programming-Language/dmd/pull/1877What do you think of this: typeof(return) foo(int x) { return x; } ? That would only infer the return type, not the attributes.
Apr 17 2013
On 4/17/2013 7:50 PM, Zach the Mystic wrote:On Thursday, 18 April 2013 at 02:40:42 UTC, Walter Bright wrote:Except that we already support typeof(return) inside of a function.On 4/16/2013 8:22 AM, Andrei Alexandrescu wrote:I don't actually have an opinion on whether attributes should be inferred, but ' auto' (as opposed to ' infer') would be a relatively innocuous way to do it explicitly instead of implicitly.There's a discussion that may be of interest to the larger community: https://github.com/D-Programming-Language/dmd/pull/1877What do you think of this: typeof(return) foo(int x) { return x; } ? That would only infer the return type, not the attributes.
Apr 17 2013
On Thursday, 18 April 2013 at 03:19:38 UTC, Walter Bright wrote:On 4/17/2013 7:50 PM, Zach the Mystic wrote:Yeah, I basically agree. If I had to choose right now, typeof(return) makes more sense. It relies on the assumption that most of the time when you want to 'auto' the return type, you also are okay with autoing the attributes (hence typeof(return) will be much rarer than 'auto'). It seems like a pretty safe assumption to make. And it's weird but ' ' is just uglier than things without ' ', despite that it would be nice for UDAs and other attributes if that weren't the case.On Thursday, 18 April 2013 at 02:40:42 UTC, Walter Bright wrote:Except that we already support typeof(return) inside of a function.On 4/16/2013 8:22 AM, Andrei Alexandrescu wrote:I don't actually have an opinion on whether attributes should be inferred, but ' auto' (as opposed to ' infer') would be a relatively innocuous way to do it explicitly instead of implicitly.There's a discussion that may be of interest to the larger community: https://github.com/D-Programming-Language/dmd/pull/1877What do you think of this: typeof(return) foo(int x) { return x; } ? That would only infer the return type, not the attributes.
Apr 17 2013
W dniu 18.04.2013 04:50, Zach the Mystic pisze:On Thursday, 18 April 2013 at 02:40:42 UTC, Walter Bright wrote:And this can apply to whole scopes.On 4/16/2013 8:22 AM, Andrei Alexandrescu wrote:I don't actually have an opinion on whether attributes should be inferred, but ' auto' (as opposed to ' infer') would be a relatively innocuous way to do it explicitly instead of implicitly.There's a discussion that may be of interest to the larger community: https://github.com/D-Programming-Language/dmd/pull/1877What do you think of this: typeof(return) foo(int x) { return x; } ? That would only infer the return type, not the attributes.
Apr 17 2013
On Thursday, 18 April 2013 at 03:42:50 UTC, Piotr Szturmaj wrote:W dniu 18.04.2013 04:50, Zach the Mystic pisze:Yeah, that's true... 'typeof(return):' would not look good at the top of a file. I feel like this feature is attempting to turn on a vacuum, seeing how many explicit things can be sucked into the implicit vortex. I think the gold medal would be if there were a way to do everything implicitly, but some things may resist being sucked in, and for good reason. The syntax ' auto' seems like a bronze medal solution, so I'd be glad to see it lose to something better.On Thursday, 18 April 2013 at 02:40:42 UTC, Walter Bright wrote:And this can apply to whole scopes.On 4/16/2013 8:22 AM, Andrei Alexandrescu wrote:I don't actually have an opinion on whether attributes should be inferred, but ' auto' (as opposed to ' infer') would be a relatively innocuous way to do it explicitly instead of implicitly.There's a discussion that may be of interest to the larger community: https://github.com/D-Programming-Language/dmd/pull/1877What do you think of this: typeof(return) foo(int x) { return x; } ? That would only infer the return type, not the attributes.
Apr 17 2013
2013/4/18 Walter Bright <newshound2 digitalmars.com>On 4/16/2013 8:22 AM, Andrei Alexandrescu wrote:It will break existing code. int foo() { typeof(return) bar() { return 1; } return bar(); } typeof(return) represents the return type of foo, that is int. Kenji HaraThere's a discussion that may be of interest to the larger community: https://github.com/D-**Programming-Language/dmd/pull/**1877<https://github.com/D-Programming-Language/dmd/pull/1877>What do you think of this: typeof(return) foo(int x) { return x; } ? That would only infer the return type, not the attributes.
Apr 17 2013
On Thursday, 18 April 2013 at 05:59:20 UTC, kenji hara wrote:It will break existing code. int foo() { typeof(return) bar() { return 1; } return bar(); } typeof(return) represents the return type of foo, that is int.That is true :( Don't seem fixable.
Apr 17 2013
On 4/17/2013 11:34 PM, deadalnix wrote:On Thursday, 18 April 2013 at 05:59:20 UTC, kenji hara wrote:It is fixable if it is special cased, but special cases stink.It will break existing code. int foo() { typeof(return) bar() { return 1; } return bar(); } typeof(return) represents the return type of foo, that is int.That is true :( Don't seem fixable.
Apr 17 2013
On 4/18/13 2:38 AM, Walter Bright wrote:On 4/17/2013 11:34 PM, deadalnix wrote:Thanks Kenji for a surgical destruction. AndreiOn Thursday, 18 April 2013 at 05:59:20 UTC, kenji hara wrote:It is fixable if it is special cased, but special cases stink.It will break existing code. int foo() { typeof(return) bar() { return 1; } return bar(); } typeof(return) represents the return type of foo, that is int.That is true :( Don't seem fixable.
Apr 18 2013
W dniu 18.04.2013 16:58, Andrei Alexandrescu pisze:On 4/18/13 2:38 AM, Walter Bright wrote:What about this: auto inferReturnTypeAndAttributes() { ... } auto(return) inferOnlyReturnType() { ... } or since all attributes are constraints, it can be rewritten to: auto inferOnlyReturnType() pure nothrow safe { ... } It really doesn't make sense to infer impurity, throwing or unsafety because these are the default. I imagine there are some use cases where programmer for example wants to infer all but purity, possibly because some other part of the code relies on pure behavior of his function, and he doesn't care about the other attributes. Example of pure function where nothrow and safety are inferred: auto inferAllButPurity() pure { ... } To sum up: 1. auto - infers all 2. auto(return) - infers only a return type 3. auto fn() attrs... - infers return type and all not specified attributes Second and third are equivalent, thus auto(return) is optional. There were some voices about breaking overriden functions by adding/inferring superclass function attribute. I think this is an oversight, virtual functions should not have attributes inferred.On 4/17/2013 11:34 PM, deadalnix wrote:Thanks Kenji for a surgical destruction.On Thursday, 18 April 2013 at 05:59:20 UTC, kenji hara wrote:It is fixable if it is special cased, but special cases stink.It will break existing code. int foo() { typeof(return) bar() { return 1; } return bar(); } typeof(return) represents the return type of foo, that is int.That is true :( Don't seem fixable.
Apr 19 2013
On Friday, 19 April 2013 at 12:43:49 UTC, Piotr Szturmaj wrote:What about this: auto inferReturnTypeAndAttributes() { ... } auto(return) inferOnlyReturnType() { ... } or since all attributes are constraints, it can be rewritten to: auto inferOnlyReturnType() pure nothrow safe { ... } It really doesn't make sense to infer impurity, throwing or unsafety because these are the default. I imagine there are some use cases where programmer for example wants to infer all but purity, possibly because some other part of the code relies on pure behavior of his function, and he doesn't care about the other attributes. Example of pure function where nothrow and safety are inferred: auto inferAllButPurity() pure { ... } To sum up: 1. auto - infers all 2. auto(return) - infers only a return type 3. auto fn() attrs... - infers return type and all not specified attributes Second and third are equivalent, thus auto(return) is optional. There were some voices about breaking overriden functions by adding/inferring superclass function attribute. I think this is an oversight, virtual functions should not have attributes inferred.I like this. It provides a good balance of control and automation. how would template functions be treated with auto(return)?
Apr 19 2013
W dniu 19.04.2013 15:43, John Colvin pisze:I like this. It provides a good balance of control and automation. how would template functions be treated with auto(return)?I see no need for special treating of template functions. In this case only return type would be inferred. Programmers should then specify attributes explicitly. By default, template functions with auto(return) would be impure, throwing and unsafe.
Apr 19 2013
On Friday, 19 April 2013 at 12:43:49 UTC, Piotr Szturmaj wrote:What about this: auto inferReturnTypeAndAttributes() { ... } auto(return) inferOnlyReturnType() { ... } or since all attributes are constraints, it can be rewritten to: auto inferOnlyReturnType() pure nothrow safe { ... } It really doesn't make sense to infer impurity, throwing or unsafety because these are the default. I imagine there are some use cases where programmer for example wants to infer all but purity, possibly because some other part of the code relies on pure behavior of his function, and he doesn't care about the other attributes. Example of pure function where nothrow and safety are inferred: auto inferAllButPurity() pure { ... } To sum up: 1. auto - infers all 2. auto(return) - infers only a return type 3. auto fn() attrs... - infers return type and all not specified attributes Second and third are equivalent, thus auto(return) is optional. There were some voices about breaking overriden functions by adding/inferring superclass function attribute. I think this is an oversight, virtual functions should not have attributes inferred.Except for 2, this is already what is proposed. As of for 2 I'd rather have a standard way to have attribute binding to the return type or the declaration. This is a recurring problem, and auto is simply one instance of it. auto applied to the return type means that we infers the return type, applied to the function it means infers return type AND attributes.
Apr 19 2013
On 4/19/2013 6:55 AM, deadalnix wrote:As of for 2 I'd rather have a standard way to have attribute binding to the return type or the declaration. This is a recurring problem, and auto is simply one instance of it.I'm not understanding it being a recurring problem. There is a recurring misunderstanding that attributes are applying to a type when they are defined as applying to the declaration.auto applied to the return type means that we infers the return type, applied to the function it means infers return type AND attributes.auto never applies to a type, it always applies to the declaration and hence the type of that declaration.
Apr 19 2013
On Friday, 19 April 2013 at 19:06:39 UTC, Walter Bright wrote:On 4/19/2013 6:55 AM, deadalnix wrote:What is type of an impure function that return a pure, extern(C) function n D ?As of for 2 I'd rather have a standard way to have attribute binding to the return type or the declaration. This is a recurring problem, and auto is simply one instance of it.I'm not understanding it being a recurring problem. There is a recurring misunderstanding that attributes are applying to a type when they are defined as applying to the declaration.
Apr 19 2013
On 04/19/2013 09:34 PM, deadalnix wrote:On Friday, 19 April 2013 at 19:06:39 UTC, Walter Bright wrote:Currently, it exists, yet cannot be named, and the formatted output of the compiler is wrong. alias extern(C) int function()pure P; P foo(){ return null; } pragma(msg, typeof(&foo)); => "extern (C) int function() pure function()"On 4/19/2013 6:55 AM, deadalnix wrote:What is type of an impure function that return a pure, extern(C) function n D ?As of for 2 I'd rather have a standard way to have attribute binding to the return type or the declaration. This is a recurring problem, and auto is simply one instance of it.I'm not understanding it being a recurring problem. There is a recurring misunderstanding that attributes are applying to a type when they are defined as applying to the declaration.
Apr 19 2013
On Friday, 19 April 2013 at 22:16:43 UTC, Timon Gehr wrote:Currently, it exists, yet cannot be named, and the formatted output of the compiler is wrong. alias extern(C) int function()pure P; P foo(){ return null; } pragma(msg, typeof(&foo)); => "extern (C) int function() pure function()"Yes you have to use a alias to do this kind of thing. But some time, you can't alias (in case of inference for instance) and so can't choose what attribute bind to.
Apr 19 2013
On 4/19/2013 11:12 PM, deadalnix wrote:But some time, you can't alias (in case of inference for instance) and so can't choose what attribute bind to.Example, please.
Apr 19 2013
On Saturday, 20 April 2013 at 06:25:09 UTC, Walter Bright wrote:On 4/19/2013 11:12 PM, deadalnix wrote:Here you go: void foo(T)(extern(C) T function() function() f); Try making the extern(C) apply to each of: 1. the result of f() 2. the result of f()() without breaking foo()'s type inference.But some time, you can't alias (in case of inference for instance) and so can't choose what attribute bind to.Example, please.
Apr 20 2013
On 4/20/2013 1:50 AM, Mehrdad wrote:On Saturday, 20 April 2013 at 06:25:09 UTC, Walter Bright wrote:What I've been trying to explain is that there's a difference between a storage class attribute and a type constructor. When pure, for example, is used as a storage class attribute, it applies to the declaration always. When pure is used as a type constructor, it applies to the type, always. There is no ambiguity about this, and no problem about choice. For your example, for purity: void foo(T)(T function() pure function() pure f); The only issue here is that extern(C) is not currently supported as a type constructor. If it were, the example would look like: void foo(T)(T function() extern(C) function() extern(C) f); Again, there is no ambiguity.On 4/19/2013 11:12 PM, deadalnix wrote:Here you go: void foo(T)(extern(C) T function() function() f); Try making the extern(C) apply to each of: 1. the result of f() 2. the result of f()() without breaking foo()'s type inference.But some time, you can't alias (in case of inference for instance) and so can't choose what attribute bind to.Example, please.
Apr 20 2013
On 4/20/13, Walter Bright <newshound2 digitalmars.com> wrote:What I've been trying to explain is that there's a difference between a storage class attribute and a type constructor.I've mentioned this before, but we need a good definition of these on dlang.org (for example people coming from other languages like Python will have no idea what these mean). Last time I mentioned it I didn't file a bug, but now I have: http://d.puremagic.com/issues/show_bug.cgi?id=9970 Hopefully someone with more knowledge of these can write some documentation.
Apr 20 2013
On 4/19/2013 12:34 PM, deadalnix wrote:On Friday, 19 April 2013 at 19:06:39 UTC, Walter Bright wrote:A function foo: extern(C) int function()pure foo() { return null; } A type fp: alias extern(C) int function()pure function() fp;On 4/19/2013 6:55 AM, deadalnix wrote:What is type of an impure function that return a pure, extern(C) function n D ?As of for 2 I'd rather have a standard way to have attribute binding to the return type or the declaration. This is a recurring problem, and auto is simply one instance of it.I'm not understanding it being a recurring problem. There is a recurring misunderstanding that attributes are applying to a type when they are defined as applying to the declaration.
Apr 19 2013
On Saturday, 20 April 2013 at 00:03:36 UTC, Walter Bright wrote:A function foo: extern(C) int function()pure foo() { return null; }That is not it as foo is extern(C).A type fp: alias extern(C) int function()pure function() fp;Same here. In general we lack a mechanism to choose what an attribute bind to.
Apr 19 2013
On 4/19/2013 11:08 PM, deadalnix wrote:On Saturday, 20 April 2013 at 00:03:36 UTC, Walter Bright wrote:That is correct. I was thinking about the pure. The extern(C) can be done in a two step process, as Timon showed.A function foo: extern(C) int function()pure foo() { return null; }That is not it as foo is extern(C).In general we lack a mechanism to choose what an attribute bind to.No, we don't. The attribute binds to the declaration. BTW, in C++ also you gotta do the extern "C" as a two step process to attach it to a function type.
Apr 19 2013
On Saturday, 20 April 2013 at 06:24:36 UTC, Walter Bright wrote:In general we lack a mechanism to choose what direction we turn to. No, we don't. We always turn to the right.In general we lack a mechanism to choose what an attribute bind to.No, we don't. The attribute binds to the declaration.
Apr 19 2013
On Saturday, 20 April 2013 at 06:32:50 UTC, deadalnix wrote:On Saturday, 20 April 2013 at 06:24:36 UTC, Walter Bright wrote:I am quite sure Walter has meant that linkage attribute was not supposed to be tied to a type by design. If you want to use it, you need a symbol (==declaration) and there can be only one at a time.In general we lack a mechanism to choose what direction we turn to. No, we don't. We always turn to the right.In general we lack a mechanism to choose what an attribute bind to.No, we don't. The attribute binds to the declaration.
Apr 20 2013
On Saturday, 20 April 2013 at 07:03:55 UTC, Dicebot wrote:On Saturday, 20 April 2013 at 06:32:50 UTC, deadalnix wrote:You don't need a symbol. They also control the ABI, and this isn't always related to a specific symbol.On Saturday, 20 April 2013 at 06:24:36 UTC, Walter Bright wrote:I am quite sure Walter has meant that linkage attribute was not supposed to be tied to a type by design. If you want to use it, you need a symbol (==declaration) and there can be only one at a time.In general we lack a mechanism to choose what direction we turn to. No, we don't. We always turn to the right.In general we lack a mechanism to choose what an attribute bind to.No, we don't. The attribute binds to the declaration.
Apr 20 2013
On Saturday, 20 April 2013 at 07:18:42 UTC, deadalnix wrote:You don't need a symbol. They also control the ABI, and this isn't always related to a specific symbol.Well, this is how it probably should be. But looking at current D state I don't see if it was even planned. Can you have an extern without declaring some symbol at the same time within current D grammar?
Apr 20 2013
On Thursday, 18 April 2013 at 05:59:20 UTC, kenji hara wrote:It will break existing code. int foo() { typeof(return) bar() { return 1; } return bar(); } typeof(return) represents the return type of foo, that is int. Kenji HaraIt wouldn't break the code though. It would change the meaning, but the code would compile just as it did before.
Apr 18 2013
On Tuesday, 16 April 2013 at 15:22:56 UTC, Andrei Alexandrescu wrote:There's a discussion that may be of interest to the larger community: https://github.com/D-Programming-Language/dmd/pull/1877 AndreiI just want to say I'm pretty gung-ho about the idea of attribute inference. If the interface files are blown up to their full explicit attributes, then the big problem of the PIMPL idiom could be solved, with modular programs getting all the info they need and the original source code still quite trim and easy to write. In the discussion of the possible uses of the 'scope' parameter attribute, and 'ref' safety in general, there's a lot of subtleties. One solution to the subtleties is additional attributes, which might be cumbersome to write individually, but easier if inference were on the table.
Apr 21 2013