Re: UFCS for arguments other than first?

2016-11-12 Thread Heisenberg via Digitalmars-d
On Friday, 11 November 2016 at 23:27:30 UTC, Jonathan M Davis 
wrote:
Ultimately, the only technical benefit from UFCS is that it 
allows you to call a function without caring whether it's a 
member function or a free function, which is of great benefit 
to generic code and not really much else. Otherwise, it's just 
a syntactic preference - albeit one that many people prefer.


- Jonathan M Davis


If many people prefer it - why not develop it further? UCFS, 
along with other 'D Gems' is one of the selling points of the 
language, after all.


Re: UFCS for arguments other than first?

2016-11-12 Thread Heisenberg via Digitalmars-d

On Saturday, 12 November 2016 at 06:42:24 UTC, Temtaime wrote:

You are wrong. We can use n1 for the second parameter.

int someNumber(int a, int b)
 {
 return a + b;
 }

int main()
{
 int n1 = 5;
 return (n1.someNumber = n1); // 10
 }


In this specific case, yes - however:


int getResult(int a, int b, int c)
{
return(a * 2 - b * 3 + c * 4);
}
int main()
{
   int n1 = 3, n2 = 5, n3 = 7;
   // If one needs to chain n3,
   // but requires it to be entered
   // as the third argument?
   return(n3.getResult(n1, n2)); // `n3` is the `a`
   return(n3.getResult = tuple(n1, n2)[]); // still `a`
}


Being able to specify the position would help maintain 'the 
chain' intact.


Re: UFCS for arguments other than first?

2016-11-11 Thread Temtaime via Digitalmars-d

On Friday, 11 November 2016 at 16:39:26 UTC, Heisenberg wrote:
What would it take to implement the Uniform Function Call 
Syntax for a function's argument which is not the first?


Right now it is possible to do the following:


int someNumber(int a, int b)
{
return a + b;
}

void main()
{
int n1 = 5;
int n2 = n1.someNumber(n1 + 1); // Here the `n1` is `a`
}


But it's not possible to use the `n1' as `b`, for UFCS only 
substitutes the expression before the `.` for the first 
argument. This limits a little bit the flexibility of UFCS. 
What would it take to specify the argument in which UFCS is 
going to put the expression before the `.`? This would make it 
even more useful.


For instance:


