www.digitalmars.com         C & C++   DMDScript  

digitalmars.D.learn - std.functional.compose compilation error

reply Antonio Corbi <amcb ggmail.com> writes:
Hello,

Trying to compile this example from Chuck Allison:
-------------------------------------------
import std.stdio;
import std.functional;

void main() {
     auto div3 = (double x) => x/3.0;
     auto sq = (double x) => x*x;
     auto pls1 = (double x) => x+1.0;
     alias compose!(div3,sq,pls1) comp;
     writeln(comp(2.0)); // 3 == (2.0+1.0)^^2 / 3.0
     alias pipe!(div3,sq,pls1) pip;
     writeln(pip(2.0));  // 1.44444 == (2.0/3.0)^^2 + 1.0
}
--------------------------------------------

I get this error (with DMD64 D Compiler v2.071.1 in linux):

compose.d(8): Error: template instance compose!(div3, sq, pls1) 
compose is not a template declaration, it is a module

But the error disappears if I use this import:
    import std.functional:compose,pipe;

Is this a bug or is it the expected behaviour under the recent 
'import' changes?
Thanks!
Aug 25 2016
parent reply Meta <jared771 gmail.com> writes:
On Thursday, 25 August 2016 at 14:06:32 UTC, Antonio Corbi wrote:
 Hello,

 Trying to compile this example from Chuck Allison:
 -------------------------------------------
 import std.stdio;
 import std.functional;

 void main() {
     auto div3 = (double x) => x/3.0;
     auto sq = (double x) => x*x;
     auto pls1 = (double x) => x+1.0;
     alias compose!(div3,sq,pls1) comp;
     writeln(comp(2.0)); // 3 == (2.0+1.0)^^2 / 3.0
     alias pipe!(div3,sq,pls1) pip;
     writeln(pip(2.0));  // 1.44444 == (2.0/3.0)^^2 + 1.0
 }
 --------------------------------------------

 I get this error (with DMD64 D Compiler v2.071.1 in linux):

 compose.d(8): Error: template instance compose!(div3, sq, pls1) 
 compose is not a template declaration, it is a module

 But the error disappears if I use this import:
    import std.functional:compose,pipe;

 Is this a bug or is it the expected behaviour under the recent 
 'import' changes?
 Thanks!
Try renaming your source file to something other than compose.d, I think that's confusing the compiler.
Aug 25 2016
next sibling parent reply Jonathan M Davis via Digitalmars-d-learn writes:
On Thursday, August 25, 2016 14:30:00 Meta via Digitalmars-d-learn wrote:
 On Thursday, 25 August 2016 at 14:06:32 UTC, Antonio Corbi wrote:
 Hello,

 Trying to compile this example from Chuck Allison:
 -------------------------------------------
 import std.stdio;
 import std.functional;

 void main() {

     auto div3 = (double x) => x/3.0;
     auto sq = (double x) => x*x;
     auto pls1 = (double x) => x+1.0;
     alias compose!(div3,sq,pls1) comp;
     writeln(comp(2.0)); // 3 == (2.0+1.0)^^2 / 3.0
     alias pipe!(div3,sq,pls1) pip;
     writeln(pip(2.0));  // 1.44444 == (2.0/3.0)^^2 + 1.0

 }
 --------------------------------------------

 I get this error (with DMD64 D Compiler v2.071.1 in linux):

 compose.d(8): Error: template instance compose!(div3, sq, pls1)
 compose is not a template declaration, it is a module

 But the error disappears if I use this import:
    import std.functional:compose,pipe;

 Is this a bug or is it the expected behaviour under the recent
 'import' changes?
 Thanks!
Try renaming your source file to something other than compose.d, I think that's confusing the compiler.
Yes. Because the module is compose, within that file, compose will refer to the module, not anything you import. The selective import essentially creates a local alias like alias compose = std.functional.compose; as part of the import, so then within that scope, compose refers to that alias and not to the module. You'll run into the same problem any time that you give a module the same name as a symbol that you're importing. - Jonathan M Davis
Aug 25 2016
parent reply bachmeier <no spam.net> writes:
On Thursday, 25 August 2016 at 15:04:43 UTC, Jonathan M Davis 
wrote:

 Yes. Because the module is compose, within that file, compose 
 will refer to the module, not anything you import. The 
 selective import essentially creates a local alias like

 alias compose = std.functional.compose;

 as part of the import, so then within that scope, compose 
 refers to that alias and not to the module. You'll run into the 
 same problem any time that you give a module the same name as a 
 symbol that you're importing.

 - Jonathan M Davis
Is there a reason there is not a warning for this when compiling? I think it explains a problem I had some time ago that cost me a lot of time.
Aug 25 2016
parent reply bachmeier <no spam.net> writes:
On Thursday, 25 August 2016 at 17:49:26 UTC, bachmeier wrote:
 On Thursday, 25 August 2016 at 15:04:43 UTC, Jonathan M Davis 
 wrote:

 Yes. Because the module is compose, within that file, compose 
 will refer to the module, not anything you import. The 
 selective import essentially creates a local alias like

 alias compose = std.functional.compose;

 as part of the import, so then within that scope, compose 
 refers to that alias and not to the module. You'll run into 
 the same problem any time that you give a module the same name 
 as a symbol that you're importing.

 - Jonathan M Davis
