Bug 3572 – declaring pure function with void return type should be compile time error

Status
RESOLVED
Resolution
INVALID
Severity
enhancement
Priority
P2
Component
dmd
Product
D
Version
D2
Platform
All
OS
All
Creation time
2009-12-04T02:37:33Z
Last change time
2020-03-25T09:00:37Z
Keywords
accepts-invalid, diagnostic
Assigned to
No Owner
Creator
Michal Minich

Comments

Comment #0 by michal.minich — 2009-12-04T02:37:33Z
In D specification is written: "Pure functions are functions that produce the same result for the same arguments. To that end, a pure function has parameters that are all immutable or are implicitly convertible to immutable void function cannot produce any result, thus they are meaningless as pure functions. Also when all parameters are implicitly immutable, there is no possibility to modify "out" parameters. So the only way for function to produce result, is by returning it (and void has no value).
Comment #1 by clugdbug — 2009-12-04T12:01:56Z
(In reply to comment #0) > In D specification is written: "Pure functions are functions that produce the > same result for the same arguments. To that end, a pure function has parameters > that are all immutable or are implicitly convertible to immutable > > void function cannot produce any result, thus they are meaningless as pure > functions. Also when all parameters are implicitly immutable, there is no > possibility to modify "out" parameters. So the only way for function to produce > result, is by returning it (and void has no value). I think the restriction on 'out' parameters will be removed. I don't think there's any reason for it. A void pure function that doesn't have any 'out' parameters does seem to be pretty useless (you can use it as a metaprogramming test that anything inside it is pure, but that's about all I can think of).
Comment #2 by dsimcha — 2009-12-04T15:52:01Z
????? Why would you allow out parameters in a pure function? This seems reasonable for simple value types (ints, floats, etc.), but when you start passing objects in, you start allowing the modification of whole object subgraphs from pure functions. This makes no sense.
Comment #3 by clugdbug — 2009-12-04T18:28:11Z
(In reply to comment #2) > ????? Why would you allow out parameters in a pure function? This seems > reasonable for simple value types (ints, floats, etc.), but when you start > passing objects in, you start allowing the modification of whole object > subgraphs from pure functions. This makes no sense. Why doesn't it make sense? Aren't you thinking of inout parameters? A pure function void foo(out A a); ought to be exactly the same as A foo(); together with an assignment. I'm not seeing anything impure in that. BTW, it works fine in CTFE. (CTFE isn't quite the same concept as pure, but it's close).
Comment #4 by dsimcha — 2010-02-17T18:38:36Z
(In reply to comment #3) > Why doesn't it make sense? Aren't you thinking of inout parameters? A pure > function void foo(out A a); ought to be exactly the same as A foo(); together > with an assignment. I'm not seeing anything impure in that. > BTW, it works fine in CTFE. (CTFE isn't quite the same concept as pure, but > it's close). You're right, I did get confused between out and ref. Allowing out parameters in pure functions makes sense. I tend to forget how out parameters work because I almost never use them. I almost always just return a tuple or a struct.
Comment #5 by hoganmeier — 2012-01-05T14:19:40Z
Also you shouldn't be able to throw away the result of a pure function. http://d.puremagic.com/issues/show_bug.cgi?id=7235
Comment #6 by andrej.mitrovich — 2013-02-03T15:53:14Z
(In reply to comment #3) > (In reply to comment #2) > > ????? Why would you allow out parameters in a pure function? This seems > > reasonable for simple value types (ints, floats, etc.), but when you start > > passing objects in, you start allowing the modification of whole object > > subgraphs from pure functions. This makes no sense. > > Why doesn't it make sense? Aren't you thinking of inout parameters? A pure > function void foo(out A a); ought to be exactly the same as A foo(); together > with an assignment. I'm not seeing anything impure in that. > BTW, it works fine in CTFE. (CTFE isn't quite the same concept as pure, but > it's close). Should we close this report then?
Comment #7 by k.hara.pg — 2013-02-03T18:50:45Z
In current, we can declare a pure function which has "weak" purity. pure void foo(int* p, out string s, ref int[] arr); All results are returned through its parameters. So, returning void itself has no problem in pure functions.
Comment #8 by yebblies — 2013-03-06T02:46:46Z
(In reply to comment #7) > In current, we can declare a pure function which has "weak" purity. > > pure void foo(int* p, out string s, ref int[] arr); > > All results are returned through its parameters. > So, returning void itself has no problem in pure functions. This would still be meaningful for strongly-pure or const-pure functions. eg. pure void foo(string x) By definition calling foo does no observable work. While this might be WONTFIX or LATER like issue 3882, it is not invalid.
Comment #9 by dkorpel — 2020-03-24T11:10:21Z
(In reply to yebblies from comment #8) > eg. > pure void foo(string x) > By definition calling foo does no observable work. False. ``` pure void foo(string x) { throw new Exception(x); } ``` Here's a nothrow one: ``` pure nothrow void assertPositive(int x) { assert(x > 0); } ``` > While this might be WONTFIX or LATER like issue 3882, it is not invalid. Until a case can be identified where there is actually "no observable work" guaranteed, this is invalid. (And even then, it's debatable whether "no observable work" is enough grounds to make something not compile. `int x = 0; x += 0;` does nothing, but it does and should compile.)
Comment #10 by michal.minich — 2020-03-25T09:00:37Z
Agreed. even pure void nothrow never() { assert(false); } can throw Error, which is observable effect.