string someStr = "Yohoho!";
// To format and print it, one could use `printf':
writefln("The string is \"%s\".", someStr);
// But since it is not in the first place,
// it is not possible to use UFCS for it:
someStr.writefln("The string is \"%s\"."); // ^ Prints 
`Yohoho!'

// One could use tuples to pass
// the expanded list of strings:
tuple("The string is \"%s\".", someStr)[].writefln();
// But it would be much easier if there was
// some way to tell the compiler
// to position the argument,
// for example:
someStr&1.writefln("The string is \"%s\".");
// ^^ argument at the position [0]
// ^ argument to be put at the position [1]
// This could even allow to insert the argument
// at more than one position at once:
someStr&1&3&4.writefln("Say it, lass!\n" ~
   "%s\nI'm a pirate!\n" ~  // someStr 
goes here (1)

   "%s\nHe's a pirate!\n" ~ // not here (2)
   "She's a pirate!\n%s" ~  // here (3)
   "Ale! Rum! %s\n" ~   // and here (4)
   "Wait.. Why is the rum gone?",
   "You are a pirate!");// gets shifted
// to position 
(2)


You are wrong. We can use n1 for the second parameter.

int someNumber(int a, int b)
 {
 return a + b;
 }

int main()
{
 int n1 = 5;
 return (n1.someNumber = n1); // 10
 }


Re: UFCS for arguments other than first?

2016-11-11 Thread Jonathan M Davis via Digitalmars-d
On Friday, November 11, 2016 22:48:24 Heisenberg via Digitalmars-d wrote:
> Isn't the whole point of UFCS implementation in providing better
> re-usability and scalability, helping the encapsulation, making
> the chaining of function calls easier?

The primary benefit of UFCS is so that generic code can call a function
without caring whether it's dealing with a member function or a free
function, allowing you to declare free functions to act like member
functions for types that are lacking the member function in question or
allowing a member function to provide a specialization of a more general
free function in cases where the type could implement the function more
efficiently than the general implementation would be (e.g. a sorted,
random-access range could implement find itself to do binary search, or if a
range were backed by a binary tree, it could implement find to do a lookup
rather than searching linearly).

The secondary benefit that leads many folks to want to use UFCS is that they
find it easier to read code when the functions are chained with . rather
than by nesting function calls in the normal manner, but that's a matter of
preference rather than providing any actual technical benefit. If the
function is a free function, then it really doesn't matter whether you use
UFCS or not with regards to what the code does or your ability to chain
function calls. It's just personal preference based on what you find easier
or harder to read.

As for reusability and scalability, I don't see how UFCS has any impact on
those at all. Making a function be a generic free function can help with
that, but that doesn't require that you use UFCS. Similarly, if you want to
encapsulate code by using free functions rather than member functions, UFCS
isn't required, and if all you're doing is turning a member function into a
free function that takes that type (as opposed to making the function
generic), then it doesn't even improve encapsulation unless its in a
different module, because everything inside of a module has access to
everything else within a module.

Ultimately, the only technical benefit from UFCS is that it allows you to
call a function without caring whether it's a member function or a free
function, which is of great benefit to generic code and not really much
else. Otherwise, it's just a syntactic preference - albeit one that many
people prefer.

- Jonathan M Davis



Re: UFCS for arguments other than first?

2016-11-11 Thread Heisenberg via Digitalmars-d

On Friday, 11 November 2016 at 21:51:29 UTC, John Colvin wrote:

On Friday, 11 November 2016 at 18:33:09 UTC, Heisenberg wrote:

On Friday, 11 November 2016 at 17:07:50 UTC, John Colvin wrote:
I'm sure there are loads of corner cases this doesn't cover, 
but:


template inPos(uint n, alias f)
{
auto inPos(Args...)(auto ref Args args)
{
return f(args[1 .. n+1], args[0], args[n+1 .. $]);
}
}

import std.stdio;
alias formatSecond = inPos!(1, writefln);

void main()
{

1.writeln(2,3,4,5);
1.inPos!(2, writeln)(2,3,4,5);

42.formatSecond("The answer is %d");
}

and of course you could easily develop more powerful 
templates that could do any other order manipulations you 
like.


That might be a solution as well. Specifying the position near 
the variable will make the code much more straightforward to 
read though, while not forcing the programmer to declare 
separate templates in order to specify the position of a 
function's argument..


Not sure if either of those reasons are language-change worthy.


Isn't the whole point of UFCS implementation in providing better 
re-usability and scalability, helping the encapsulation, making 
the chaining of function calls easier?


- 
http://www.drdobbs.com/cpp/uniform-function-call-syntax/232700394
- 
https://forum.dlang.org/reply/ldlgoxuivwinqimta...@forum.dlang.org





Re: UFCS for arguments other than first?

2016-11-11 Thread John Colvin via Digitalmars-d

On Friday, 11 November 2016 at 18:33:09 UTC, Heisenberg wrote:

On Friday, 11 November 2016 at 17:07:50 UTC, John Colvin wrote:
I'm sure there are loads of corner cases this doesn't cover, 
but:


template inPos(uint n, alias f)
{
auto inPos(Args...)(auto ref Args args)
{
return f(args[1 .. n+1], args[0], args[n+1 .. $]);
}
}

import std.stdio;
alias formatSecond = inPos!(1, writefln);

void main()
{

1.writeln(2,3,4,5);
1.inPos!(2, writeln)(2,3,4,5);

42.formatSecond("The answer is %d");
}

and of course you could easily develop more powerful templates 
that could do any other order manipulations you like.


That might be a solution as well. Specifying the position near 
the variable will make the code much more straightforward to 
read though, while not forcing the programmer to declare 
separate templates in order to specify the position of a 
function's argument..


Not sure if either of those reasons are language-change worthy.


Re: UFCS for arguments other than first?

2016-11-11 Thread Heisenberg via Digitalmars-d

On Friday, 11 November 2016 at 17:07:50 UTC, John Colvin wrote:
I'm sure there are loads of corner cases this doesn't cover, 
but:


template inPos(uint n, alias f)
{
auto inPos(Args...)(auto ref Args args)
{
return f(args[1 .. n+1], args[0], args[n+1 .. $]);
}
}

import std.stdio;
alias formatSecond = inPos!(1, writefln);

void main()
{

1.writeln(2,3,4,5);
1.inPos!(2, writeln)(2,3,4,5);

42.formatSecond("The answer is %d");
}

and of course you could easily develop more powerful templates 
that could do any other order manipulations you like.


That might be a solution as well. Specifying the position near 
the variable will make the code much more straightforward to read 
though, while not forcing the programmer to declare separate 
templates in order to specify the position of a function's 
argument..


Re: UFCS for arguments other than first?

2016-11-11 Thread John Colvin via Digitalmars-d

On Friday, 11 November 2016 at 16:39:26 UTC, Heisenberg wrote:
What would it take to implement the Uniform Function Call 
Syntax for a function's argument which is not the first?


Right now it is possible to do the following:


int someNumber(int a, int b)
{
return a + b;
}

void main()
{
int n1 = 5;
int n2 = n1.someNumber(n1 + 1); // Here the `n1` is `a`
}


But it's not possible to use the `n1' as `b`, for UFCS only 
substitutes the expression before the `.` for the first 
argument. This limits a little bit the flexibility of UFCS. 
What would it take to specify the argument in which UFCS is 
going to put the expression before the `.`? This would make it 
even more useful.


