digitalmars.D.bugs - [Issue 5125] New: Optional function purity/nothrowness
- d-bugmail puremagic.com (91/91) Oct 27 2010 http://d.puremagic.com/issues/show_bug.cgi?id=5125
- d-bugmail puremagic.com (6/6) Nov 09 2010 http://d.puremagic.com/issues/show_bug.cgi?id=5125
- d-bugmail puremagic.com (7/7) Nov 14 2010 http://d.puremagic.com/issues/show_bug.cgi?id=5125
- d-bugmail puremagic.com (19/19) Mar 04 2011 http://d.puremagic.com/issues/show_bug.cgi?id=5125
- d-bugmail puremagic.com (11/11) Jun 26 2011 http://d.puremagic.com/issues/show_bug.cgi?id=5125
http://d.puremagic.com/issues/show_bug.cgi?id=5125
Summary: Optional function purity/nothrowness
Product: D
Version: D2
Platform: All
OS/Version: All
Status: NEW
Severity: enhancement
Priority: P2
Component: DMD
AssignedTo: nobody puremagic.com
ReportedBy: bearophile_hugs eml.cc
A higher order function like "map" (or "filter") is meant to be often a pure
function, this means that the mapping delegate is often pure (see also bug 3934
and bug 5006 ).
A possible solution: the "map" function may be pure if and only if the given
delegate/function is pure (a similar problem is present regarding the "nothrow"
attribute). But currently there is no good way to do this.
This code shows the situation, you need two map functions, and some code
duplication:
pure int sqr(int x) { return x * x; }
pure int[] pureMymap(F)(F f, int[] data) {
int[] res;
foreach (x; data)
res ~= f(x);
return res;
}
int[] mymap(F)(F f, int[] data) {
int[] res;
foreach (x; data)
res ~= f(x);
return res;
}
void main() {
int[] data = [1, 2, 3, 4];
auto r1 = pureMymap(&sqr, data);
assert(r1 == [1, 4, 9, 16]);
int acc = 1;
int impure(int x) { acc += x; return acc; }
// Error: pure function 'pureMymap' cannot call impure delegate 'f'
// auto r2 = pureMymap(&impure, data);
auto r2 = mymap(&impure, data); // OK
assert(r2 == [2, 4, 7, 11]);
}
With a string mixing that contains the whole code of map you may remove the
code duplication, but it's an ugly solution, and in the end you have two
functions with different names still:
import std.metastrings: Format;
enum string mapCode = q{
%s int[] %smap(F)(F f, int[] data) {
int[] res;
foreach (x; data)
res ~= f(x);
return res;
}
};
mixin(Format!(mapCode, "", "")); // defines map()
mixin(Format!(mapCode, "pure", "pure")); // defines pure puremap()
pure int sqr(int x) { return x * x; }
void main() {
int[] data = [1, 2, 3, 4];
auto r1 = puremap(&sqr, data);
assert(r1 == [1, 4, 9, 16]);
int acc = 1;
int impure(int x) { acc += x; return acc; }
// Error: pure function 'puremap' cannot call impure delegate 'f'
//auto r2 = puremap(&impure, data);
auto r2 = map(&impure, data); // OK
assert(r2 == [2, 4, 7, 11]);
}
A better solution is an attribute that allows to use optional tags, like (you
may find a better name for this attribute):
optional_tag(isPure!F, pure) int[] map(F)(F f, int[] data) {
int[] res;
foreach (x; data)
res ~= f(x);
return res;
}
The first argument of optional_tag() is a boolean known at compile-time.
Where isPure is just:
import std.traits: FunctionAttribute, functionAttributes;
template isPure(F) {
enum bool isPure = functionAttributes!(F) & FunctionAttribute.PURE;
}
A more general alternative syntax:
__traits(optional, isPure!F, pure)
Other more general solutions are possible, this is just a first idea.
--
Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email
------- You are receiving this mail because: -------
Oct 27 2010
http://d.puremagic.com/issues/show_bug.cgi?id=5125 See bug 4974 for another usage -- Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email ------- You are receiving this mail because: -------
Nov 09 2010
http://d.puremagic.com/issues/show_bug.cgi?id=5125 Another idea: http://www.digitalmars.com/webnews/newsgroups.php?art_group=digitalmars.D&article_id=122087 -- Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email ------- You are receiving this mail because: -------
Nov 14 2010
http://d.puremagic.com/issues/show_bug.cgi?id=5125
Jonathan M Davis <jmdavisProg gmx.com> changed:
What |Removed |Added
----------------------------------------------------------------------------
CC| |jmdavisProg gmx.com
PST ---
I believe that Andrei's suggestion for pure was to add optional constraints to
pure. So, you'd have pure(condition) instead of pure, and the function would be
pure if the constraint was true. Presumably, we could do the same for nothrow
as well. safe, trusted, and system (or at least safe and trusted) are in
the same boat. So, maybe it should just be generalized to all function
attributes (which would then presumably include stuff like public and private,
though that's pretty pointless other than avoiding special casing attributes
might be nice).
Regardless, we're going to need a solution for this if we want attributes like
pure to really work with templated functions.
--
Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email
------- You are receiving this mail because: -------
Mar 04 2011
http://d.puremagic.com/issues/show_bug.cgi?id=5125
bearophile_hugs eml.cc changed:
What |Removed |Added
----------------------------------------------------------------------------
Status|NEW |RESOLVED
Resolution| |FIXED
Conditional purity of DMD 2.054 makes this enhancement request unnecessary.
--
Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email
------- You are receiving this mail because: -------
Jun 26 2011









d-bugmail puremagic.com 