Is there a reason there is not a warning for this when compiling? I think it explains a problem I had some time ago that cost me a lot of time.
I mean there should be a better message.
Aug 25 2016
parent Jonathan M Davis via Digitalmars-d-learn writes:
On Thursday, August 25, 2016 17:50:44 bachmeier via Digitalmars-d-learn wrote:
 On Thursday, 25 August 2016 at 17:49:26 UTC, bachmeier wrote:
 On Thursday, 25 August 2016 at 15:04:43 UTC, Jonathan M Davis

 wrote:
 Yes. Because the module is compose, within that file, compose
 will refer to the module, not anything you import. The
 selective import essentially creates a local alias like

 alias compose = std.functional.compose;

 as part of the import, so then within that scope, compose
 refers to that alias and not to the module. You'll run into
 the same problem any time that you give a module the same name
 as a symbol that you're importing.

 - Jonathan M Davis
Is there a reason there is not a warning for this when compiling? I think it explains a problem I had some time ago that cost me a lot of time.
I mean there should be a better message.
If you have a suggestion for a better message, then feel free to open a bug report for it - https://issues.dlang.org - or even create a pull request to fix it if you're feeling ambitious. But shadowing like this is a normal part of the module system. You'd get the same problem if your module was named something else, and you declared a function named compose in your module and then tried to use the compose from std.functional without fully qualifying it. It can certainly be annoying if you don't realize that that's what's happening, but how is the compiler going to know that what you meant to use the version of compose from another module rather than the one in the current module? All it knows is that you're using it wrong. - Jonathan M Davis
Aug 25 2016
prev sibling parent reply Antonio Corbi <amcb ggmail.com> writes:
On Thursday, 25 August 2016 at 14:30:00 UTC, Meta wrote:
 On Thursday, 25 August 2016 at 14:06:32 UTC, Antonio Corbi 
 wrote:
 Hello,

 Trying to compile this example from Chuck Allison:
 -------------------------------------------
 import std.stdio;
 import std.functional;

 void main() {
     auto div3 = (double x) => x/3.0;
     auto sq = (double x) => x*x;
     auto pls1 = (double x) => x+1.0;
     alias compose!(div3,sq,pls1) comp;
     writeln(comp(2.0)); // 3 == (2.0+1.0)^^2 / 3.0
     alias pipe!(div3,sq,pls1) pip;
     writeln(pip(2.0));  // 1.44444 == (2.0/3.0)^^2 + 1.0
 }
 --------------------------------------------

 I get this error (with DMD64 D Compiler v2.071.1 in linux):

 compose.d(8): Error: template instance compose!(div3, sq, 
 pls1) compose is not a template declaration, it is a module

 But the error disappears if I use this import:
    import std.functional:compose,pipe;

 Is this a bug or is it the expected behaviour under the recent 
 'import' changes?
 Thanks!
Try renaming your source file to something other than compose.d, I think that's confusing the compiler.
Yep, that did the trick! I also noticed that 'old' compilers like: - gdc: gdc (GCC) 6.1.1 20160501 - ldc: LDC - the LLVM D compiler (1.0.0): based on DMD v2.070.2 and LLVM 3.8.0 *do* compile the original code posted without error. Thank's to all of you for your answers.
Aug 25 2016
parent ZombineDev <petar.p.kirov gmail.com> writes:
On Thursday, 25 August 2016 at 21:01:29 UTC, Antonio Corbi wrote:
 On Thursday, 25 August 2016 at 14:30:00 UTC, Meta wrote:
 On Thursday, 25 August 2016 at 14:06:32 UTC, Antonio Corbi 
 wrote:
 Hello,

 Trying to compile this example from Chuck Allison:
 -------------------------------------------
 import std.stdio;
 import std.functional;

 void main() {
     auto div3 = (double x) => x/3.0;
     auto sq = (double x) => x*x;
     auto pls1 = (double x) => x+1.0;
     alias compose!(div3,sq,pls1) comp;
     writeln(comp(2.0)); // 3 == (2.0+1.0)^^2 / 3.0
     alias pipe!(div3,sq,pls1) pip;
     writeln(pip(2.0));  // 1.44444 == (2.0/3.0)^^2 + 1.0
 }
 --------------------------------------------

 I get this error (with DMD64 D Compiler v2.071.1 in linux):

 compose.d(8): Error: template instance compose!(div3, sq, 
 pls1) compose is not a template declaration, it is a module

 But the error disappears if I use this import:
    import std.functional:compose,pipe;

 Is this a bug or is it the expected behaviour under the 
 recent 'import' changes?
 Thanks!
Try renaming your source file to something other than compose.d, I think that's confusing the compiler.
Yep, that did the trick! I also noticed that 'old' compilers like: - gdc: gdc (GCC) 6.1.1 20160501 - ldc: LDC - the LLVM D compiler (1.0.0): based on DMD v2.070.2 and LLVM 3.8.0 *do* compile the original code posted without error. Thank's to all of you for your answers.
Since DMD 2.071 the compiler has become more strict about the use of imports. See the changelog for more info: http://dlang.org/changelog/2.071.0.html
Aug 28 2016