June 10, 2013
ok I found what I think is the best solution to this problem :-)
see:
http://forum.dlang.org/post/mailman.1002.1370829729.13711.digitalmars-d-learn@puremagic.com



On Sun, Jun 9, 2013 at 6:59 PM, Jonathan M Davis <jmdavisProg@gmx.com>wrote:

> On Monday, June 10, 2013 11:44:56 Daniel Murphy wrote:
> > In this case we can prevent problem simply by not giving functions
> generic
> > names like 'compress'.  Ideally you should be able to import the entire standard library with no name conflicts.
>
> We've actually made the opposite choice when discussing this in the past.
> We've specifically gone for making functions which do the same thing in
> different modules having the same name (e.g. std.ascii and std.uni), which
> makes swapping one for the other easy and avoids having to come up with
> distinct names, though it does obviously create more naming conflicts when
> you
> try and mix and match such modules. I'd also point out that it's been
> argued
> that it's a failure of the module system if we're specifically trying to
> avoid
> having different modules have functions with the same name. It's the module
> system's job to differentiate such functions, and specifically avoiding
> naming
> stuff the same to avoid naming conflicts means that you're pretty much
> ignoring
> the module system.
>
> So, the general approach has been to name functions differently when they
> do
> different things and name them the same when they do the same thing and
> then
> let the module system take care of differentiating between the two when you
> need to.
>
> - Jonathan M Davis
>


June 10, 2013
On Monday, 10 June 2013 at 01:59:29 UTC, Jonathan M Davis wrote:
> On Monday, June 10, 2013 11:44:56 Daniel Murphy wrote:
>> In this case we can prevent problem simply by not giving functions generic
>> names like 'compress'.  Ideally you should be able to import the entire
>> standard library with no name conflicts.
>
> We've actually made the opposite choice when discussing this in the past.
> We've specifically gone for making functions which do the same thing in
> different modules having the same name (e.g. std.ascii and std.uni), which
> makes swapping one for the other easy and avoids having to come up with
> distinct names, though it does obviously create more naming conflicts when you
> try and mix and match such modules. I'd also point out that it's been argued
> that it's a failure of the module system if we're specifically trying to avoid
> having different modules have functions with the same name. It's the module
> system's job to differentiate such functions, and specifically avoiding naming
> stuff the same to avoid naming conflicts means that you're pretty much ignoring
> the module system.
>
> So, the general approach has been to name functions differently when they do
> different things and name them the same when they do the same thing and then
> let the module system take care of differentiating between the two when you
> need to.
>
> - Jonathan M Davis

You are wise and speak the truth :P
June 11, 2013
"Jonathan M Davis" <jmdavisProg@gmx.com> wrote in message news:mailman.1001.1370829569.13711.digitalmars-d@puremagic.com...
> On Monday, June 10, 2013 11:44:56 Daniel Murphy wrote:
>> In this case we can prevent problem simply by not giving functions
>> generic
>> names like 'compress'.  Ideally you should be able to import the entire
>> standard library with no name conflicts.
>
> We've actually made the opposite choice when discussing this in the past.
> We've specifically gone for making functions which do the same thing in
> different modules having the same name (e.g. std.ascii and std.uni), which
> makes swapping one for the other easy and avoids having to come up with
> distinct names, though it does obviously create more naming conflicts when
> you
> try and mix and match such modules. I'd also point out that it's been
> argued
> that it's a failure of the module system if we're specifically trying to
> avoid
> having different modules have functions with the same name. It's the
> module
> system's job to differentiate such functions, and specifically avoiding
> naming
> stuff the same to avoid naming conflicts means that you're pretty much
> ignoring
> the module system.
>
> So, the general approach has been to name functions differently when they
> do
> different things and name them the same when they do the same thing and
> then
> let the module system take care of differentiating between the two when
> you
> need to.
>
> - Jonathan M Davis

The difference here is these are range functions and you lose ufcs.  It doesn't make much difference unless you are trying to chain them.

Ranges, and call chaining of range-based functions using ufcs, are among the most attractive features of phobos.  Let's define a new general approach, and keep them conflict-free when possible.

