digitalmars.D - How do you use templates in D?
- Andrew Pennebaker <andrew.pennebaker gmail.com> Oct 18 2011
- Trass3r <un known.com> Oct 18 2011
- Ali =?iso-8859-1?q?=C7ehreli?= <acehreli yahoo.com> Oct 18 2011
- "Jonathan M Davis" <jmdavisProg gmx.com> Oct 18 2011
- Ali =?iso-8859-1?q?=C7ehreli?= <acehreli yahoo.com> Oct 18 2011
- "Jonathan M Davis" <jmdavisProg gmx.com> Oct 18 2011
--bcaec51dd153631d7304af967111
Content-Type: text/plain; charset=ISO-8859-1
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
--bcaec51dd153631d7304af967111
Content-Type: text/html; charset=ISO-8859-1
Content-Transfer-Encoding: quoted-printable
<div>I'm writing a function called <font class=3D"Apple-style-span" fac=
e=3D"'courier new', monospace">genArray</font> that accepts a funct=
ion <font class=3D"Apple-style-span" face=3D"'courier new', monospa=
ce">gen</font> and returns a random array populated by calling <font class=
=3D"Apple-style-span" face=3D"'courier new', monospace">gen()</font=
. genString builds on this by returning <font class=3D"Apple-style-span" f=
my type signatures are wrong.</div>
<div><br></div><div>In dashcheck.d:</div><div><br></div><div><font class=3D=
"Apple-style-span" face=3D"'courier new', monospace">char genChar()=
{</font></div><div><font class=3D"Apple-style-span" face=3D"'courier n=
ew', monospace">=A0 =A0 return cast(char) uniform(0, 128);</font></div>
<div><font class=3D"Apple-style-span" face=3D"'courier new', monosp=
ace">}</font></div><div><font class=3D"Apple-style-span" face=3D"'couri=
er new', monospace"><br></font></div><div><font class=3D"Apple-style-sp=
an" face=3D"'courier new', monospace">T[] genArray(T function() gen=
) {</font></div>
<div><font class=3D"Apple-style-span" face=3D"'courier new', monosp=
ace">=A0 =A0 int len =3D uniform(0, 100);</font></div><div><font class=3D"A=
pple-style-span" face=3D"'courier new', monospace">=A0 =A0 T[] arr =
=3D [];</font></div>
<div><font class=3D"Apple-style-span" face=3D"'courier new', monosp=
ace"><br></font></div><div><font class=3D"Apple-style-span" face=3D"'co=
urier new', monospace">=A0 =A0 for(int i =3D 0; i < len; i++) {</fon=
t></div><div>
<font class=3D"Apple-style-span" face=3D"'courier new', monospace">=
=A0 =A0 =A0 =A0 arr ~=3D gen();</font></div><div><font class=3D"Apple-style=
-span" face=3D"'courier new', monospace">=A0 =A0 }</font></div><div=
<font class=3D"Apple-style-span" face=3D"'courier new', monospace"=
<br>
</font></div><div><font class=3D"Apple-style-span" face=3D"'courier new=
', monospace">=A0 =A0 return arr;</font></div><div><font class=3D"Apple=
-style-span" face=3D"'courier new', monospace">}</font></div><div><=
font class=3D"Apple-style-span" face=3D"'courier new', monospace"><=
br>
</font></div><div><font class=3D"Apple-style-span" face=3D"'courier new=
', monospace">string genString() {</font></div><div><font class=3D"Appl=
e-style-span" face=3D"'courier new', monospace">=A0 =A0 return genA=
rray(&genChar);</font></div>
<div><font class=3D"Apple-style-span" face=3D"'courier new', monosp=
ace">}</font></div><div><br></div><div>Trace:</div><div><br></div><div><fon=
t class=3D"Apple-style-span" face=3D"'courier new', monospace">dash=
check.d(17): Error: undefined identifier T</font></div>
<div><font class=3D"Apple-style-span" face=3D"'courier new', monosp=
ace">dashcheck.d(17): Error: T is used as a type</font></div><div><font cla=
ss=3D"Apple-style-span" face=3D"'courier new', monospace">dashcheck=
.d(17): Error: undefined identifier T</font></div>
<div><font class=3D"Apple-style-span" face=3D"'courier new', monosp=
ace">dashcheck.d(17): Error: T is used as a type</font></div><div><br></div=
<div>Full code at <a href=3D"https://github.com/mcandre/dashcheck">GitHub<=
<div><br></div>Cheers,<div><br></div><div>Andrew Pennebaker</div><div><a hr=
ef=3D"http://www.yellosoft.us" target=3D"_blank">www.yellosoft.us</a></div>
--bcaec51dd153631d7304af967111--
Oct 18 2011
T[] genArray(T function() gen) {
T[] genArray(T)(T function() gen) {
Oct 18 2011
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
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
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
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









Trass3r <un known.com> 