www.digitalmars.com         C & C++   DMDScript  

digitalmars.D.learn - About to!int

reply bearophile <bearophileHUGS lycos.com> writes:
In Python int() and float() convert a string into a number even if it contains
some whitespace before and after the number:


 s = " 12\n"
 int(s)



 float(s)



In D to!int(" 12\n") gives a run-time error. So time ago I have weakly asked Andrei to change to!int, to let it ignore leading and trailing whitespace, but he has ignored my request. A leading newline comes often from input stdin.readln() and other sources. So in D you need to add a strip(): int n = to!int(stdin.readln().strip()); I sometimes forget to add the strip(). Do you know why Andrei has not appreciated the idea of to!int and similar functions to ignore leading and trailing whitespace? Bye, bearophile
Jan 30 2012
next sibling parent reply Zardoz <luis.panadero gmail.com> writes:
On Mon, 30 Jan 2012 21:01:38 -0500, bearophile wrote:


 
 In D  to!int(" 12\n")  gives a run-time error. So time ago I have weakly
 asked Andrei to change to!int, to let it ignore leading and trailing
 whitespace, but he has ignored my request.
 
 A leading newline comes often from input stdin.readln() and other
 sources. So in D you need to add a strip():
 
 int n = to!int(stdin.readln().strip());
 
 Bye,
 bearophile

Try parse!int(" 12\n"); http://www.d-programming-language.org/phobos/std_conv.html#parse -- Yep, I'm afraid that I have a blog : zardoz.es
Jan 30 2012
parent bearophile <bearophileHUGS lycos.com> writes:
Zardoz:

 Try parse!int(" 12\n");
 http://www.d-programming-language.org/phobos/std_conv.html#parse

It doesn't work, because it accepts a ref string. So you have to write: string s = " 12\n"; int n = parse!int(s); But it doesn't work still, it chokes on the first space, so you have to remove it: string s = "12\n"; int n = parse!int(s); But it ignores leading noise: string s = "12x"; int n = parse!int(s); So it's completely broken for my purposes. Bye, bearophile
Jan 31 2012
prev sibling next sibling parent reply Jonathan M Davis <jmdavisProg gmx.com> writes:
On Monday, January 30, 2012 21:01:38 bearophile wrote:
 In Python int() and float() convert a string into a number even if it 

 s = " 12\n"
 int(s)



12
 float(s)



12.0 In D to!int(" 12\n") gives a run-time error. So time ago I have weakly asked Andrei to change to!int, to let it ignore leading and trailing whitespace, but he has ignored my request. A leading newline comes often from input stdin.readln() and other sources. So in D you need to add a strip(): int n = to!int(stdin.readln().strip()); I sometimes forget to add the strip(). Do you know why Andrei has not appreciated the idea of to!int and similar functions to ignore leading and trailing whitespace?

He's probably completely forgotten about it, and it's the sort of thing that he's likely to consider bikeshedding at this point - particularly since he's increasingly against making small changes like this. Also, the argument can easily be made that " 10 " is _not_ a number. It's a number surrounded by spaces. In general, std.conv.to does exact conversions, and to!int(" 10 ") is _not_ an exact conversion, since it includes characters which are not digits or a leading minus sign. std.conv.parse, on the other hand, deals with the spaces, because it's parsing the string rather than converting the whole thing. Also, if you _want_ to do an exact conversion, and std.conv.to removed the whitespace for you, then you couldn't use std.conv.to. You'd have to create your own. On the other hand, if you want to ignore whitespace in the conversion, you can easily wrap std.conv.to to do it. So, it's more composable as it is. There are obviously arguments for having std.conv.to ignore whitespace as well (you're making them), but at this point, I think that it's simply a matter of using parse rather than std.conv.to (or stripping the string first) if you want to ignore whitespace. I don't see std.conv.to changing. And as far Andrei, as I said, he's increasingly against making small changes like this. He wants substantial work done, not arguments over shifting around small stuff. - Jonathan M Davis
Jan 31 2012
parent bearophile <bearophileHUGS lycos.com> writes:
Jonathan M Davis:

 and it's the sort of thing that 
 he's likely to consider bikeshedding at this point -

He isn't the only Phobos developer. It's a change able to improve my usage of conversions, so it's not a neutral change (as I think 'bikeshedding' implies).
 particularly since he's 
 increasingly against making small changes like this.

This is quite bad, because many things in Phobos were designed in a very quick way, with essentially no usage feedback from a larger community of users, so several details are sub-optimal. The only way to not carry on for a lot of time such early mistakes is to accept to fix them.
 Also, the argument can easily be made that " 10 " is _not_ a number. It's a 
 number surrounded by spaces. In general, std.conv.to does exact conversions, 
 and to!int(" 10 ") is _not_ an exact conversion, since it includes characters 
 which are not digits or a leading minus sign.

I see. Walter doesn't like little functions in Phobos, so you can't just add a little function to Phobos that contains a strip followed a to!T.
 std.conv.parse, on the other 
 hand, deals with the spaces, because it's parsing the string rather than 
 converting the whole thing.

I have just answered to Zardoz why parse() is very bad for this purpose.
 Also, if you _want_ to do an exact conversion, and std.conv.to removed the 
 whitespace for you, then you couldn't use std.conv.to. You'd have to create 
 your own.

I see.
 On the other hand, if you want to ignore whitespace in the 
 conversion, you can easily wrap std.conv.to to do it.

Right. I will add a small function to my dlibs2 then. A small problem of doing it, is that my future snippets (even ones shown on newsgroups) tend to contain functions that aren't present in Phobos.
 So, it's more composable as it is.

This is true and it's an interesting point. From my experience composability is useful because it gives you more flexibility and offers you ways to do everything you want to do, but having "good defaults" (with functions that pack different functionality that is commonly needed together) leads to easy to write code. So when you design library functions you need to find a tradeoff between the two opposed desires. In Haskell (both its Prelude and in most of the libraries I've seen) they solve this problem giving both the elementary function and functions composed by only two or three functions, that Walter doesn't like such shallow functions in Phobos :-)
 I don't see std.conv.to changing.

We'll see. Thank you for your good answers, bye, bearophile
Jan 31 2012
prev sibling parent "Jonathan M Davis" <jmdavisProg gmx.com> writes:
On Tuesday, January 31, 2012 08:05:37 bearophile wrote:
 Jonathan M Davis:
 I don't see std.conv.to changing.

We'll see.

As far as I recall, you're the only person to ever bring this up (though you have brought it up before). In general, I think that programmers are fine with how to!int(str) works. - Jonathan M Davis
Jan 31 2012