Also, compress is a ridiculously general name for a function.


June 11, 2013
"Timothee Cour" <thelastmammoth@gmail.com> wrote in message news:mailman.1003.1370829991.13711.digitalmars-d@puremagic.com...
> ok I found what I think is the best solution to this problem :-)
> see:
> http://forum.dlang.org/post/mailman.1002.1370829729.13711.digitalmars-d-learn@puremagic.com
>

That's pretty awesome, but still much much much uglier than not having to disambiguate in the first place.


June 11, 2013
On Tuesday, 11 June 2013 at 13:13:56 UTC, Daniel Murphy wrote:
> Also, compress is a ridiculously general name for a function.

We have module-level functions called "copy" (multiple), "read", "write", "map", etc. already, and it's not a bad thing!

It's OK because the full name is not "compress", but "std.compression.lz77.compress". This way, how specific the code wants to be depends on the user and the particular use-case, instead of one-size-fits-all alternatives like "lz77Compress". There's no redundancy in the name yet we still have the option to be pin-point specific (e.g. static import), and yes, we still get to use UFCS!

To eliminate the UFCS problem - which doesn't happen very often (how often do you want to use two different compression algorithms in the same unit?), we can (must?) use renamed symbols when importing.

Since any example using multiple "compress" functions would be contrived, I'll use an existing conflict - the case of "copy".

The following program backs up the specified files and writes a nicely formatted message to stdout (OK, so a tiny bit contrived):
----
void main(string[] args)
{
	import std.algorithm : chain, copy, joiner;
	import std.array : empty;
	import std.file : fileCopy = copy; // `fileCopy` is std.file.copy
	import std.stdio : stdout;

	auto fileNames = args[1 .. $];

	foreach(fileName; fileNames)
		fileName.fileCopy(fileName ~ ".bak");

	if(!fileNames.empty)
		"Backed up the following files: "
			.chain(fileNames.joiner(", "))
			.copy(stdout.lockingTextWriter());
}
----

By eliminating redundancies from symbol names, we empower the user, and the module system offers all the tools necessary to solve conflicts in a variety of ways.
June 11, 2013
On Tue, Jun 11, 2013 at 11:22 AM, Jakob Ovrum <jakobovrum@gmail.com> wrote:

> On Tuesday, 11 June 2013 at 13:13:56 UTC, Daniel Murphy wrote:
>
>> Also, compress is a ridiculously general name for a function.
>>
>
> We have module-level functions called "copy" (multiple), "read", "write", "map", etc. already, and it's not a bad thing!
>
> It's OK because the full name is not "compress", but "std.compression.lz77. **compress". This way, how specific the code wants to be depends on the user and the particular use-case, instead of one-size-fits-all alternatives like "lz77Compress". There's no redundancy in the name yet we still have the option to be pin-point specific (e.g. static import), and yes, we still get to use UFCS!
>
> To eliminate the UFCS problem - which doesn't happen very often (how often
> do you want to use two different compression algorithms in the same unit?),
> we can (must?) use renamed symbols when importing.
>

I have found a better way to do that: see
http://forum.dlang.org/post/mailman.1002.1370829729.13711.digitalmars-d-learn@puremagic.com
subject: 'best way to handle UFCS with ambiguous names: using
std.typetuple.Alias!'
syntax: 'arg1.Alias!(std.file.write).arg2'*
see related discussion for reasoning. I'd like to push this as standard way
to deal with ambiguities.


>
> Since any example using multiple "compress" functions would be contrived, I'll use an existing conflict - the case of "copy".
>
> The following program backs up the specified files and writes a nicely formatted message to stdout (OK, so a tiny bit contrived):
> ----
> void main(string[] args)
> {
>         import std.algorithm : chain, copy, joiner;
>         import std.array : empty;
>         import std.file : fileCopy = copy; // `fileCopy` is std.file.copy
>         import std.stdio : stdout;
>
>         auto fileNames = args[1 .. $];
>
>         foreach(fileName; fileNames)
>                 fileName.fileCopy(fileName ~ ".bak");
>
>         if(!fileNames.empty)
>                 "Backed up the following files: "
>                         .chain(fileNames.joiner(", "))
>                         .copy(stdout.**lockingTextWriter());
> }
> ----
>
> By eliminating redundancies from symbol names, we empower the user, and the module system offers all the tools necessary to solve conflicts in a variety of ways.
>


