www.digitalmars.com         C & C++   DMDScript  

digitalmars.D - forward references... again?

reply Mehrdad <wfunction hotmail.com> writes:
Hm... why is this giving a forward reference error?

int main()
{
     auto a = normal(5);
     auto b = a + a;
     writeln(b.get(0.0));
}

struct OpBinary(string op, T...) if (T.length == 2)
{
     T values;

     this(T values) { this.values = values; }

     auto ref get(T2...)(T2 args)
     {
         static assert(T.length == 2);
         return (mixin(q{this.values[0]} ~ op ~ 
q{this.values[1]})).get(args);   // Why is calling get() considered a 
"forward reference"?
     }
}

struct Normal(T = real)
{
     T mean, stddev;

     this(T mean = 0, T stddev = 0) { this.mean = mean; this.stddev = 
stddev; }

     auto get(T2)(T2 value)
     {
         auto variance = this.stddev * this.stddev;
         auto offset = value - this.mean;
         return variance == 0.0 ? this.mean == value : 
.std.math.exp(-(offset * offset) / (2.0 * variance)) / 
.std.math.sqrt(2.0 * PI * variance);
     }

     OpBinary!(op, typeof(this), T2) opBinary(string op, T2)(T2 other) const
         if (op == "+" || op == "-" || op == "*" || op == "/")
     {
         return typeof(return)(this, other);
     }
}

auto normal(T)(T value) { real v = value; return Normal!(T)(v); }
Sep 26 2011
parent reply bearophile <bearophileHUGS lycos.com> writes:
Mehrdad Wrote:

 Hm... why is this giving a forward reference error?
In similar situations I suggest you to minimize your code, so both you ans us are able to better see the situation and the problem. Doing that you often don't need help. Bye, bearophile
Sep 26 2011
parent reply Mehrdad <wfunction hotmail.com> writes:
On 9/26/2011 9:36 AM, bearophile wrote:
 In similar situations I suggest you to minimize your code, so both you 
 ans us are able to better see the situation and the problem. Doing 
 that you often don't need help. Bye, bearophile 
