February 16, 2016
On 16.02.2016 11:21, krzaq wrote:
>
> By the way, your example in C++ would be even worse:
>
> auto sum_of_filtered = x
>      .map([&](auto&& val){ foo(val); })
>      .filter([](auto&& val){ return is_bar(val); })
>      .reduce(std::plus<>{});
>
> vs
>
> auto sum_of_filtered =
> reduce(filter(map(x, [&](auto&& val){ foo(val); }) ,[](auto&& val){
> return is_bar(val); }), std::plus<>{});

auto sum_of_filtered = x >>=
  map([&](auto&& val){ return foo(val); })
| filter([](auto&& val){ return is_bar(val); })
| reduce(std::plus<>{});
February 17, 2016
On Tuesday, 16 February 2016 at 11:08:28 UTC, Timon Gehr wrote:
> On 16.02.2016 11:21, krzaq wrote:
>>
>> By the way, your example in C++ would be even worse:
>>
>> auto sum_of_filtered = x
>>      .map([&](auto&& val){ foo(val); })
>>      .filter([](auto&& val){ return is_bar(val); })
>>      .reduce(std::plus<>{});
>>
>> vs
>>
>> auto sum_of_filtered =
>> reduce(filter(map(x, [&](auto&& val){ foo(val); }) ,[](auto&& val){
>> return is_bar(val); }), std::plus<>{});
>
> auto sum_of_filtered = x >>=
>   map([&](auto&& val){ return foo(val); })
> | filter([](auto&& val){ return is_bar(val); })
> | reduce(std::plus<>{});

This will only work with stream-aware functions. That might've been your intention, but to me it's only the next best thing. Additionally, adding IDE code completion will be pretty difficult here.
February 19, 2016
On Tue, 16 Feb 2016 08:08:46 +0000, Ola Fosheim Grøstad wrote:

> On Tuesday, 16 February 2016 at 07:59:49 UTC, w0rp wrote:
>> Personally, I find this proposal for C++ to be laughable. It's like hitch hiking from New York to California, and only getting as far as Texas and calling it good.
>>
>> The great thing about our UFCS is the left-to-right chaining of algorithms.
>>
>> x.map!(...).filter!(...).reduce!(...)
>>
>> It beats the Hell out of...
>>
>> reduce!(...)(filter!(...)(map!(...)(x)))
>>
>> This proposal will encourage non member functions, which is good, but will never reach the "aha" moment D had which gave us UFCS chaining.
> 
> Ugh, that syntax is abusing the implied semantics of dot-notation; member-access. Better to have a pipeline operator.
> 
> Such syntax abuse is common in other languages too, so I don't get the "aha". It is more a case of "ugh, repeated mistake"...
> 
> Explicit extension methods is a much better alternative.


+1 !!

I *completely* agree with this. UFCS is OK in some places but not everywhere like people do lately. What you said about abusing the dot- notation is on the spot. It is not uncommon nowadays to see D code that I have absolutely no idea what it does, because of UFCS. I have to go through each piece separated by dots to understand what it is...

-- 
Dejan Lekic
  ✉ dejan.lekic (at) gmail.com
  ➚ http://dejan.lekic.org
February 19, 2016
On Friday, 19 February 2016 at 16:18:12 UTC, Dejan Lekic wrote:
> I have to go through each piece separated by dots to understand what it is...

Let me play devil's advocate here: How would this be any different if UFCS were not used?

 — David
February 20, 2016
On Friday, 19 February 2016 at 16:42:36 UTC, David Nadlinger wrote:
> On Friday, 19 February 2016 at 16:18:12 UTC, Dejan Lekic wrote:
>> I have to go through each piece separated by dots to understand what it is...
>
> Let me play devil's advocate here: How would this be any different if UFCS were not used?

// if a has a process
if( a.process ) …

// if processing a was successful
if( process(a) ) ...

// copy a to b
a.copy_to(b)

// copy b to a
copy_to(a,b)

// print a on stream f
f.print(a)

// print f and a on std out
print(f,a)

// count the number of people, cars and drinks
count(people,cars,drinks)

// count the number of cars and drinks people has
people.count(cars,drinks)

If you have namespace operator "::" in c++ or "'" in Ada (IIRC) and extension methods

// access library "as" extension method string
obj1.as'string

etc…



