http://d.puremagic.com/issues/show_bug.cgi?id=7355



--- Comment #17 from Steven Schveighoffer <schvei...@yahoo.com> 2012-02-03 
16:54:12 PST ---
(In reply to comment #16)
> (In reply to comment #13)
> > Once again you are right Timon!
> > 
> > I was neglecting to see in the original example that the call was id(foo(y))
> > instead of just id(y)!  I sometimes cannot penetrate your inadvertent
> > obfuscation :)  Your original example was (should have been) sufficient.
> > 
> 
> OK. What measures can I take to less obfuscate my code? =)

hehe, use temporaries to demonstrate what types should be.  Or more inline
comments maybe.  I just missed seeing the double call in one expression.

For example, this could have been more effective:

// your definition for foo

inout(int)[] id(inout(int)[] x) { return x;}

inout(const(int))[] bar(inout(int)[] x)
{
   inout(const(int))[] tmp = foo(x);
   return id(tmp); // need to be able to call
}

> I think what you propose would work.
> 
> But the overload rule I want to add (see issue 7431) is actually quite
> intuitive and I think it is a good move to make the overload rules consistent
> enough so that we could re-use them for inout matching. It benefits code that
> does not use inout too.
> 
> Not fixing the overload rules would result in inout being _more_ powerful than
> three overloads => inout could not be replaced by three overloads
> transparently, if it was later determined that the different const versions
> need different function bodies.

inout is *already* more powerful.  It guarantees no molestation, even for
mutable args.

But I see your point.  I'm not opposed to fixing both, but this way of
explaining inout is simple to me, and to someone who doesn't want to get into
the complexities of understanding overload resolution.  In other words, one
doesn't have to be able to understand overload resolution to understand inout.

Consequently, if the way it gets implemented is that overload resolution is
fixed, and then inout uses that, it's not any different, but it's easier to
explain this way (IMO).

> The only difference between using the repaired overload
> resolution and your proposal I can see is that yours introduces possible
> disambiguation in the case of multiple alias this. I don't know if this is 
> good
> or bad (my initial proposal had the same characteristic).
> 
> inout(int)[] foo(inout(int)[] x){return x;}
> 
> class C{
>     int[] x(){writeln("x!");return new int[10];}
>     immutable int[] y(){writeln("y!");return new immutable(int)[10];}
>     alias x this;
>     alias y this;
> }
> 
> void main(){
>     C c = new C;
>     foo(c); // should this work or fail?
> }

I think you give me too many headaches :)  My gut says this should fail,
because the call is not just ambiguously typed, but what you *pass* to the call
is ambiguous.  Consider this less benign example:

struct S
{
   int[] x;
   immutable(int)[] y;
   alias x this;
   alias y this;
}

x and y are not just generated temporaries, so the data you pass could be
different depending on the compiler choice of what order to try the first three
type constructors.

My rules depend on the assumption that the argument type is already decided. 
In the case of literals, that's ok, because an arbitrary choice doesn't change
code paths, just the type of the expression.

In this case, we have to cry ambiguity, and fail to compile, in the name of
consistency.  So how to amend my algorithm?  I suppose something like:

try at a minimum immutable, mutable, and inout.  If more than one of these
typechecks, the call is ambiguous.

-- 
Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email
------- You are receiving this mail because: -------

Reply via email to