February 21, 2016
On Sunday, 21 February 2016 at 10:16:19 UTC, Jonathan M Davis wrote:
> As for a pipe operator, I expect that it wouldn't really help any. It would be a lot like . vs -> in that it's an unnecessary complication,

"." vs "->" isn't an unnecessary complication it is a strong typing issue, as can be seen when trying to implement a smart pointer.


> but it would actually probably be worse. If | meant that a function call could be either a member function or a free function, you'd still have no more clue about which functions were member functions than you do now,

There are many options.

It could require function objects (instantiated or non-instantiated) that provide the right opXXX members. If the protocol is well designed and fully specified then the compiler can figure out what glue-code to generate even if connecting nodes aren't directly compatible, or choose the most efficient interface (e.g. one node provides a SIMD interface)

If iterators (ranges) are a main selling point for D, then you might as well give pipelining language support, make it better than a library solution, open up for parallel execution and hardware dependent cache and loop optimizations. A pure library solution cannot do this well.


> the syntax. So, I really don't see how another syntax would help any.

Stronger typing helps when programs grow in size...

February 21, 2016
Anyway, adding extension methods to C++ could be as trivial as the name of the first parameter being "this":

std::string reverse(const std::string& this){…}

auto s = somestring.reverse();

February 21, 2016
On 2/21/2016 2:16 AM, Jonathan M Davis wrote:
> As for a pipe operator, I expect that it wouldn't really help any. It would be a
> lot like . vs -> in that it's an unnecessary complication, but it would actually
> probably be worse. If | meant that a function call could be either a member
> function or a free function, you'd still have no more clue about which functions
> were member functions than you do now, and there would be plenty of incentive to
> just not bother using . in order to be consistent. Certainly, . would become
> unnecessary.

I'm not thrilled about overloading | with a non-arithmetic purpose. I hated iostreams' use of << from the beginning.

> It's the fact that there is a way to call a function without caring
> whether it's a member function or a free function which causes the confusion.
> The syntax itself doesn't really matter. But ultimately, regardless of the
> syntax, it's a big win, because it allows us to do stuff like have find be a
> free function and then have a range which can implement find more efficiently
> overload it as a member function, and the calling code doesn't need to care. So,
> UFCS is almost always worth the confusion about whether you're calling a member
> function or not, and the confusion is just inherent to UFCS regardless of the
> syntax. So, I really don't see how another syntax would help any.

Big reasons for allowing f(x) and x.f() equivalence are:

1. Head off the temptation to fill up a class declaration with every conceivable member function:

  http://www.drdobbs.com/cpp/how-non-member-functions-improve-encapsu/184401197

2. Allow users to 'extend' a class without having to modify the original.

3. And, of course, to chain calls together.
February 22, 2016
On Sunday, 21 February 2016 at 22:32:23 UTC, Walter Bright wrote:
> I'm not thrilled about overloading | with a non-arithmetic purpose. I hated iostreams' use of << from the beginning.

 Ditto, I've always hated it as well. I recall reading that the original iostream class was an example class (and badly designed), not only does the implementation look ugly to use, but it has no value in a logical/mathematical way unlike how those operators are intended to work natively (unlike say gmp or BigNum or something).

 At least overloading the + in Java was limited strictly to concatenation of strings.

 I can sort of see how the | (pipe) might be overloaded acceptably if you're working a lot with shell (script programmers) where you send the output of one program as the input of another, but that doesn't appear to offer any real advantage compared to what is already being used with UFCS.

 Best not to break what's not broke.
February 22, 2016
On Sunday, 21 February 2016 at 22:32:23 UTC, Walter Bright wrote:
> I'm not thrilled about overloading | with a non-arithmetic purpose. I hated iostreams' use of << from the beginning.

Adding a new token is done in less than an hour, and a non-breaking change...


February 22, 2016
On Monday, 22 February 2016 at 08:07:03 UTC, Ola Fosheim Grøstad wrote:
> Adding a new token is done in less than an hour, and a non-breaking change...

I have to ask: How will adding a new token help us or improve the language?
February 23, 2016
On Monday, 22 February 2016 at 10:09:47 UTC, Era Scarecrow wrote:
> I have to ask: How will adding a new token help us or improve the language?