June 11, 2013
On Tuesday, 11 June 2013 at 18:43:45 UTC, Timothee Cour wrote:
> I have found a better way to do that: see
> http://forum.dlang.org/post/mailman.1002.1370829729.13711.digitalmars-d-learn@puremagic.com
> subject: 'best way to handle UFCS with ambiguous names: using
> std.typetuple.Alias!'
> syntax: 'arg1.Alias!(std.file.write).arg2'*
> see related discussion for reasoning. I'd like to push this as standard way
> to deal with ambiguities.

It's clearly an option, but I think it's too syntactically heavy, causing more harm than good (the idea of UFCS is, of course, readability!).

Since these conflicting symbols are in the minority for the vast majority of code units, I think renamed symbols are much, much better.
June 11, 2013
On Tuesday, June 11, 2013 20:50:17 Jakob Ovrum wrote:
> On Tuesday, 11 June 2013 at 18:43:45 UTC, Timothee Cour wrote:
> > I have found a better way to do that: see
> > http://forum.dlang.org/post/mailman.1002.1370829729.13711.digitalmars-d-le
> > arn@puremagic.com subject: 'best way to handle UFCS with ambiguous names:
> > using
> > std.typetuple.Alias!'
> > syntax: 'arg1.Alias!(std.file.write).arg2'*
> > see related discussion for reasoning. I'd like to push this as
> > standard way
> > to deal with ambiguities.
> 
> It's clearly an option, but I think it's too syntactically heavy, causing more harm than good (the idea of UFCS is, of course, readability!).
> 
> Since these conflicting symbols are in the minority for the vast majority of code units, I think renamed symbols are much, much better.

Agreed.

- Jonathan M Davis
June 11, 2013
"Jakob Ovrum" <jakobovrum@gmail.com> wrote in message news:fjmuuahorgbwkcvygnqq@forum.dlang.org...
> On Tuesday, 11 June 2013 at 13:13:56 UTC, Daniel Murphy wrote:
>> Also, compress is a ridiculously general name for a function.
>
> We have module-level functions called "copy" (multiple), "read", "write", "map", etc. already, and it's not a bad thing!
>

It is.

> It's OK because the full name is not "compress", but "std.compression.lz77.compress". This way, how specific the code wants to be depends on the user and the particular use-case, instead of one-size-fits-all alternatives like "lz77Compress". There's no redundancy in the name yet we still have the option to be pin-point specific (e.g. static import), and yes, we still get to use UFCS!
>

There is a reason we don't call every function in phobos 'process' and let the module name tell us what is actually does - when you see the name in your source code, it is easy to recognize what is being done.

> To eliminate the UFCS problem - which doesn't happen very often (how often do you want to use two different compression algorithms in the same unit?), we can (must?) use renamed symbols when importing.
>

My workplace has a fire extinguisher, but this doesn't mean lighting fires is a good idea.

I know we have the tools to disambiguate, but they come at a syntax and/or clarity cost.  Why create a problem when we don't have to?

> Since any example using multiple "compress" functions would be contrived, I'll use an existing conflict - the case of "copy".
>

Eg. Code which implements http compression with support for multiple algorithms.

tl;dr We have great tools to disambiguate when we have to.  Let's not have to.


June 13, 2013
On Tuesday, 11 June 2013 at 22:34:55 UTC, Daniel Murphy wrote:
> There is a reason we don't call every function in phobos 'process' and let
> the module name tell us what is actually does - when you see the name in
> your source code, it is easy to recognize what is being done.

"copy", "write" and "compress" are perfectly recognizable names.

> tl;dr We have great tools to disambiguate when we have to.  Let's not have
> to.

The way I see it, you're asking that all code should pay for the benefit of a minority of cases. I'd choose the inverse.