## digitalmars.D.learn - calling function templates

• Jos van Uden (27/27) Aug 09 2009 I noticed that I don't always have to use the bang notation for
• bearophile (5/8) Aug 09 2009 It may be a problems of ranges. D fixed-size arrays have some limitation...
• bearophile (3/3) Aug 09 2009 And a more general note Jos van Uden: don't use D2, it's unfinished, thi...
• Jos van Uden (4/8) Aug 09 2009 I'm not using the language. Just trying to learn it. Most code
• bearophile (5/7) Aug 09 2009 Then don't look at them, and do your own experiments, etc.
• Bill Baxter (7/12) Aug 09 2009 Aw come on. I'd learn D2 if I were just getting into D now. It's
• Daniel Keep (14/34) Aug 09 2009 You're instantiating the template as putNumbers!(int[20u],int) because
Jos van Uden <jvu nospam.nl> writes:
```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
```
Aug 09 2009
bearophile <bearophileHUGS lycos.com> writes:
```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
```
Aug 09 2009
bearophile <bearophileHUGS lycos.com> writes:
```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
```
Aug 09 2009
Jos van Uden <jvu nospam.nl> writes:
```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
```
Aug 09 2009
bearophile <bearophileHUGS lycos.com> writes:
```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
```
Aug 09 2009
Bill Baxter <wbaxter gmail.com> writes:
```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
```
Aug 09 2009
Daniel Keep <daniel.keep.lists gmail.com> writes:
```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);
```
Aug 09 2009