How will it not help?

February 23, 2016
On Tuesday, 23 February 2016 at 07:22:26 UTC, Ola Fosheim Grøstad wrote:
>> I have to ask: How will adding a new token help us or improve the language?
>
> How will it not help?

 How about let's rephrase this as a short example. Let's say we add @ for a symbol which by default just duplicates +. So:

 a @ b; //is a + b

 So:

 x[] @ y[] //is legal now too.

 foreach(i,a; x) {
   //I'll assume $ is also the same as multiply, just for fun
   //also no clue what this code would be for
     zz@=x[i@b]@y[i$(b@c)@z]$a;
//vs zz+=x[i+b]+y[i*(b+c)+z]*a;
 }


 If | effectively does the same as . (at least that's the impression I get, maybe I'm totally wrong), what benefit does it give other than confusing or obfuscating code?

 Before adding it in, I'd need a clean proof of concept of why it's a good idea to add.
February 23, 2016
On Tuesday, 23 February 2016 at 07:46:08 UTC, Era Scarecrow wrote:
>  If | effectively does the same as . (at least that's the impression I get, maybe I'm totally wrong), what benefit does it give other than confusing or obfuscating code?

It doesn't confuse or  obfuscate code, on the contrary, it brings clarity and makes the code more legible.

>  Before adding it in, I'd need a clean proof of concept of why it's a good idea to add.

*toss arms up in the air*

February 23, 2016
On Tuesday, 23 February 2016 at 10:16:43 UTC, Ola Fosheim Grøstad wrote:
> On Tuesday, 23 February 2016 at 07:46:08 UTC, Era Scarecrow wrote:
>>  If | effectively does the same as . (at least that's the impression I get, maybe I'm totally wrong), what benefit does it give other than confusing or obfuscating code?
>
> It doesn't confuse or  obfuscate code, on the contrary, it brings clarity and makes the code more legible.

 You know, i remember that in C there was a dereferencing symbol, it was ->, and that was thrown out for UFCS as well as simplicity.

 c->x and c.x were basically the same. Why not use -> instead of | ?

 That would be fun wouldn't it. To borrow from w0rp's post earlier as I don't do this much.

x.map!(...).filter!(...).reduce!(...)
x.map!(...)|filter!(...)|reduce!(...)
x.map!(...)->filter!(...)->reduce!(...)

Honestly looking at them side by side, I don't like |, -> is almost preferable except I sometimes don't hit the > and have to re-edit it, unlike using ., but that's a minor gripe there.

 Hell why not extend to the rest of the operators? Don't forget C++'s iostream pushes using very specific low level operations to do weird things.

x.map!(...)>>filter!(...)>>reduce!(...)
x.map!(...)<<filter!(...)<<reduce!(...)
x.map!(...)^filter!(...)^reduce!(...)
x.map!(...)-filter!(...)-reduce!(...)
x.map!(...)+filter!(...)+reduce!(...)
x.map!(...)&filter!(...)&reduce!(...)
x.map!(...)*filter!(...)*reduce!(...)
x.map!(...)!filter!(...)!reduce!(...)
x.map!(...)~filter!(...)~reduce!(...)
x.map!(...)%filter!(...)%reduce!(...)

Why stop there?

x.map!(...)&&filter!(...)&&reduce!(...)
x.map!(...)||filter!(...)||reduce!(...)
x.map!(...)::filter!(...)::reduce!(...)
x.map!(...)=>filter!(...)=>reduce!(...)
x.map!(...)++filter!(...)++reduce!(...)
x.map!(...)--filter!(...)--reduce!(...)
x.map!(...)<=>filter!(...)<=>reduce!(...)
x.map!(...)<>filter!(...)<>reduce!(...)
x.map!(...)>=<filter!(...)>=<reduce!(...)
x.map!(...)><filter!(...)><reduce!(...)
x.map!(...)!!filter!(...)!!reduce!(...)
x.map!(...)~~filter!(...)~~reduce!(...)
x.map!(...)%%filter!(...)%%reduce!(...)

I still stand by that _unless_ it shows it really improves it somehow, or adds something vital that it shouldn't be there.