Re: Who wore it better?

2016-04-25 Thread Steven Schveighoffer via Digitalmars-d

On 4/24/16 6:40 AM, Nick Treleaven wrote:

On Friday, 15 April 2016 at 18:46:01 UTC, Steven Schveighoffer wrote:

inout(T)[] overlap(T)(inout(T)[] r1, inout(T)[] r2)


Might be nice if inout applied to template parameter types:

T[] overlap(inout T)(T[] r1, T[] r2);

If it wasn't for the virtual function issue, I wonder if inout would
still be needed on runtime arguments given the above feature?


The only issue is that overlap being passed a mutable T[] could modify 
the data. This is the major deficiency with the template solution. As 
I've said before, if you don't care about advertisement of non-mutation, 
then inout doesn't really do much for you.


-Steve


Re: Who wore it better?

2016-04-24 Thread Nick Treleaven via Digitalmars-d
On Friday, 15 April 2016 at 18:46:01 UTC, Steven Schveighoffer 
wrote:

inout(T)[] overlap(T)(inout(T)[] r1, inout(T)[] r2)


Might be nice if inout applied to template parameter types:

T[] overlap(inout T)(T[] r1, T[] r2);

If it wasn't for the virtual function issue, I wonder if inout 
would still be needed on runtime arguments given the above 
feature?


Using traits like CopyConstness might be enough.


Re: Who wore it better?

2016-04-18 Thread Kagamin via Digitalmars-d
On Friday, 15 April 2016 at 21:01:44 UTC, Andrei Alexandrescu 
wrote:
Jesus. C++ has const without inout. We used to have const 
without inout - and we probably should again. -- Andrei


What about immutability? E.g. Java gets away with immutable in a 
library and it just werks.


Re: Who wore it better?

2016-04-17 Thread Nick Treleaven via Digitalmars-d
On Friday, 15 April 2016 at 17:24:19 UTC, Andrei Alexandrescu 
wrote:

inout(T)[] overlap(T)(inout(T)[] r1, inout(T)[] r2) @trusted


BTW, why is overlap undocumented - is ctfe support a good enough 
reason?

https://github.com/dlang/phobos/blob/v2.071.0/std/array.d#L715

I've thought about implementing something similar, good to know 
it's there. I wonder if there are places in Phobos that could use 
this.


Also, its unittest needs to get undocumented too, it's appearing 
in the previous symbol's documentation instead.


Re: Who wore it better?

2016-04-15 Thread Jonathan M Davis via Digitalmars-d
On Friday, April 15, 2016 13:46:24 Andrei Alexandrescu via Digitalmars-d 
wrote:
> On 04/15/2016 01:31 PM, Namespace wrote:
> > Since it is a template: Why these attributes: @trusted pure nothrow ?
>
> @trusted is not inferrable, the others are type-independent and nice for
> the documentation. -- Andrei

Yes. I definitely think that it should be standard policy in Phobos (if not
D code in general) to only use attribute inference when it's actually
required. Without attribute inference, attributes and templates really
wouldn't work together (which is why we have it), but the cost is that you
don't know what the actual attributes are without compiling the code. So,
while some folks may not like the extra typing, I think that it's clearly
better for everyone who has to look at or maintain a function and/or its
documentation to know what its attributes are by looking just at it, even if
it's a little bit of extra work for the person who writes the function
initially.

I honestly wish that we hadn't added attribute inference to auto return
functions, since I think that it's just enabling a bad practice.

- Jonathan M Davis



Re: Who wore it better?

2016-04-15 Thread Andrei Alexandrescu via Digitalmars-d

On 04/15/2016 05:27 PM, Steven Schveighoffer wrote:

On 4/15/16 5:01 PM, Andrei Alexandrescu wrote:

On 04/15/2016 04:45 PM, Steven Schveighoffer wrote:

On 4/15/16 4:34 PM, Andrei Alexandrescu wrote:

On 04/15/2016 04:16 PM, Steven Schveighoffer wrote:

If you find such advertisement useless, you of course do not need
inout
or const.


Let's not exaggerate by putting them together. -- Andrei


This is not an exaggeration.


Jesus. C++ has const without inout. We used to have const without inout
- and we probably should again. -- Andrei


"C++ has it" is a terrible argument.


You're losing track of the thread of the argument. It's not an argument, 
it's the factual correct refutation of your wrong claim.



If you care about advertisement, you can't use templates to advertise
whether something is const or not. Your solution is "let's use templates
instead". That works, but obviously, compiler will let you molest
whatever data you want. Then advertisement is done with documentation
and trust.

C++ simply doesn't have that capability to advertise const for the
things inout can, but also const isn't as restrictive in C++, so you can
put const on things that aren't really const. IIRC Walter says C++ const
is useless for guarantees (and I agree with that).

