Thread overview
Module names shadowing defined functions/templates.
Sep 29, 2016
Minty Fresh
Sep 29, 2016
Minty Fresh
Sep 29, 2016
Joakim
Sep 29, 2016
Minty Fresh
Sep 29, 2016
Walter Bright
Sep 29, 2016
bachmeier
Sep 29, 2016
Timon Gehr
Sep 29, 2016
Jacob Carlborg
Sep 29, 2016
Adam D. Ruppe
September 29, 2016
I ran into this issue just recently when trying to write a least-squares optimization function.
Notably,

  module leastsq;

  T[] leastsq(alias func, T)(T[] vec, . . .)
  {
      . . .
  }

It becomes impossible to import and call this template function from outside the module it's declared in. Trying to do so just yields:

  Error: function expected before (), not module leastsq of type void

This is really inconvenient. `leastsq` has a very long and implementation, most of which is not a public API. It makes sense to put it into its own module because it and all of the functions it uses internally are some 1000 lines long.

I don't really know of any other language that faces this limitation.
September 29, 2016
As an addendum to the above, the error message I posted was from the overload that takes a delegate as a runtime parameter.

Trying to pass template arguments just gives you:

   Error: template instance leastsq!((p) => p) leastsq is not a template declaration, it is a import
September 29, 2016
On Thursday, 29 September 2016 at 01:54:42 UTC, Minty Fresh wrote:
> I ran into this issue just recently when trying to write a least-squares optimization function.
> Notably,
>
>   module leastsq;
>
>   T[] leastsq(alias func, T)(T[] vec, . . .)
>   {
>       . . .
>   }
>
> It becomes impossible to import and call this template function from outside the module it's declared in. Trying to do so just yields:
>
>   Error: function expected before (), not module leastsq of type void
>
> This is really inconvenient. `leastsq` has a very long and implementation, most of which is not a public API. It makes sense to put it into its own module because it and all of the functions it uses internally are some 1000 lines long.
>
> I don't really know of any other language that faces this limitation.

I ran into this too, it is annoying. I think you're supposed to use different names.
September 29, 2016
On Thursday, 29 September 2016 at 02:26:15 UTC, Joakim wrote:
> I ran into this too, it is annoying. I think you're supposed to use different names.

It's a rather painful limitation if that were the case.
Going with the example I gave, what would an alternative name for the module be? All it's public members are named `leastsq`.

While I can imagine there are technical challenges that have caused this issue to be the way it is, it's still a pretty major flaw to try to work around.

Working around shortcomings of a language is never a good place to be in.
September 28, 2016
On 9/28/2016 9:17 PM, Minty Fresh wrote:
> While I can imagine there are technical challenges that have caused this issue
> to be the way it is, it's still a pretty major flaw to try to work around.

Overloading of names is a constant minefield of unexpected problems, arbitrary rules to disambiguate, and obtuse error messages when the compiler picks the wrong one. Worse, this proposal is asking for syntax-dependent name lookups.

Having a consistent, general name lookup scheme has its own advantages, like predictability, as opposed to a lot of special case rules.


> Working around shortcomings of a language is never a good place to be in.

I recommend changing one of the names and moving on.

September 29, 2016
On 2016-09-29 04:26, Joakim wrote:

> I ran into this too, it is annoying. I think you're supposed to use
> different names.

Yeah, especially since I have a lot of module looking like this:

module main;

void main()
{
    // some stuff
}

This works since "main" is a special function which is never explicitly called.

-- 
/Jacob Carlborg
September 29, 2016
On Thursday, 29 September 2016 at 04:17:56 UTC, Minty Fresh wrote:
> On Thursday, 29 September 2016 at 02:26:15 UTC, Joakim wrote:
>> I ran into this too, it is annoying. I think you're supposed to use different names.
>
> It's a rather painful limitation if that were the case.
> Going with the example I gave, what would an alternative name for the module be? All it's public members are named `leastsq`.
>
> While I can imagine there are technical challenges that have caused this issue to be the way it is, it's still a pretty major flaw to try to work around.
>
> Working around shortcomings of a language is never a good place to be in.

It's slightly annoying, yes, but is it a big deal? Can't you just name the module lsq rather than leastsq? Apparently this is a tradeoff of inconvenience for simplicity.
September 29, 2016
On 29.09.2016 06:17, Minty Fresh wrote:
>
> Going with the example I gave, what would an alternative name for the
> module be? All it's public members are named `leastsq`.

I usually just add an underscore to the module name. module leastsq_;
September 29, 2016
On Thursday, 29 September 2016 at 01:54:42 UTC, Minty Fresh wrote:
>   module leastsq;

Here's my tip: always give a module a name with at least two pieces, and always write it explicitly.

So make it `module your_name.leastsq;`.

If you ever end up mixing modules from different projects, this makes the odds of a name collision a lot lower. It also solves the problem you have here.


> It becomes impossible to import and call this template function from outside the module it's declared in.

It isn't impossible, you just need to rename the import.

import leastsq_ = leastsq;

then it works with the naked name and you still get the ability to disambiguate items by their full name.

Though I still recommend just giving the module a two part name.

> I don't really know of any other language that faces this limitation.

It's not a limitation, it is one of the nicest features to allow code interoperation. Look at the hoops Javascript jumps through to get this, wrapping everything in a self-calling function, returning objects with various names, and it still risks overwriting some other library's code with your local stuff accidentally.

In D, such things just work.