|
Archives
D Programming
DD.gnu digitalmars.D digitalmars.D.bugs digitalmars.D.dtl digitalmars.D.ide digitalmars.D.dwt digitalmars.D.announce digitalmars.D.learn digitalmars.D.debugger C/C++ Programming
c++c++.announce c++.atl c++.beta c++.chat c++.command-line c++.dos c++.dos.16-bits c++.dos.32-bits c++.idde c++.mfc c++.rtl c++.stl c++.stl.hp c++.stl.port c++.stl.sgi c++.stlsoft c++.windows c++.windows.16-bits c++.windows.32-bits c++.wxwindows digitalmars.empire digitalmars.DMDScript electronics |
digitalmars.D - Re: Idea: partially pure functions
Bruno Medeiros Wrote:I want to conceptualize an idea that has been briefly mentioned in the previous pure discussions (by Don I think?), but has not been explicitly brought into attention. As we know, the current definition of pure functions (according to http://www.digitalmars.com/d/2.0/accu-functional.pdf) is that they can only access invariant, or local mutable data. This means that all of the function's parameters have to be invariant. The idea is: let's also allow pure functions to have (and access) non-invariant parameters. These won't be normal pure functions, but instead "partially" pure functions. Their semantics are: the function promises not to change any external/global data, except for the parameters that are not invariant. Example: pure char[] mutable_tolower(char[] str) { // in-place tolower here as str is mutable... } But what's the use of partially pure functions then? Well, what happens is that, since the set of possible mutable data of a partial function is "finite", and restricted to only the function's parameters, one can safely allow the calling of partially pure functions inside fully pure functions (and also other partially pure functions). How come? Well, a fully pure function is allowed to mutate local state. Thus, it can use that mutable local sate as arguments to a partially pure function, since that partially pure function will only mutable those arguments, and nothing else. The contract for a full pure function is maintained. Example: consider a pure function that takes two strings as arguments, concatenates them, tolower's the first half, and toupper's the second half. How does one write that function with the usual rules for pure functions? Something like: alias char[] mstring; char[] xpto(string a, string b) { mstring result = a ~ b; auto halflen = result.length/2; return (tolower(result[0..halflen]) ~ toupper(result[halflen..$])); } But notice that this version is inefficient. About 3 unnecessary temporary allocations are performed. How could this be prevented? One solution would be to call mutable versions of tolower and toupper... but since they are not pure functions, they cannot be called under the normal rules. But if one allows the partially pure function rules, it becomes possible. One then could write the previous function as this: char[] xpto2(string a, string b) { mstring result = a ~ b; auto halflen = result.length/2; mutable_tolower(result[0..halflen]); mutable_toupper(result[halflen..$]); return result; } Now, I know that xpto could be rewritten so as to be as efficient as xpto2 with the current rules, but the code wouldn't look nearly as nice. And that is precisely the point: You would have to code tolower inside of xpto, and this is just a trivial example, imagine with more complicated functions... The partially pure functions allow more expressiveness and efficiency without any kind of compromise. -- Bruno Medeiros - Software Developer, MSc. in CS/E graduate http://www.prowiki.org/wiki4d/wiki.cgi?BrunoMedeiros#D May 01 2008
Jason House wrote:Bruno Medeiros Wrote:I want to conceptualize an idea that has been briefly mentioned in the previous pure discussions (by Don I think?), but has not been explicitly brought into attention. As we know, the current definition of pure functions (according to http://www.digitalmars.com/d/2.0/accu-functional.pdf) is that they can only access invariant, or local mutable data. This means that all of the function's parameters have to be invariant. The idea is: let's also allow pure functions to have (and access) non-invariant parameters. These won't be normal pure functions, but instead "partially" pure functions. Their semantics are: the function promises not to change any external/global data, except for the parameters that are not invariant. Example: pure char[] mutable_tolower(char[] str) { // in-place tolower here as str is mutable... } But what's the use of partially pure functions then? Well, what happens is that, since the set of possible mutable data of a partial function is "finite", and restricted to only the function's parameters, one can safely allow the calling of partially pure functions inside fully pure functions (and also other partially pure functions). How come? Well, a fully pure function is allowed to mutate local state. Thus, it can use that mutable local sate as arguments to a partially pure function, since that partially pure function will only mutable those arguments, and nothing else. The contract for a full pure function is maintained. Example: consider a pure function that takes two strings as arguments, concatenates them, tolower's the first half, and toupper's the second half. How does one write that function with the usual rules for pure functions? Something like: alias char[] mstring; char[] xpto(string a, string b) { mstring result = a ~ b; auto halflen = result.length/2; return (tolower(result[0..halflen]) ~ toupper(result[halflen..$])); } But notice that this version is inefficient. About 3 unnecessary temporary allocations are performed. How could this be prevented? One solution would be to call mutable versions of tolower and toupper... but since they are not pure functions, they cannot be called under the normal rules. But if one allows the partially pure function rules, it becomes possible. One then could write the previous function as this: char[] xpto2(string a, string b) { mstring result = a ~ b; auto halflen = result.length/2; mutable_tolower(result[0..halflen]); mutable_toupper(result[halflen..$]); return result; } Now, I know that xpto could be rewritten so as to be as efficient as xpto2 with the current rules, but the code wouldn't look nearly as nice. And that is precisely the point: You would have to code tolower inside of xpto, and this is just a trivial example, imagine with more complicated functions... The partially pure functions allow more expressiveness and efficiency without any kind of compromise. -- Bruno Medeiros - Software Developer, MSc. in CS/E graduate http://www.prowiki.org/wiki4d/wiki.cgi?BrunoMedeiros#D May 02 2008
Bruno Medeiros Wrote:Jason House wrote: May 02 2008
Jason House wrote:and it can't allocate a new C. May 03 2008
Bruno Medeiros wrote:Jason House wrote:and it can't allocate a new C. May 03 2008
|