February 21, 2016
On Saturday, 13 February 2016 at 10:27:59 UTC, Daniel N wrote:
> "Abstract
> This is the proposed wording for a unified call syntax based on the idea that f(x,y) can invoke a member function, x.f(y), if there are no f(x,y). The inverse transformation, from x.f(y) to f(x,y) is not proposed."
>
> They were considering 6 alternatives and chose the worst...
> https://isocpp.org/files/papers/P0251R0.pdf

Am I crazy, or is this paper proposing the exact opposite of what would be needed to do chaning of ranges or extension methods?

I don't get how it would be useful at all to type f(x, y) and have the compiler call x.f(y) for me. Why would I ever not want to just use member invocation syntax?

    Bit
February 21, 2016
On Sunday, 21 February 2016 at 00:52:13 UTC, bitwise wrote:
> I don't get how it would be useful at all to type f(x, y) and have the compiler call x.f(y) for me. Why would I ever not want to just use member invocation syntax?

 One reason could be connecting to OO based code that's written purely in C (but doesn't have the member invocation). I think a good portion of XWindows was written that way.

 Beyond that I'm not sure.
February 21, 2016
On Sunday, 21 February 2016 at 00:52:13 UTC, bitwise wrote:
> Am I crazy, or is this paper proposing the exact opposite of what would be needed to do chaning of ranges or extension methods?

That is a good thing.

> I don't get how it would be useful at all to type f(x, y) and have the compiler call x.f(y) for me. Why would I ever not want to just use member invocation syntax?

Generic code cannot assume they exist. E.g. cbegin(x)



February 21, 2016
On Friday, 19 February 2016 at 16:18:12 UTC, Dejan Lekic wrote:
> I *completely* agree with this. UFCS is OK in some places but not everywhere like people do lately. What you said about abusing the dot- notation is on the spot. It is not uncommon nowadays to see D code that I have absolutely no idea what it does, because of UFCS. I have to go through each piece separated by dots to understand what it is...

Well, you could actually argue the exact same thing about function overloading and overriding, which is part of why Linus Torvalds prefers C to C++ - ostensibly, you can look at a chunk of C code and know exactly what it's doing without a lot of context, which is often not at all true in languages which have overloading and the like (especially when operator overloading gets added into the mix). Now, how big a deal that is is debatable, but it's something that some folks have complained about, whereas many folks would never want to have to deal with not having function overloading. With regards to UFCS, some folks think that it makes code way cleaner and easier to figure out what's going on, whereas others think that it's worse.

Personally, I'm enough used to dealing with functional languages, that not having UFCS doesn't bother me that much, though it's easier to have clean, long UFCS chains than it is to have clean, long normal function call chains, because the number of parens tend to drown things out.

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. 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.

- Jonathan M Davis
February 21, 2016
On Sunday, 21 February 2016 at 00:52:13 UTC, bitwise wrote:
> On Saturday, 13 February 2016 at 10:27:59 UTC, Daniel N wrote:
>> "Abstract
>> This is the proposed wording for a unified call syntax based on the idea that f(x,y) can invoke a member function, x.f(y), if there are no f(x,y). The inverse transformation, from x.f(y) to f(x,y) is not proposed."
>>
>> They were considering 6 alternatives and chose the worst...
>> https://isocpp.org/files/papers/P0251R0.pdf
>
> Am I crazy, or is this paper proposing the exact opposite of what would be needed to do chaning of ranges or extension methods?
>
> I don't get how it would be useful at all to type f(x, y) and have the compiler call x.f(y) for me. Why would I ever not want to just use member invocation syntax?

Because UFCS is not about chaining function calls. It's about being able to call a function without worrying about whether it's a free function or a member function. Without some form of UFCS, it really doesn't work well for generic code to be able to call a function when some types define the function and others work with a free function with the same name, because the syntax to call them is different, meaning that the same code won't work with both types. Regardless of whether UFCS is foo(x, y) or x.foo(y), it allows for a _universal_ way to call a function (hence the name Universal Function Call Syntax). That's the whole point.

Much as many folks love how D's version of UFCS makes it really easy to chain function calls, it's really not the main goal of UFCS. It's just a nice side effect of how we've done it. C++ will still get all of the benefits for generic code the way that they're doing it. So, they'll get the intended benefit of UFCS. They just won't get the side benefits that many folks like about the syntax that D chose.

- Jonathan M Davis