Thread overview
calling function templates
Aug 09, 2009
Jos van Uden
Aug 09, 2009
bearophile
Aug 09, 2009
bearophile
Aug 09, 2009
Jos van Uden
Aug 09, 2009
bearophile
Aug 09, 2009
Bill Baxter
Aug 09, 2009
Daniel Keep
August 09, 2009
I noticed that I don't always have to use the bang notation for
function templates. I played around with that a little, but got
an error when I used a static array. I think it's because of a
casting problem or wrong type inference... I don't imagine it's
a bug. Just not possible.

module test;

import std.range;

void putNumbers(Range, T)(Range r, T start, T incr) {
    T i = start;
    while (!r.empty) {
        r.put(i);  // line 8
        i += incr;
    }
}

void main() {

    int[] arr = new int[20];
    putNumbers!(int[])(arr, 0, 3); // dyn array, bang notation

    int[] arr2 = new int[20];
    putNumbers(arr2, 0, 3); // dyn array, regular notation

    int[20] arr3;
    putNumbers!(int[])(arr3, 0, 3); // stat array, bang notation

    int[20] arr4;
    putNumbers(arr4, 0, 3); // ERROR, stat array, regular notation

}

test.d(8): Error: cast(int[])r is not an lvalue
test.d(25): Error: template instance test.putNumbers!(int[20u],int) error instantiating
August 09, 2009
Jos van Uden:

> I noticed that I don't always have to use the bang notation for function templates.

Generally function templates in D are able to infer their types by themselves, so generally you don't add the types with the !().


>I played around with that a little, but got an error when I used a static array.<

It may be a problems of ranges. D fixed-size arrays have some limitations/bugs, like you can't return them (but you can return one of them if you wrap it into a struct, weird).

Bye,
bearophile
August 09, 2009
And a more general note Jos van Uden: don't use D2, it's unfinished, things don't work yet. Use a stable version of D1, like 1.042.

Bye,
bearophile
August 09, 2009
bearophile wrote:
> And a more general note Jos van Uden: don't use D2, it's unfinished, things don't work yet. Use a stable version of D1, like 1.042.
> 
> Bye,
> bearophile

I'm not using the language. Just trying to learn it. Most code
examples I see, require D2.

Jos
August 09, 2009
Jos van Uden:
> I'm not using the language. Just trying to learn it.<

To learn a programming language you have to use it some.


>Most code examples I see, require D2.<

Then don't look at them, and do your own experiments, etc.

Bye,
bearophile
August 09, 2009
On Sun, Aug 9, 2009 at 9:30 AM, bearophile<bearophileHUGS@lycos.com> wrote:
> Jos van Uden:
>> I'm not using the language. Just trying to learn it.<
>
> To learn a programming language you have to use it some.
>
>
>>Most code examples I see, require D2.<
>
> Then don't look at them, and do your own experiments, etc.


Aw come on.  I'd learn D2 if I were just getting into D now.  It's
where all the action is heading these days.
If you don't like dealing with the bleeding edge, then yeh, D1 is
better for now.   But there are reasons why a person might prefer to
learn either.

--bb
August 09, 2009

Jos van Uden wrote:
> I noticed that I don't always have to use the bang notation for function templates. I played around with that a little, but got an error when I used a static array. I think it's because of a casting problem or wrong type inference... I don't imagine it's a bug. Just not possible.
> 
> ...
> 
>     int[20] arr4;
>     putNumbers(arr4, 0, 3); // ERROR, stat array, regular notation
> 
> }
> 
> test.d(8): Error: cast(int[])r is not an lvalue
> test.d(25): Error: template instance test.putNumbers!(int[20u],int)
> error instantiating

You're instantiating the template as putNumbers!(int[20u],int) because
arr4 is of type int[20u].

This means Range is int[20u].  Here's the code for put:

> void put(T, E)(ref T[] a, E e) {
>     assert(a.length);
>     a[0] = e; a = a[1 .. $];
> }

r.put(i) is rewritten by the compiler as put(r, i)... except that put
wants an int[], not an int[20u].  So it implicitly casts it to the
correct type, giving put(cast(int[])r, i).

But put ALSO expects its first argument to be passed by reference, and you cannot pass the result of a cast by-reference.

(There are a LOT of things you can't pass by reference; it's a constant thorn in my side, and many others' sides.)

The problem here is that put is fundamentally incompatible with fixed-size arrays.  The solution is to change line 25 to read:

auto arr4_temp = arr4[]; putNumbers(arr4_temp, 0, 3);