Hope this is better: void main() { (Test() + Test()).get(0.0); } struct Sum(T1, T2) { T1 a; T2 b; auto ref get(T2...)(T2 args) { return (a + b).get(args); // Why is calling get() considered a "forward reference"? } } struct Test { auto ref get(T2...)(T2 value) { return 0; } Sum!(typeof(this), T2) opAdd(T2)(T2 other) const { return typeof(return)(this, other); } }
Sep 26 2011
parent reply "Jonathan M Davis" <jmdavisProg gmx.com> writes:
On Monday, September 26, 2011 10:13 Mehrdad wrote:
 On 9/26/2011 9:36 AM, bearophile wrote:
 In similar situations I suggest you to minimize your code, so both you
 ans us are able to better see the situation and the problem. Doing
 that you often don't need help. Bye, bearophile
Hope this is better: void main() { (Test() + Test()).get(0.0); } struct Sum(T1, T2) { T1 a; T2 b; auto ref get(T2...)(T2 args) { return (a + b).get(args); // Why is calling get() considered a "forward reference"? } } struct Test { auto ref get(T2...)(T2 value) { return 0; } Sum!(typeof(this), T2) opAdd(T2)(T2 other) const { return typeof(return)(this, other); } }
I'm not sure, but I would have expected that reusing T2 in th template of the get function would cause problems. At best, that T2 is shadowing the outer T2. You should be using a different name for get's template parameter. Maybe that has something to do with the problem, and the error message is just bad. - Jonathna m Davis
Sep 26 2011
parent reply Mehrdad <wfunction hotmail.com> writes:
On 9/26/2011 10:56 AM, Jonathan M Davis wrote:
 On Monday, September 26, 2011 10:13 Mehrdad wrote:
 On 9/26/2011 9:36 AM, bearophile wrote:
 In similar situations I suggest you to minimize your code, so both you
 ans us are able to better see the situation and the problem. Doing
 that you often don't need help. Bye, bearophile
Hope this is better: void main() { (Test() + Test()).get(0.0); } struct Sum(T1, T2) { T1 a; T2 b; auto ref get(T2...)(T2 args) { return (a + b).get(args); // Why is calling get() considered a "forward reference"? } } struct Test { auto ref get(T2...)(T2 value) { return 0; } Sum!(typeof(this), T2) opAdd(T2)(T2 other) const { return typeof(return)(this, other); } }
I'm not sure, but I would have expected that reusing T2 in th template of the get function would cause problems. At best, that T2 is shadowing the outer T2. You should be using a different name for get's template parameter. Maybe that has something to do with the problem, and the error message is just bad. - Jonathna m Davis
Nah, that's not the issue. Originally it was a different name, it just so happened that I didn't notice this in the simplification. However, I DID find the problem -- it's because the function is recursive. :( What I _meant_ to say was a.get(args) + b.get(args), but I said (a + b).get(args). So it was pretty much calling itself.
Sep 26 2011
parent reply "Regan Heath" <regan netmail.co.nz> writes:
On Mon, 26 Sep 2011 19:07:59 +0100, Mehrdad <wfunction hotmail.com> wrote:

 On 9/26/2011 10:56 AM, Jonathan M Davis wrote:
 On Monday, September 26, 2011 10:13 Mehrdad wrote:
 On 9/26/2011 9:36 AM, bearophile wrote:
 In similar situations I suggest you to minimize your code, so both you
 ans us are able to better see the situation and the problem. Doing
 that you often don't need help. Bye, bearophile
Hope this is better: void main() { (Test() + Test()).get(0.0); } struct Sum(T1, T2) { T1 a; T2 b; auto ref get(T2...)(T2 args) { return (a + b).get(args); // Why is calling get() considered a "forward reference"? } } struct Test { auto ref get(T2...)(T2 value) { return 0; } Sum!(typeof(this), T2) opAdd(T2)(T2 other) const { return typeof(return)(this, other); } }
I'm not sure, but I would have expected that reusing T2 in th template of the get function would cause problems. At best, that T2 is shadowing the outer T2. You should be using a different name for get's template parameter. Maybe that has something to do with the problem, and the error message is just bad. - Jonathna m Davis
Nah, that's not the issue. Originally it was a different name, it just so happened that I didn't notice this in the simplification. However, I DID find the problem -- it's because the function is recursive. :( What I _meant_ to say was a.get(args) + b.get(args), but I said (a + b).get(args). So it was pretty much calling itself.
So.. bug report for the bad error message then? -- Using Opera's revolutionary email client: http://www.opera.com/mail/
Sep 27 2011
parent reply Mehrdad <wfunction hotmail.com> writes:
On 9/27/2011 2:37 AM, Regan Heath wrote:
 On Mon, 26 Sep 2011 19:07:59 +0100, Mehrdad <wfunction hotmail.com> 
 wrote:

 Nah, that's not the issue. Originally it was a different name, it 
 just so happened that I didn't notice this in the simplification.

 However, I DID find the problem -- it's because the function is 
 recursive. :(
 What I _meant_ to say was a.get(args) + b.get(args), but I said (a + 
 b).get(args).  So it was pretty much calling itself.
So.. bug report for the bad error message then?
I... guess? But I'm not sure how to improve it. Something along the lines of "foo is currently being defined" might be clearer, but then again it's not like I didn't figure that out myself -- it's just that I thought it's for a different instantiation of the template.
Sep 27 2011
parent "Regan Heath" <regan netmail.co.nz> writes:
On Tue, 27 Sep 2011 11:05:12 +0100, Mehrdad <wfunction hotmail.com> wrote:

 On 9/27/2011 2:37 AM, Regan Heath wrote:
 On Mon, 26 Sep 2011 19:07:59 +0100, Mehrdad <wfunction hotmail.com>  
 wrote:

 Nah, that's not the issue. Originally it was a different name, it just  
 so happened that I didn't notice this in the simplification.

 However, I DID find the problem -- it's because the function is  
 recursive. :(
 What I _meant_ to say was a.get(args) + b.get(args), but I said (a +  
 b).get(args).  So it was pretty much calling itself.
So.. bug report for the bad error message then?
I... guess? But I'm not sure how to improve it. Something along the lines of "foo is currently being defined" might be clearer, but then again it's not like I didn't figure that out myself -- it's just that I thought it's for a different instantiation of the template.
Hmm.. I don't really know either, trying to untangle templates does my head in. Would it have helped if the error mentioned the "inferred return type" i.e. "Error: forward reference to inferred return type <file>.Sum!(Test,Test) of function call this.a.opAdd(this.b).get(_param_0)" the next error does mention the template it was instantiating, e.g. "Error: template instance <file>.Sum!(Test,Test).Sum.get!(double) error instantiating" so, provided you noticed that the inferred return type matched the template you would expect that to be the forward reference/problem.. -- Using Opera's revolutionary email client: http://www.opera.com/mail/
Sep 27 2011