Re: UFCS and overloading

2015-04-07 Thread cym13 via Digitalmars-d-learn

EDIT: mis-formatted previous snippet

import std.algorithm, std.stdio, std.range, std.conv;
void main()
{
stdin
.byLine
.filter!(s = !s.empty  s.front != '#’) // Filter with 
this lambda function

.map!(s = s.to!double) // Map the strings to doubles
.array // Sorting needs random access
.sort!((a, b) = a  b) // Another lambda
.take(10) // Applyable to any range
.writeln;
}


Re: UFCS and overloading

2015-04-07 Thread cym13 via Digitalmars-d-learn

On Monday, 6 April 2015 at 18:00:46 UTC, Szymon Gatner wrote:
Why is that? The use case is to provide a set of convenience 
extension methods to a basic interface. Say, given:


This is not the only use case, another (maybe even more common) 
use is to allow pipeline programming.


Example from one of Andrei's talks ( 
http://channel9.msdn.com/Events/Lang-NEXT/Lang-NEXT-2014/D ):


import std.algorithm, std.stdio, std.range, std.conv;
void main()
{
stdin
.byLine
.filter!(s = !s.empty  s.front != '#’) // Filter with 
this lambda function
.map!(s = s.to!double)  // Map 
the strings to doubles
.array
  // Sorting needs random access
.sort!((a, b) = a  b)  // 
Another lambda
.take(10) 
   // Applyable to any range

.writeln;
}

With such constructs, it is important to be able to call a method 
and not the function as there are ways to explicitely call the 
function but not the method (AFAIK). As this style of programming 
is actively encouraged by both Andrei and Walter, I think the 
design is coherent.


Re: UFCS and overloading

2015-04-07 Thread Szymon Gatner via Digitalmars-d-learn

On Tuesday, 7 April 2015 at 14:46:52 UTC, cym13 wrote:

EDIT: mis-formatted previous snippet

import std.algorithm, std.stdio, std.range, std.conv;
void main()
{
stdin
.byLine
.filter!(s = !s.empty  s.front != '#’) // Filter 
with this lambda function

.map!(s = s.to!double) // Map the strings to doubles
.array // Sorting needs random access
.sort!((a, b) = a  b) // Another lambda
.take(10) // Applyable to any range
.writeln;
}


Yup, I get that, still does not explain why UFCS can't extend 
overload set. Especially if there would be no conflict wrt to 
overload of method vs free function.


Re: UFCS and overloading

2015-04-06 Thread Steven Schveighoffer via Digitalmars-d-learn

On 4/6/15 12:23 PM, Szymon Gatner wrote:

Hi,

I am surprised that this doesn't work:

class Foo
{
   void bar(string) {}
}

void bar(Foo foo, int i)
{
}

auto foo = new Foo();
foo.bar(123); // === error

causing compilation error:

main.d(24): Error: function main.Foo.bar (string _param_0) is not
callable using argument types (int)

does UFCS now work with method overloading? I know it is not a syntax
error because changing the name of int version of bar to bar2 and
calling foo.bar2(123) works fine.


You can't do this. UFCS cannot add overloads, it can only add whole 
overload sets (if not already present).


-Steve


Re: UFCS and overloading

2015-04-06 Thread Szymon Gatner via Digitalmars-d-learn
On Monday, 6 April 2015 at 17:53:13 UTC, Steven Schveighoffer 
wrote:

On 4/6/15 12:23 PM, Szymon Gatner wrote:

Hi,

I am surprised that this doesn't work:

class Foo
{
  void bar(string) {}
}

void bar(Foo foo, int i)
{
}

auto foo = new Foo();
foo.bar(123); // === error

causing compilation error:

main.d(24): Error: function main.Foo.bar (string _param_0) is 
not

callable using argument types (int)

does UFCS now work with method overloading? I know it is not a 
syntax
error because changing the name of int version of bar to bar2 
and

calling foo.bar2(123) works fine.


You can't do this. UFCS cannot add overloads, it can only add 
whole overload sets (if not already present).


-Steve


Why is that? The use case is to provide a set of convenience 
extension methods to a basic interface. Say, given:


interface Subject
{
  void add(SomeInterface obj);
}

// and then
void add(Subject a, Type1 v1)
{
  a.add(convertToSomeInterface(v1));
}

void add(Subject a, Type2 v2)
{
  a.add(convertToSomeInterface(v2));
}

this way client can just implement Subject interface and still 
use it with types Type1 and Type2. C# allows that, why D does not?


Re: UFCS and overloading

2015-04-06 Thread Steven Schveighoffer via Digitalmars-d-learn

On 4/6/15 2:00 PM, Szymon Gatner wrote:

On Monday, 6 April 2015 at 17:53:13 UTC, Steven Schveighoffer wrote:

On 4/6/15 12:23 PM, Szymon Gatner wrote:

Hi,

I am surprised that this doesn't work:

class Foo
{
  void bar(string) {}
}

void bar(Foo foo, int i)
{
}

auto foo = new Foo();
foo.bar(123); // === error

causing compilation error:

main.d(24): Error: function main.Foo.bar (string _param_0) is not
callable using argument types (int)

does UFCS now work with method overloading? I know it is not a syntax
error because changing the name of int version of bar to bar2 and
calling foo.bar2(123) works fine.


You can't do this. UFCS cannot add overloads, it can only add whole
overload sets (if not already present).


Why is that? The use case is to provide a set of convenience extension
methods to a basic interface. Say, given:

interface Subject
{
   void add(SomeInterface obj);
}

// and then
void add(Subject a, Type1 v1)
{
   a.add(convertToSomeInterface(v1));
}

void add(Subject a, Type2 v2)
{
   a.add(convertToSomeInterface(v2));
}

this way client can just implement Subject interface and still use it
with types Type1 and Type2. C# allows that, why D does not?


In D, the symbol itself is used to find the appropriate overload set 
and then the parameters are used within the set to figure out the 
specific overload to use. Overload sets have different precedence, with 
I think members having the highest precedent, and likely UFCS having the 
lowest. But once an overload set is found, anything defined outside that 
set is not seen.


This is done in part to prevent hijacking of functions. For example, if 
you wanted to change the meaning of some code by defining a better 
overload match.


This doesn't mean it couldn't be changed, but it is definitely 
implemented as designed.


-Steve


UFCS and overloading

2015-04-06 Thread Szymon Gatner via Digitalmars-d-learn

Hi,

I am surprised that this doesn't work:

class Foo
{
  void bar(string) {}
}

void bar(Foo foo, int i)
{
}

auto foo = new Foo();
foo.bar(123); // === error

causing compilation error:

main.d(24): Error: function main.Foo.bar (string _param_0) is not 
callable using argument types (int)


does UFCS now work with method overloading? I know it is not a 
syntax error because changing the name of int version of bar to 
bar2 and calling foo.bar2(123) works fine.