delegate object instead of a literal

Jonathan M Davis jmdavisProg at gmx.com
Sun Aug 14 03:33:40 PDT 2011


On Sunday, August 14, 2011 03:23:39 Jonathan M Davis wrote:
> On Sunday, August 14, 2011 20:50:03 Joel Christensen wrote:
> > Hi,
> > 
> > This program loops through a string until it finds a number and gives
> > the position of it.
> > 
> > The first assert works, but not the second one.
> > 
> > import std.algorithm;
> > 
> > void main() {
> > 
> > 	static bool isNumber( char input, char dummy ) {
> > 	
> > 		if ( ( input >= '0' && input <= '9' ) || input == '.' )
> > 		
> > 			return true;
> > 		
> > 		else
> > 		
> > 			return false;
> > 	
> > 	}
> > 	
> > 	string str = "abc123";
> > 	assert( countUntil!( ( input, b ) {
> > 	
> > 		if ( ( input >= '0' && input <= '9' ) || input == '.' ) return true;
> > 
> > else return false;
> > 
> > 		} )(str, 0) == 3 ); // works
> > 	
> > 	assert( countUntil!( isNumber, string, string )( str, 0 ) == 3 );
> > 
> > }
> > 
> > This is the error:
> > parse.d(15): Error: template instance
> > countUntil!(isNumber,string,string) does not match template declaration
> > countUntil(alias pred = "a == b",R1,R2) if
> > (is(typeof(startsWith!(pred)(haystack,needle))))
> 
> Okay. Several things here. One, don't ever declare an individual char. char
> is a UTF-8 code unit, not a code point. And characters are code points.
> ASCII characters only require one UTF-8 code unit, so they can be held in a
> single char, but that's not true of characters in general. When dealing
> with individual characters, always use dchar. So, if you're using foreach
> for a string, use dchar as the iteration type. e.g.
> 
> foreach(dchar c; str) {...}
> 
> Youre code will be wrong if it iterates over char or wchar, since those
> aren't full characters. And because of that, _all_ strings are ranges of
> dchar, not char or wchar. So, the fact that you're using string instead of
> dstring with a range-based function like countUntil is irrelevant. You're
> still dealing with a range of dchars. So, isNumber should definitely be
> taking dchars, not chars.
> 
> Two, don't pass 0 as a string. 0 is an int. _None_ of those countUntil calls
> shouldn't be compiling at all. It's actually a bit disturbing thath the
> first one compiles. It definitely looks like a bug. countUntil takes two
> ranges with the same element type. 0 is not a range, let alone a range of
> dchars. 0 shouldn't even really be used as a dchar, since 0 is an int, not
> a character.
> 
> Third, you really shouldn't be using if statements like that. It looks like
> you don't know what you're doing if you do
> 
> if(condition)
>     return true;
> else
>     return false;
> 
> The condition is already a bool. You can simply do
> 
>     return condition;
> 
> Plenty of newbie programmers make that mistake, and I don't know how
> experienced a programmer you are, but I'd advise you not to do that anymore.
> 
> In any case, I'm a bit shocked that the first call to countUntil compiles,
> let alone works. That's quite disturbing actually. It looks like countUntil
> has a bug. However, your usage of countUntil here does imply that it could
> use an overload which takes a unary function and only one range.

Oh and by the way, isNumber isn't a delegate. It's a function. A delegate has 
access to its outer scope, which is what you get when you don't use static.

- Jonathan M Davis


More information about the Digitalmars-d-learn mailing list