For instance:


string someStr = "Yohoho!";
// To format and print it, one could use `printf':
writefln("The string is \"%s\".", someStr);
// But since it is not in the first place,
// it is not possible to use UFCS for it:
someStr.writefln("The string is \"%s\"."); // ^ Prints 
`Yohoho!'

// One could use tuples to pass
// the expanded list of strings:
tuple("The string is \"%s\".", someStr)[].writefln();
// But it would be much easier if there was
// some way to tell the compiler
// to position the argument,
// for example:
someStr&1.writefln("The string is \"%s\".");
// ^^ argument at the position [0]
// ^ argument to be put at the position [1]
// This could even allow to insert the argument
// at more than one position at once:
someStr&1&3&4.writefln("Say it, lass!\n" ~
   "%s\nI'm a pirate!\n" ~  // someStr 
goes here (1)

   "%s\nHe's a pirate!\n" ~ // not here (2)
   "She's a pirate!\n%s" ~  // here (3)
   "Ale! Rum! %s\n" ~   // and here (4)
   "Wait.. Why is the rum gone?",
   "You are a pirate!");// gets shifted
// to position 
(2)


I'm sure there are loads of corner cases this doesn't cover, but:

template inPos(uint n, alias f)
{
auto inPos(Args...)(auto ref Args args)
{
return f(args[1 .. n+1], args[0], args[n+1 .. $]);
}
}

import std.stdio;
alias formatSecond = inPos!(1, writefln);

void main()
{

1.writeln(2,3,4,5);
1.inPos!(2, writeln)(2,3,4,5);

42.formatSecond("The answer is %d");
}

and of course you could easily develop more powerful templates 
that could do any other order manipulations you like.


UFCS for arguments other than first?

2016-11-11 Thread Heisenberg via Digitalmars-d
What would it take to implement the Uniform Function Call Syntax 
for a function's argument which is not the first?


Right now it is possible to do the following:


int someNumber(int a, int b)
{
return a + b;
}

void main()
{
int n1 = 5;
int n2 = n1.someNumber(n1 + 1); // Here the `n1` is `a`
}


But it's not possible to use the `n1' as `b`, for UFCS only 
substitutes the expression before the `.` for the first argument. 
This limits a little bit the flexibility of UFCS. What would it 
take to specify the argument in which UFCS is going to put the 
expression before the `.`? This would make it even more useful.


For instance:


string someStr = "Yohoho!";
// To format and print it, one could use `printf':
writefln("The string is \"%s\".", someStr);
// But since it is not in the first place,
// it is not possible to use UFCS for it:
someStr.writefln("The string is \"%s\"."); // ^ Prints `Yohoho!'
// One could use tuples to pass
// the expanded list of strings:
tuple("The string is \"%s\".", someStr)[].writefln();
// But it would be much easier if there was
// some way to tell the compiler
// to position the argument,
// for example:
someStr&1.writefln("The string is \"%s\".");
// ^^ argument at the position [0]
// ^ argument to be put at the position [1]
// This could even allow to insert the argument
// at more than one position at once:
someStr&1&3&4.writefln("Say it, lass!\n" ~
   "%s\nI'm a pirate!\n" ~  // someStr goes 
here (1)

   "%s\nHe's a pirate!\n" ~ // not here (2)
   "She's a pirate!\n%s" ~  // here (3)
   "Ale! Rum! %s\n" ~   // and here (4)
   "Wait.. Why is the rum gone?",
   "You are a pirate!");// gets shifted
// to position 
(2)