Tell me what the benefits of const are. Pretty much all the arguments
you are saying for getting rid of inout (that don't involve corner cases
we can fix) can be used to say we should get rid of const too. Why stop
getting rid of complexity at inout?


The simple answer is const pays enough, inout doesn't.

Anyhow this meandering is the kiss of death - this exchange is becoming 
a time-wasting back and forth, exactly the kind I promised myself to not 
get involved in. I'll keep your good points in mind when deciding 
whether we should rid D of inout.



Thanks,

Andrei



Re: Who wore it better?

2016-04-15 Thread Steven Schveighoffer via Digitalmars-d

On 4/15/16 5:01 PM, Andrei Alexandrescu wrote:

On 04/15/2016 04:45 PM, Steven Schveighoffer wrote:

On 4/15/16 4:34 PM, Andrei Alexandrescu wrote:

On 04/15/2016 04:16 PM, Steven Schveighoffer wrote:

If you find such advertisement useless, you of course do not need inout
or const.


Let's not exaggerate by putting them together. -- Andrei


This is not an exaggeration.


Jesus. C++ has const without inout. We used to have const without inout
- and we probably should again. -- Andrei


"C++ has it" is a terrible argument.

If you care about advertisement, you can't use templates to advertise 
whether something is const or not. Your solution is "let's use templates 
instead". That works, but obviously, compiler will let you molest 
whatever data you want. Then advertisement is done with documentation 
and trust.


C++ simply doesn't have that capability to advertise const for the 
things inout can, but also const isn't as restrictive in C++, so you can 
put const on things that aren't really const. IIRC Walter says C++ const 
is useless for guarantees (and I agree with that).


Tell me what the benefits of const are. Pretty much all the arguments 
you are saying for getting rid of inout (that don't involve corner cases 
we can fix) can be used to say we should get rid of const too. Why stop 
getting rid of complexity at inout?


-Steve


Re: Who wore it better?

2016-04-15 Thread Andrei Alexandrescu via Digitalmars-d

On 04/15/2016 04:47 PM, Marco Leise wrote:

Am Fri, 15 Apr 2016 14:48:26 -0400
schrieb Andrei Alexandrescu :


On 4/15/16 2:46 PM, Steven Schveighoffer wrote:

On 4/15/16 1:24 PM, Andrei Alexandrescu wrote:

auto overlap(T, U)(T[] r1, U[] r2) @trusted pure nothrow
if (is(typeof(r1.ptr < r2.ptr) == bool))
{
  import std.algorithm : min, max;
  auto b = max(r1.ptr, r2.ptr);
  auto e = min(r1.ptr + r1.length, r2.ptr + r2.length);
  return b < e ? b[0 .. e - b] : null;
}

Who wore it better?


inout(T)[] overlap(T)(inout(T)[] r1, inout(T)[] r2) @trusted pure nothrow
{
  import std.algorithm: min, max;
  auto b = max(r1.ptr, r2.ptr);
  auto e = min(r1.ptr + r1.length, r2.ptr + r2.length);
  return b < e ? b[0 .. e - b] : null;
}


Is that better or worse than the one without inout? -- Andrei


I tend to write functions in the latter style, to avoid
unneeded template instantiations. In this case it also
documents the intent better. Both arrays are of the same type
T and we wont modify the contents.


Thanks, this is a good point that needs keeping in mind.


Even if the compiler can remove binary identical instances
after the fact, the compile time and memory use increases.
It also has implications on debugging. After duplicate
removal, you cannot map a function address to a unique symbol
name any more.


This is perhaps weaker.


Andrei



Re: Who wore it better?

2016-04-15 Thread Andrei Alexandrescu via Digitalmars-d

On 04/15/2016 04:45 PM, Steven Schveighoffer wrote:

On 4/15/16 4:34 PM, Andrei Alexandrescu wrote:

On 04/15/2016 04:16 PM, Steven Schveighoffer wrote:

If you find such advertisement useless, you of course do not need inout
or const.


Let's not exaggerate by putting them together. -- Andrei


This is not an exaggeration.


Jesus. C++ has const without inout. We used to have const without inout 
- and we probably should again. -- Andrei




Re: Who wore it better?

2016-04-15 Thread Marco Leise via Digitalmars-d
Am Fri, 15 Apr 2016 14:48:26 -0400
schrieb Andrei Alexandrescu :

