www.digitalmars.com         C & C++   DMDScript  

digitalmars.D - Proposal: Automatic shallow Unqual on IFTI

reply dsimcha <dsimcha yahoo.com> writes:
Bug 2594 (http://d.puremagic.com/issues/show_bug.cgi?id=2594) has languished
in Bugzilla for about 1.5 years and really irks me.  Furthermore,
std.math.pow(), for example, doesn't work when passed immutable values.  In
other words, right now you can't do:

immutable uint foo = 5;
immutable uint bar = 2;
uint baz = foo ^^ bar;

Lots of functions in Phobos, as well as libs I've written, have basically this
bug, and fixing/preventing all instances of it is a monumental and tedious task.

Therefore, I propose that implicit function template instantiation
automatically runs the equivalent of a shallow Unqual on its non-ref arguments
before determining the types.  In other words, if a const/immutable object
could be implicitly cast to shallow mutable, it is.  For example:

void fun(T, U)(T arg1, U arg2) {
    // Do stuff that assumes arg1, arg2 are shallowly mutable.
}

void main() {
    immutable uint foo = 3;
    immutable char[] bar = "bar";

    // This instantiates fun with T = uint and U =
    // immutable(char)[], NOT T = immutable uint and
    // U = immutable char[].
    fun(foo, bar);
}

This would prevent a lot of nasty bugs but would be safe because arguments
passed by value are shallowly copied and therefore can safely be made
shallowly mutable, which is why implicitly casting between fully
const/immutable and shallowly mutable is allowed already by the spec.
Jul 20 2010
next sibling parent reply "Lars T. Kyllingstad" <public kyllingen.NOSPAMnet> writes:
On Tue, 20 Jul 2010 16:19:50 +0000, dsimcha wrote:

 Bug 2594 (http://d.puremagic.com/issues/show_bug.cgi?id=2594) has
 languished in Bugzilla for about 1.5 years and really irks me. 
 Furthermore, std.math.pow(), for example, doesn't work when passed
 immutable values.  In other words, right now you can't do:
 
 immutable uint foo = 5;
 immutable uint bar = 2;
 uint baz = foo ^^ bar;
 
 Lots of functions in Phobos, as well as libs I've written, have
 basically this bug, and fixing/preventing all instances of it is a
 monumental and tedious task.
 
 Therefore, I propose that implicit function template instantiation
 automatically runs the equivalent of a shallow Unqual on its non-ref
 arguments before determining the types.  In other words, if a
 const/immutable object could be implicitly cast to shallow mutable, it
 is.  For example:
 
 void fun(T, U)(T arg1, U arg2) {
     // Do stuff that assumes arg1, arg2 are shallowly mutable.
 }
 
 void main() {
     immutable uint foo = 3;
     immutable char[] bar = "bar";
 
     // This instantiates fun with T = uint and U = // immutable(char)[],
     NOT T = immutable uint and // U = immutable char[].
     fun(foo, bar);
 }
 
 This would prevent a lot of nasty bugs but would be safe because
 arguments passed by value are shallowly copied and therefore can safely
 be made shallowly mutable, which is why implicitly casting between fully
 const/immutable and shallowly mutable is allowed already by the spec.

++vote -Lars
Jul 20 2010
parent BCS <none anon.com> writes:
Hello Lars,

 On Tue, 20 Jul 2010 16:19:50 +0000, dsimcha wrote:
 
 Bug 2594 (http://d.puremagic.com/issues/show_bug.cgi?id=2594) has
 languished in Bugzilla for about 1.5 years and really irks me.
 Furthermore, std.math.pow(), for example, doesn't work when passed
 immutable values.  In other words, right now you can't do:
 
 immutable uint foo = 5;
 immutable uint bar = 2;
 uint baz = foo ^^ bar;
 Lots of functions in Phobos, as well as libs I've written, have
 basically this bug, and fixing/preventing all instances of it is a
 monumental and tedious task.
 
 Therefore, I propose that implicit function template instantiation
 automatically runs the equivalent of a shallow Unqual on its non-ref
 arguments before determining the types.  In other words, if a
 const/immutable object could be implicitly cast to shallow mutable,
 it is.  For example:
 
 void fun(T, U)(T arg1, U arg2) {
 // Do stuff that assumes arg1, arg2 are shallowly mutable.
 }
 void main() {
 immutable uint foo = 3;
 immutable char[] bar = "bar";
 // This instantiates fun with T = uint and U = // immutable(char)[],
 NOT T = immutable uint and // U = immutable char[].
 fun(foo, bar);
 }
 This would prevent a lot of nasty bugs but would be safe because
 arguments passed by value are shallowly copied and therefore can
 safely be made shallowly mutable, which is why implicitly casting
 between fully const/immutable and shallowly mutable is allowed
 already by the spec.
 


vote++; s/ITFI//g Good idea, but think bigger. That is safe in general *runtime* code. OTOH I'd rather see the possibility of it only getting done on request be explored. Also allowing that as an implicit conversion on any copy is also safe. -- ... <IXOYE><
Jul 21 2010
prev sibling parent dsimcha <dsimcha yahoo.com> writes:
== Quote from dsimcha (dsimcha yahoo.com)'s article
 Bug 2594 (http://d.puremagic.com/issues/show_bug.cgi?id=2594) has languished
 in Bugzilla for about 1.5 years and really irks me.  Furthermore,
 std.math.pow(), for example, doesn't work when passed immutable values.  In
 other words, right now you can't do:
 immutable uint foo = 5;
 immutable uint bar = 2;
 uint baz = foo ^^ bar;
 Lots of functions in Phobos, as well as libs I've written, have basically this
 bug, and fixing/preventing all instances of it is a monumental and tedious
task.
 Therefore, I propose that implicit function template instantiation
 automatically runs the equivalent of a shallow Unqual on its non-ref arguments
 before determining the types.  In other words, if a const/immutable object
 could be implicitly cast to shallow mutable, it is.  For example:
 void fun(T, U)(T arg1, U arg2) {
     // Do stuff that assumes arg1, arg2 are shallowly mutable.
 }
 void main() {
     immutable uint foo = 3;
     immutable char[] bar = "bar";
     // This instantiates fun with T = uint and U =
     // immutable(char)[], NOT T = immutable uint and
     // U = immutable char[].
     fun(foo, bar);
 }
 This would prevent a lot of nasty bugs but would be safe because arguments
 passed by value are shallowly copied and therefore can safely be made
 shallowly mutable, which is why implicitly casting between fully
 const/immutable and shallowly mutable is allowed already by the spec.

Ok, now that I've had a few months to think about this, I realize there's one gaping hole in it: Not every T is implicitly convertible to Unqual!T. I'll modify it slightly: IFTI should do an implicit shallow Unqual iff the type T is implicitly convertible to Unqual!T. Having just dealt with a bunch of Phobos issues related to using const/immutable arrays with ranges, let me say that doing this would solve tons of problems. I'd really like some comments from Walter on whether this is feasible.
Sep 18 2010