www.digitalmars.com         C & C++   DMDScript  

digitalmars.D - How do you use templates in D?

reply Andrew Pennebaker <andrew.pennebaker gmail.com> writes:
I'm writing a function called genArray that accepts a function gen and
returns a random array populated by calling gen(). genString builds on this
by returning genArray(&genChar). But my type signatures are wrong.

In dashcheck.d:

char genChar() {
    return cast(char) uniform(0, 128);
}

T[] genArray(T function() gen) {
    int len = uniform(0, 100);
    T[] arr = [];

    for(int i = 0; i < len; i++) {
        arr ~= gen();
    }

    return arr;
}

string genString() {
    return genArray(&genChar);
}

Trace:

dashcheck.d(17): Error: undefined identifier T
dashcheck.d(17): Error: T is used as a type
dashcheck.d(17): Error: undefined identifier T
dashcheck.d(17): Error: T is used as a type

Full code at GitHub <https://github.com/mcandre/dashcheck>

Cheers,

Andrew Pennebaker
www.yellosoft.us
Oct 18 2011
next sibling parent Trass3r <un known.com> writes:
 T[] genArray(T function() gen) {
T[] genArray(T)(T function() gen) {
Oct 18 2011
prev sibling parent reply Ali =?iso-8859-1?q?=C7ehreli?= <acehreli yahoo.com> writes:
On Tue, 18 Oct 2011 13:56:09 -0400, Andrew Pennebaker wrote:

 I'm writing a function called genArray that accepts a function gen and
 returns a random array populated by calling gen(). genString builds on
 this by returning genArray(&genChar). But my type signatures are wrong.
 
 In dashcheck.d:
 
 char genChar() {
     return cast(char) uniform(0, 128);
It's a good thing that you are staying within ASCII. Otherwise there might be invalid UTF-8 sequences. :)
 T[] genArray(T function() gen) {
The template parameters are specified in a separate list before the function parameter list: T[] genArray(T)(T function() gen) { Now genArray is a function template with the template parameter T.
 string genString() {
     return genArray(&genChar);
Add .idup to convert from char[] to immutable(char)[] (i.e. string): return genArray(&genChar).idup; Or use std.exception.assumeUnique to communicate that the characters are not going to be mutated by somebody else: import std.exception; // ... auto result = genArray(&genChar); return assumeUnique(result); Ali P.S. There is also the digitalmars.D.learn newsgroup where this post would be appreciated at. ;)
Oct 18 2011
parent reply "Jonathan M Davis" <jmdavisProg gmx.com> writes:
On Tuesday, October 18, 2011 12:32 Ali Çehreli wrote:
 On Tue, 18 Oct 2011 13:56:09 -0400, Andrew Pennebaker wrote:
 I'm writing a function called genArray that accepts a function gen and
 returns a random array populated by calling gen(). genString builds on
 this by returning genArray(&genChar). But my type signatures are wrong.
 
 In dashcheck.d:
 
 char genChar() {
 
 return cast(char) uniform(0, 128);
It's a good thing that you are staying within ASCII. Otherwise there might be invalid UTF-8 sequences. :)
Yeah. It's generally a very bad sign when code uses char or wchar outside of arrays. They're UTF-8 and UTF-16 code units respectively and are not necessarily full code points (and therefore are not necessarily full characters). That's particularly true of char, since anything outside of ASCII is not going to work. Code which operates on individual characters really should be operating on dchars, not chars or wchars. - Jonathan M Davis
Oct 18 2011
parent reply Ali =?iso-8859-1?q?=C7ehreli?= <acehreli yahoo.com> writes:
On Tue, 18 Oct 2011 17:56:33 -0400, Jonathan M Davis wrote:

 On Tuesday, October 18, 2011 12:32 Ali Çehreli wrote:
 On Tue, 18 Oct 2011 13:56:09 -0400, Andrew Pennebaker wrote:
 I'm writing a function called genArray that accepts a function gen
 and returns a random array populated by calling gen(). genString
 builds on this by returning genArray(&genChar). But my type
 signatures are wrong.
 
 In dashcheck.d:
 
 char genChar() {
 
 return cast(char) uniform(0, 128);
It's a good thing that you are staying within ASCII. Otherwise there might be invalid UTF-8 sequences. :)
Yeah. It's generally a very bad sign when code uses char or wchar outside of arrays. They're UTF-8 and UTF-16 code units respectively and are not necessarily full code points (and therefore are not necessarily full characters). That's particularly true of char, since anything outside of ASCII is not going to work. Code which operates on individual characters really should be operating on dchars, not chars or wchars.
Good tips, but we can further qualify "Code which operates on individual characters". I think you imply accessing individual characters, likely with the [] operator. It is perfectly fine to use char and wchar strings as ranges when std.array is imported (it is automatically imported by std.range too): import std.stdio; import std.range; import std.array; // <-- empowers (en-ranges :p) char and wchar strings void main() { writeln(take("abcçdeé", 5)); } Outputs 5 Unicode characters, not code units. In other words, e.g. .front on any type of string produces a dchar; and that may very well prove your point. ;)
 - Jonathan M Davis
Ali
Oct 18 2011
parent "Jonathan M Davis" <jmdavisProg gmx.com> writes:
On Tuesday, October 18, 2011 15:37 Ali Çehreli wrote:
 On Tue, 18 Oct 2011 17:56:33 -0400, Jonathan M Davis wrote:
 On Tuesday, October 18, 2011 12:32 Ali Çehreli wrote:
 On Tue, 18 Oct 2011 13:56:09 -0400, Andrew Pennebaker wrote:
 I'm writing a function called genArray that accepts a function gen
 and returns a random array populated by calling gen(). genString
 builds on this by returning genArray(&genChar). But my type
 signatures are wrong.
 
 In dashcheck.d:
 
 char genChar() {
 
 return cast(char) uniform(0, 128);
It's a good thing that you are staying within ASCII. Otherwise there might be invalid UTF-8 sequences. :)
Yeah. It's generally a very bad sign when code uses char or wchar outside of arrays. They're UTF-8 and UTF-16 code units respectively and are not necessarily full code points (and therefore are not necessarily full characters). That's particularly true of char, since anything outside of ASCII is not going to work. Code which operates on individual characters really should be operating on dchars, not chars or wchars.
Good tips, but we can further qualify "Code which operates on individual characters". I think you imply accessing individual characters, likely with the [] operator. It is perfectly fine to use char and wchar strings as ranges when std.array is imported (it is automatically imported by std.range too): import std.stdio; import std.range; import std.array; // <-- empowers (en-ranges :p) char and wchar strings void main() { writeln(take("abcçdeé", 5)); } Outputs 5 Unicode characters, not code units. In other words, e.g. .front on any type of string produces a dchar; and that may very well prove your point. ;)
Yes. When treating arrays of char and wchar as ranges, you're effectively operating on dchars, so you're fine. The problem is when you have a variable which is char or wchar or when youyou access an individual char or wchar in an array. Operating on chars and wchars is fine as long as you decode them to dchar when you do it (as happens when using range operations such as front), but operating on individual chars or wchars is almost always a bug. - Jonathan M Davis
Oct 18 2011