> On 4/15/16 2:46 PM, Steven Schveighoffer wrote:
> > On 4/15/16 1:24 PM, Andrei Alexandrescu wrote:  
> >> auto overlap(T, U)(T[] r1, U[] r2) @trusted pure nothrow
> >> if (is(typeof(r1.ptr < r2.ptr) == bool))
> >> {
> >>  import std.algorithm : min, max;
> >>  auto b = max(r1.ptr, r2.ptr);
> >>  auto e = min(r1.ptr + r1.length, r2.ptr + r2.length);
> >>  return b < e ? b[0 .. e - b] : null;
> >> }
> >>
> >> Who wore it better?  
> >
> > inout(T)[] overlap(T)(inout(T)[] r1, inout(T)[] r2) @trusted pure nothrow
> > {
> >  import std.algorithm: min, max;
> >  auto b = max(r1.ptr, r2.ptr);
> >  auto e = min(r1.ptr + r1.length, r2.ptr + r2.length);
> >  return b < e ? b[0 .. e - b] : null;
> > }  
> 
> Is that better or worse than the one without inout? -- Andrei
 
I tend to write functions in the latter style, to avoid
unneeded template instantiations. In this case it also
documents the intent better. Both arrays are of the same type
T and we wont modify the contents.

Even if the compiler can remove binary identical instances
after the fact, the compile time and memory use increases.
It also has implications on debugging. After duplicate
removal, you cannot map a function address to a unique symbol
name any more.

Just my 2ยข.

-- 
Marco



Re: Who wore it better?

2016-04-15 Thread Steven Schveighoffer via Digitalmars-d

On 4/15/16 4:34 PM, Andrei Alexandrescu wrote:

On 04/15/2016 04:16 PM, Steven Schveighoffer wrote:

If you find such advertisement useless, you of course do not need inout
or const.


Let's not exaggerate by putting them together. -- Andrei


This is not an exaggeration. inout and const have pretty much the same 
benefits and drawbacks, with only a couple of major differences. The 
main feature of const/inout is advertisement of non-mutation. Otherwise, 
we could do with just mutable and immutable + templates.


-Steve


Re: Who wore it better?

2016-04-15 Thread Andrei Alexandrescu via Digitalmars-d

On 04/15/2016 04:16 PM, Steven Schveighoffer wrote:

If you find such advertisement useless, you of course do not need inout
or const.


Let's not exaggerate by putting them together. -- Andrei


Re: Who wore it better?

2016-04-15 Thread Steven Schveighoffer via Digitalmars-d

On 4/15/16 4:05 PM, Andrei Alexandrescu wrote:

On 04/15/2016 03:13 PM, Steven Schveighoffer wrote:

On 4/15/16 2:48 PM, Andrei Alexandrescu wrote:

On 4/15/16 2:46 PM, Steven Schveighoffer wrote:

inout(T)[] overlap(T)(inout(T)[] r1, inout(T)[] r2) @trusted pure
nothrow
{
 import std.algorithm: min, max;
 auto b = max(r1.ptr, r2.ptr);
 auto e = min(r1.ptr + r1.length, r2.ptr + r2.length);
 return b < e ? b[0 .. e - b] : null;
}


Is that better or worse than the one without inout? -- Andrei


Better. It generates one implementation for all 9 combinations of
mutability. Yours generates 9 identical binary functions.


A valid but weak argument. There's been long talk about eliminating
binary identical functions in the front end (some linkers already do
it). That would be the real solution that would help cases unrelated to
inout, too.


The main argument is this:

auto overlap(T, U)(T[] r1, U[] r2) @trusted pure nothrow

Can you tell, does overlap modify any data in r1 or r2?

If you find such advertisement useless, you of course do not need inout 
or const.



And yours possibly depends on a bug:
https://issues.dlang.org/show_bug.cgi?id=15930


Red herring. Fixing the bug shouldn't break that code.


I don't know what the bug is. That's why I said "possibly." I was 
surprised your code compiled with both const/mutable parameters, but 
then I found the bug. It's possible it could be fixed and become 
correct. I'm not sure.


-Steve


Re: Who wore it better?

2016-04-15 Thread Andrei Alexandrescu via Digitalmars-d

On 04/15/2016 03:13 PM, Steven Schveighoffer wrote:

On 4/15/16 2:48 PM, Andrei Alexandrescu wrote:

On 4/15/16 2:46 PM, Steven Schveighoffer wrote:

inout(T)[] overlap(T)(inout(T)[] r1, inout(T)[] r2) @trusted pure
nothrow
{
 import std.algorithm: min, max;
 auto b = max(r1.ptr, r2.ptr);
 auto e = min(r1.ptr + r1.length, r2.ptr + r2.length);
 return b < e ? b[0 .. e - b] : null;
}


Is that better or worse than the one without inout? -- Andrei


Better. It generates one implementation for all 9 combinations of
mutability. Yours generates 9 identical binary functions.


A valid but weak argument. There's been long talk about eliminating 
binary identical functions in the front end (some linkers already do 
it). That would be the real solution that would help cases unrelated to 
inout, too.



And yours possibly depends on a bug:
https://issues.dlang.org/show_bug.cgi?id=15930


Red herring. Fixing the bug shouldn't break that code.


Andrei




Re: Who wore it better?

2016-04-15 Thread Steven Schveighoffer via Digitalmars-d

On 4/15/16 2:48 PM, Andrei Alexandrescu wrote:

On 4/15/16 2:46 PM, Steven Schveighoffer wrote:

inout(T)[] overlap(T)(inout(T)[] r1, inout(T)[] r2) @trusted pure nothrow
{
 import std.algorithm: min, max;
 auto b = max(r1.ptr, r2.ptr);
 auto e = min(r1.ptr + r1.length, r2.ptr + r2.length);
 return b < e ? b[0 .. e - b] : null;
}


Is that better or worse than the one without inout? -- Andrei


Better. It generates one implementation for all 9 combinations of 
mutability. Yours generates 9 identical binary functions.


And yours possibly depends on a bug: 
https://issues.dlang.org/show_bug.cgi?id=15930


-Steve


Re: Who wore it better?

2016-04-15 Thread Andrei Alexandrescu via Digitalmars-d

On 4/15/16 2:46 PM, Steven Schveighoffer wrote:

On 4/15/16 1:24 PM, Andrei Alexandrescu wrote:

I grepped phobos for "inout" and picked a heavy one. Not even cherry
picking here. You be the judges.

Before:

inout(T)[] overlap(T)(inout(T)[] r1, inout(T)[] r2) @trusted pure nothrow
{
 alias U = inout(T);
 static U* max(U* a, U* b) nothrow { return a > b ? a : b; }
 static U* min(U* a, U* b) nothrow { return a < b ? a : b; }

 auto b = max(r1.ptr, r2.ptr);
 auto e = min(r1.ptr + r1.length, r2.ptr + r2.length);
 return b < e ? b[0 .. e - b] : null;
}

After:

auto overlap(T, U)(T[] r1, U[] r2) @trusted pure nothrow
if (is(typeof(r1.ptr < r2.ptr) == bool))
{
 import std.algorithm : min, max;
 auto b = max(r1.ptr, r2.ptr);
 auto e = min(r1.ptr + r1.length, r2.ptr + r2.length);
 return b < e ? b[0 .. e - b] : null;
}

Who wore it better?


inout(T)[] overlap(T)(inout(T)[] r1, inout(T)[] r2) @trusted pure nothrow
{
 import std.algorithm: min, max;
 auto b = max(r1.ptr, r2.ptr);
 auto e = min(r1.ptr + r1.length, r2.ptr + r2.length);
 return b < e ? b[0 .. e - b] : null;
}


Is that better or worse than the one without inout? -- Andrei




Re: Who wore it better?

2016-04-15 Thread Steven Schveighoffer via Digitalmars-d

On 4/15/16 1:24 PM, Andrei Alexandrescu wrote:

I grepped phobos for "inout" and picked a heavy one. Not even cherry
picking here. You be the judges.

Before:

inout(T)[] overlap(T)(inout(T)[] r1, inout(T)[] r2) @trusted pure nothrow
{
 alias U = inout(T);
 static U* max(U* a, U* b) nothrow { return a > b ? a : b; }
 static U* min(U* a, U* b) nothrow { return a < b ? a : b; }

 auto b = max(r1.ptr, r2.ptr);
 auto e = min(r1.ptr + r1.length, r2.ptr + r2.length);
 return b < e ? b[0 .. e - b] : null;
}

After:

auto overlap(T, U)(T[] r1, U[] r2) @trusted pure nothrow
if (is(typeof(r1.ptr < r2.ptr) == bool))
{
 import std.algorithm : min, max;
 auto b = max(r1.ptr, r2.ptr);
 auto e = min(r1.ptr + r1.length, r2.ptr + r2.length);
 return b < e ? b[0 .. e - b] : null;
}

Who wore it better?


inout(T)[] overlap(T)(inout(T)[] r1, inout(T)[] r2) @trusted pure nothrow
{
import std.algorithm: min, max;
auto b = max(r1.ptr, r2.ptr);
auto e = min(r1.ptr + r1.length, r2.ptr + r2.length);
return b < e ? b[0 .. e - b] : null;
}

-Steve


Re: Who wore it better?

2016-04-15 Thread Andrei Alexandrescu via Digitalmars-d

On 04/15/2016 01:31 PM, Namespace wrote:

Since it is a template: Why these attributes: @trusted pure nothrow ?


@trusted is not inferrable, the others are type-independent and nice for 
the documentation. -- Andrei




Re: Who wore it better?

2016-04-15 Thread Namespace via Digitalmars-d
Since it is a template: Why these attributes: @trusted pure 
nothrow ?


Re: Who wore it better?

2016-04-15 Thread Andrei Alexandrescu via Digitalmars-d

https://github.com/D-Programming-Language/phobos/pull/4201 -- Andrei