www.digitalmars.com         C & C++   DMDScript  

digitalmars.D.learn - How to avoid throwing an exceptions for a built-in function?

reply k-five <vhsu30 yahoo.com> writes:
I have a line of code that uses "to" function in std.conv for a 
purpose like:

int index = to!int( user_apply[ 4 ] ); // string to int

When the user_apply[ 4 ] has value, there is no problem; but when 
it is empty: ""
it throws an ConvException exception and I want to avoid this 
exception.

currently I have to use a dummy catch:
try{
     index = to!int( user_apply[ 4 ] );
} catch( ConvException conv_error ){
     // nothing
}

I no need to handle that, so is there any way to prevent this 
exception?
May 10
next sibling parent Nicholas Wilson <iamthewilsonator hotmail.com> writes:
On Wednesday, 10 May 2017 at 12:40:41 UTC, k-five wrote:
 I have a line of code that uses "to" function in std.conv for a 
 purpose like:

 int index = to!int( user_apply[ 4 ] ); // string to int

 When the user_apply[ 4 ] has value, there is no problem; but 
 when it is empty: ""
 it throws an ConvException exception and I want to avoid this 
 exception.

 currently I have to use a dummy catch:
 try{
     index = to!int( user_apply[ 4 ] );
 } catch( ConvException conv_error ){
     // nothing
 }

 I no need to handle that, so is there any way to prevent this 
 exception?
there has been talk of adding an overload that substitutes a supplied value on failure. apart from that there is assumeWontThrow in the stdlib somewhere.
May 10
prev sibling next sibling parent reply Ivan Kazmenko <gassa mail.ru> writes:
On Wednesday, 10 May 2017 at 12:40:41 UTC, k-five wrote:
 I have a line of code that uses "to" function in std.conv for a 
 purpose like:

 int index = to!int( user_apply[ 4 ] ); // string to int

 When the user_apply[ 4 ] has value, there is no problem; but 
 when it is empty: ""
 it throws an ConvException exception and I want to avoid this 
 exception.

 currently I have to use a dummy catch:
 try{
     index = to!int( user_apply[ 4 ] );
 } catch( ConvException conv_error ){
     // nothing
 }

 I no need to handle that, so is there any way to prevent this 
 exception?
I assume that an empty string is a valid input then. The question is, what value do you want `index` to have when the string is empty? Maybe the old value, or some constant? In any case, to better express your intent, you may write something like: if (user_apply[4] != "") { index = to !(int) (user_apply[4]); } else { index = ...; // specify whatever your intent is } This way, the code is self-documenting, and the program still throws when `user_apply[4]` is neither empty nor an integer, which may be the right thing to do in the long run. Ivan Kazmenko.
May 10
parent reply k-five <vhsu30 yahoo.com> writes:
On Wednesday, 10 May 2017 at 13:12:46 UTC, Ivan Kazmenko wrote:
 On Wednesday, 10 May 2017 at 12:40:41 UTC, k-five wrote:
----------------------------------------------------------
 I assume that an empty string is a valid input then.
 The question is, what value do you want `index` to have when 
 the string is empty?
 Maybe the old value, or some constant?
 In any case, to better express your intent, you may write 
 something like:

     if (user_apply[4] != "")
     {
         index = to !(int) (user_apply[4]);
     }
     else
     {
         index = ...;  // specify whatever your intent is
     }

 This way, the code is self-documenting, and the program still 
 throws when `user_apply[4]` is neither empty nor an integer, 
 which may be the right thing to do in the long run.

 Ivan Kazmenko.
---------------------------------------------------------- Thanks, but I know about what are you saying. The user_apply[4] has so many possibilities and I cannot use if-else
May 10
parent reply Stanislav Blinov <stanislav.blinov gmail.com> writes:
On Wednesday, 10 May 2017 at 13:27:17 UTC, k-five wrote:

 Thanks, but I know about what are you saying. The user_apply[4] 
 has so many possibilities and I cannot use if-else
That doesn't sound right. Either you've already handled all the possible cases and thus expect the to! to not throw (can specify that i.e. via std.exception.assumeWontThrow), or, as you're saying, it's much more than an if-else, but in that case exception will be thrown on invalid input.
May 10
parent reply k-five <vhsu30 yahoo.com> writes:
On Wednesday, 10 May 2017 at 14:27:46 UTC, Stanislav Blinov wrote:
 On Wednesday, 10 May 2017 at 13:27:17 UTC, k-five wrote:

 Thanks, but I know about what are you saying. The 
 user_apply[4] has so many possibilities and I cannot use 
 if-else
That doesn't sound right. Either you've already handled all the possible cases and thus expect the to! to not throw (can specify that i.e. via std.exception.assumeWontThrow), or, as you're saying, it's much more than an if-else, but in that case exception will be thrown on invalid input.
------------------------------------------------------------------ I know. But I am saying that I do not want to take care of any exceptions. I just wanted to write: int variable = to!int( string-type ); In fact something like using "no throw" is a function: void init( ... ) nothrow { ... int variable = to!int( string-type ); ... } but this is not valid. Thanks anyway and I will test: Function std.exception.assumeWontThrow at this link: https://dlang.org/library/std/exception/assume_wont_throw.html
May 10
parent reply Stanislav Blinov <stanislav.blinov gmail.com> writes:
On Wednesday, 10 May 2017 at 15:35:24 UTC, k-five wrote:
 On Wednesday, 10 May 2017 at 14:27:46 UTC, Stanislav Blinov 
 wrote:
 On Wednesday, 10 May 2017 at 13:27:17 UTC, k-five wrote:

 Thanks, but I know about what are you saying. The 
 user_apply[4] has so many possibilities and I cannot use 
 if-else
That doesn't sound right. Either you've already handled all the possible cases and thus expect the to! to not throw (can specify that i.e. via std.exception.assumeWontThrow), or, as you're saying, it's much more than an if-else, but in that case exception will be thrown on invalid input.
------------------------------------------------------------------ I know. But I am saying that I do not want to take care of any exceptions. I just wanted to write: int variable = to!int( string-type ); In fact something like using "no throw" is a function: void init( ... ) nothrow { ... int variable = to!int( string-type ); ... } but this is not valid. Thanks anyway and I will test: Function std.exception.assumeWontThrow at this link: https://dlang.org/library/std/exception/assume_wont_throw.html
I don't understand. If you don't want to take care of exceptions, then you just don't do anything, simply call to!int(str). If an exception is thrown, it'll propagate further up the stack, until you either handle it or abort the program. "nothrow" does not turn off exceptions, it simply forbids throwing them in the enclosing scope (i.e. calling anything that might throw is not allowed). Or do you mean that you've already made sure that the user input is valid such that to!int() will never throw with it? In that case, yes, assumeWontThrow is a way to express that. But then, the only way you can be sure of that is if you've already parsed the input yourself, so I'm not clear on the intent. Alternatively, if what you're calling still might throw but you don't want to deal with try/catch blocks, there's collectException function in std.exception that'll give you the exception if it was thrown and let you deal with it without using try/catch.
May 10
next sibling parent Moritz Maxeiner <moritz ucworks.org> writes:
On Wednesday, 10 May 2017 at 21:19:21 UTC, Stanislav Blinov wrote:
 "nothrow" does not turn off exceptions, it simply forbids 
 throwing them in the enclosing scope (i.e. calling anything 
 that might throw is not allowed).
nothrow disallows the function scope to throw exceptions not derived from core.object.Error. It makes no claim about what happens *inside* the scope; you can throw as much as you want inside nothrow, as long as you take care to catch anything that's not a core.object.Error (which is what std.exception.assumeWontThrow essentially does).
May 10
prev sibling parent reply k-five <vhsu30 yahoo.com> writes:
On Wednesday, 10 May 2017 at 21:19:21 UTC, Stanislav Blinov wrote:
 On Wednesday, 10 May 2017 at 15:35:24 UTC, k-five wrote:
 On Wednesday, 10 May 2017 at 14:27:46 UTC, Stanislav Blinov
---------------------------------------------------------------
 I don't understand. If you don't want to take care of 
 exceptions, then you just don't do anything, simply call 
 to!int(str).
Well I did that, but when the string is a valid type like: "10" there is no problems. But when the string is not valid, like: "abc", then to! function throws an exception. Why I do not want to take care of that? Because I just need the value, if the string is valid, otherwise no matter what the value of string is. First I just wrote: index = to!int( user_apply[ 4 ] ); And this code is a part of a command-line program and the user may enter anything. So, for a valid string: ./program '10' // okey but for: ./program 'non-numerical' // throws an exception an 10 lines of error appear on the screen( console ) I just want to silent this exception. Of course it is useful for handling when someone wants to. But in my code I no need to handle it. So I want to silent that, without using try{}catch(){} block. I just wondered about try-catch and I want to know may there would be a better way instead of a dummy try-catch block. Thanks for replying and mentioning. And I am sorry, since I an new in English Writing, if you got confuse.
May 11
parent reply Mike B Johnson <Mikey Ikes.com> writes:
On Thursday, 11 May 2017 at 16:07:22 UTC, k-five wrote:
 On Wednesday, 10 May 2017 at 21:19:21 UTC, Stanislav Blinov 
 wrote:
 On Wednesday, 10 May 2017 at 15:35:24 UTC, k-five wrote:
 On Wednesday, 10 May 2017 at 14:27:46 UTC, Stanislav Blinov
---------------------------------------------------------------
 I don't understand. If you don't want to take care of 
 exceptions, then you just don't do anything, simply call 
 to!int(str).
Well I did that, but when the string is a valid type like: "10" there is no problems. But when the string is not valid, like: "abc", then to! function throws an exception. Why I do not want to take care of that? Because I just need the value, if the string is valid, otherwise no matter what the value of string is. First I just wrote: index = to!int( user_apply[ 4 ] ); And this code is a part of a command-line program and the user may enter anything. So, for a valid string: ./program '10' // okey but for: ./program 'non-numerical' // throws an exception an 10 lines of error appear on the screen( console ) I just want to silent this exception. Of course it is useful for handling when someone wants to. But in my code I no need to handle it. So I want to silent that, without using try{}catch(){} block. I just wondered about try-catch and I want to know may there would be a better way instead of a dummy try-catch block. Thanks for replying and mentioning. And I am sorry, since I an new in English Writing, if you got confuse.
You are not making a lot of sense: 1. Exception do bubble up, so you don't need to "handle" exceptions at the call site if you don't want to. The whole point of exceptions is do effectively do what you want. 2. You say that you don't have to deal with it in your code but you are trying to deal with it now. You are not clear on exactly what you are trying to accomplish. Can you be more specific on why you do not want to add a try/catch/if-else/ifThrown/etc? Is it because you don't need to handle it in your own usage? If that is true, will others ever use it? Basically all you have to do is ask yourself this: "Do I need to EVER handle the case where the data is invalid?" If you do(e.g., other users will use your code) then you better implement some type of exception handling. Else all you have to do is always put in the right data(not good because it might bite you in the ass one day). If you just want less noise when the program crashes, just put a try/catch block in main and catch all generic exceptions and exit with a simple error message like "There was an ERROR, I do not know why...".
May 12
parent reply k-five <vhsu30 yahoo.com> writes:
On Saturday, 13 May 2017 at 02:40:17 UTC, Mike B Johnson wrote:
 You are not making a lot of sense:

 1. Exception do bubble up, so you don't need to "handle" 
 exceptions at the call site if you don't want to. The whole 
 point of exceptions is do effectively do what you want.

 2. You say that you don't have to deal with it in your code but 
 you are trying to deal with it now.


 You are not clear on exactly what you are trying to accomplish.

 Can you be more specific on why you do not want to add a 
 try/catch/if-else/ifThrown/etc? Is it because you don't need to 
 handle it in your own usage? If that is true, will others ever 
 use it?

 Basically all you have to do is ask yourself this:

 "Do I need to EVER handle the case where the data is invalid?"

 If you do(e.g., other users will use your code) then you better 
 implement some type of exception handling. Else all you have to 
 do is always put in the right data(not good because it might 
 bite you in the ass one day).

 If you just want less noise when the program crashes, just put 
 a try/catch block in main and catch all generic exceptions and 
 exit with a simple error message like "There was an ERROR, I do 
 not know why...".
---------------------------------------------------------------- Way arguing when a simple code can clarify the subject? right? If am not clear so consider me as an stupid man, no problem at all. but CAN you please solve it for me? import std.stdio: writeln; import std.conv: to; void main( string[] args ){ string str = "10"; int index; index = to!int( str ); // okay, no exception are thrown str = "some-words"; index = to!int( str ); // problem, an exception is thrown } Please run this code and convert "some-words" to int by using to! function without facing any exception. Thanks
May 13
parent Stanislav Blinov <stanislav.blinov gmail.com> writes:
On Saturday, 13 May 2017 at 08:50:20 UTC, k-five wrote:

 Way arguing when a simple code can clarify the subject? right?
 If am not clear so consider me as an stupid man, no problem at 
 all.

 but CAN you please solve it for me?

 import std.stdio:	writeln;
 import std.conv:	to;

 void main( string[] args ){
 	
 	string str = "10";
 	int index;
 	index = to!int( str );	// okay, no exception are thrown
 	
 	str = "some-words";
 	index = to!int( str ); // problem, an exception is thrown
 	
 }

 Please run this code and convert "some-words" to int by using 
 to! function without facing any exception. Thanks
Please don't take it the wrong way. It just seems that Mike was as confused by your questions as I was initially. But it's clear that's just the language barrier, nothing more. See, you said:
 Why I do not want to take care of that? Because I just need the 
 value, if the string is valid, otherwise no matter what the 
 value of string is.
...but it doesn't make sense to have an int "value" for a string like "some-words". *Unless* one defines a "not-a-number" equivalent for an int, i.e. 0 or some other value. That part was hard to infer from what you were saying :) It might've been obvious for you, but hard to understand from what you wrote. This was what made things clear:
 I just want to silent this exception...
Mostly, the source of the confusion was the "I don't want to handle the exception". But in fact what you were asking was was there a way to somehow ignore the exception and just return some predefined value in case of an error. So in fact, you did want to handle the exception (or rather, an exceptional case), you just wanted to do it without inserting control flow instructions (try/catch) into your code. I think the latter part already got covered in others' replies. Nobody was trying to insult you. With this being a multi-lingual and multi-cultural community, remember that understanding goes both ways, and we're sometimes caught right in the middle, in the clash of mentalities.
May 13
prev sibling next sibling parent reply Andrei Alexandrescu <SeeWebsiteForEmail erdani.org> writes:
On 5/10/17 3:40 PM, k-five wrote:
 I have a line of code that uses "to" function in std.conv for a purpose 
 like:
 
 int index = to!int( user_apply[ 4 ] ); // string to int
 
 When the user_apply[ 4 ] has value, there is no problem; but when it is 
 empty: ""
 it throws an ConvException exception and I want to avoid this exception.
 
 currently I have to use a dummy catch:
 try{
      index = to!int( user_apply[ 4 ] );
 } catch( ConvException conv_error ){
      // nothing
 }
 
 I no need to handle that, so is there any way to prevent this exception?
Use the "parse" family: https://dlang.org/phobos/std_conv.html#parse -- Andrei
May 10
parent k-five <vhsu30 yahoo.com> writes:
On Wednesday, 10 May 2017 at 21:44:32 UTC, Andrei Alexandrescu 
wrote:
 On 5/10/17 3:40 PM, k-five wrote:
-----------------------------------
 I no need to handle that, so is there any way to prevent this 
 exception?
Use the "parse" family: https://dlang.org/phobos/std_conv.html#parse -- Andrei
----------------------------------- This is my answer :). I want a way to covert a string without facing any exceptions. But may I do not understand so well the documentation It says: The parse family of functions works quite like the to family, except that: 1 - It only works with character ranges as input. 2 - It takes the input by reference. (This means that rvalues - such as string literals - are not accepted: use to instead.) 3 - It advances the input to the position following the conversion. 4 - It does not throw if it could not convert the entire input. here, number 4: It does not throw if it could not convert the entire input. then it says: Throws: A ConvException if the range does not represent a bool. Well it says different things about throwing! Also I tested this: import std.stdio; import std.conv: parse; void main( string[] args ){ string str = "string"; int index = parse!int( str ); writeln( "index: ", index ); } the output: std.conv.ConvException /usr/include/dmd/phobos/std/conv.d(2111): Unexpected 's' when converting from type string to type int and so on ... Please correct me if I am wrong.
May 11
prev sibling next sibling parent =?UTF-8?Q?Ali_=c3=87ehreli?= <acehreli yahoo.com> writes:
On 05/10/2017 05:40 AM, k-five wrote:
 I have a line of code that uses "to" function in std.conv for a purpose
 like:

 int index = to!int( user_apply[ 4 ] ); // string to int

 When the user_apply[ 4 ] has value, there is no problem; but when it is
 empty: ""
 it throws an ConvException exception and I want to avoid this exception.

 currently I have to use a dummy catch:
 try{
     index = to!int( user_apply[ 4 ] );
 } catch( ConvException conv_error ){
     // nothing
 }
Are you really fine with 'index' being left with its previous value? If so, you can write a function like the following: void setMaybe(To, From)(ref To var, From from) { import std.conv : to, ConvException; try { var = to!To(from); } catch( ConvException conv_error ) { } } unittest { int index = 41; index.setMaybe("42"); assert(index == 42); index.setMaybe("forty three"); assert(index == 42); index.setMaybe(""); assert(index == 42); } void main() { } If you want the variable to be set to a default value (perhaps .init), then here is an idea: void setMaybe(To, From)(ref To var, From from, To def = To.init) { import std.conv : to, ConvException; try { var = to!To(from); } catch( ConvException conv_error ) { var = def; } } unittest { int index = 41; index.setMaybe("42"); assert(index == 42); index.setMaybe("forty three"); assert(index == 0); index.setMaybe(7); index.setMaybe("", 8); assert(index == 8); } void main() { } Ali
May 10
prev sibling parent reply crimaniak <crimaniak gmail.com> writes:
On Wednesday, 10 May 2017 at 12:40:41 UTC, k-five wrote:
 I have a line of code that uses "to" function in std.conv for a 
 purpose like:

 int index = to!int( user_apply[ 4 ] ); // string to int

 When the user_apply[ 4 ] has value, there is no problem; but 
 when it is empty: ""
 it throws an ConvException exception and I want to avoid this 
 exception.

 currently I have to use a dummy catch:
 try{
     index = to!int( user_apply[ 4 ] );
 } catch( ConvException conv_error ){
     // nothing
 }

 I no need to handle that, so is there any way to prevent this 
 exception?
try this: https://dlang.org/phobos/std_exception.html#ifThrown
May 11
parent reply k-five <vhsu30 yahoo.com> writes:
On Thursday, 11 May 2017 at 17:18:37 UTC, crimaniak wrote:
 On Wednesday, 10 May 2017 at 12:40:41 UTC, k-five wrote:
---------------------------------------------------------
 try this:
 https://dlang.org/phobos/std_exception.html#ifThrown
Worked. Thanks. import std.stdio; import std.conv: to; import std.exception: ifThrown; void main( string[] args ){ string str = "string"; int index = to!int( str ).ifThrown( 0 ); // if an exception was thrown, it is ignored and then return ( 0 ); writeln( "index: ", index ); // 0 }
May 11
parent reply "H. S. Teoh via Digitalmars-d-learn" <digitalmars-d-learn puremagic.com> writes:
On Thu, May 11, 2017 at 05:55:03PM +0000, k-five via Digitalmars-d-learn wrote:
 On Thursday, 11 May 2017 at 17:18:37 UTC, crimaniak wrote:
 On Wednesday, 10 May 2017 at 12:40:41 UTC, k-five wrote:
---------------------------------------------------------
 try this:
 https://dlang.org/phobos/std_exception.html#ifThrown
Worked. Thanks. import std.stdio; import std.conv: to; import std.exception: ifThrown; void main( string[] args ){ string str = "string"; int index = to!int( str ).ifThrown( 0 ); // if an exception was thrown, it is ignored and then return ( 0 ); writeln( "index: ", index ); // 0 }
Keep in mind, though, that you should not do this in an inner loop if you care about performance, as throwing / catching exceptions will incur a performance hit. Outside of inner loops, though, it probably doesn't matter. T -- Ph.D. = Permanent head Damage
May 11
parent reply Jordan Wilson <wilsonjord gmail.com> writes:
On Thursday, 11 May 2017 at 18:07:47 UTC, H. S. Teoh wrote:
 On Thu, May 11, 2017 at 05:55:03PM +0000, k-five via 
 Digitalmars-d-learn wrote:
 On Thursday, 11 May 2017 at 17:18:37 UTC, crimaniak wrote:
 On Wednesday, 10 May 2017 at 12:40:41 UTC, k-five wrote:
---------------------------------------------------------
 try this: 
 https://dlang.org/phobos/std_exception.html#ifThrown
Worked. Thanks. import std.stdio; import std.conv: to; import std.exception: ifThrown; void main( string[] args ){ string str = "string"; int index = to!int( str ).ifThrown( 0 ); // if an exception was thrown, it is ignored and then return ( 0 ); writeln( "index: ", index ); // 0 }
Keep in mind, though, that you should not do this in an inner loop if you care about performance, as throwing / catching exceptions will incur a performance hit. Outside of inner loops, though, it probably doesn't matter. T
This reason is why I sometimes use isNumeric if I have heaps of strings I need to convert, to reduce exceptions. So something like: int index = (str.isNumeric) ? to!int(str).ifThrown(0) : 0; Jordan
May 11
parent reply k-five <vhsu30 yahoo.com> writes:
On Thursday, 11 May 2017 at 19:59:55 UTC, Jordan Wilson wrote:
 On Thursday, 11 May 2017 at 18:07:47 UTC, H. S. Teoh wrote:
 On Thu, May 11, 2017 at 05:55:03PM +0000, k-five via 
 Digitalmars-d-learn wrote:
 On Thursday, 11 May 2017 at 17:18:37 UTC, crimaniak wrote:
 On Wednesday, 10 May 2017 at 12:40:41 UTC, k-five wrote:
---------------------------------------------------------
This reason is why I sometimes use isNumeric if I have heaps of strings I need to convert, to reduce exceptions. So something like: int index = (str.isNumeric) ? to!int(str).ifThrown(0) : 0; Jordan
-------------------------------------------------------------- Interesting! I was worried about performance and for that I did not want to use try-catch. So (isNumberic) is a good solution. http://dlang.org/phobos/std_traits.html#isNumeric
May 12
next sibling parent k-five <vhsu30 yahoo.com> writes:
On Friday, 12 May 2017 at 08:32:03 UTC, k-five wrote:
 On Thursday, 11 May 2017 at 19:59:55 UTC, Jordan Wilson wrote:
 On Thursday, 11 May 2017 at 18:07:47 UTC, H. S. Teoh wrote:
 On Thu, May 11, 2017 at 05:55:03PM +0000, k-five via 
 Digitalmars-d-learn wrote:
 On Thursday, 11 May 2017 at 17:18:37 UTC, crimaniak wrote:
 On Wednesday, 10 May 2017 at 12:40:41 UTC, k-five wrote:
---------------------------------------------------------
This reason is why I sometimes use isNumeric if I have heaps of strings I need to convert, to reduce exceptions. So something like: int index = (str.isNumeric) ? to!int(str).ifThrown(0) : 0; Jordan
-------------------------------------------------------------- Interesting! I was worried about performance and for that I did not want to use try-catch. So (isNumberic) is a good solution. http://dlang.org/phobos/std_traits.html#isNumeric
---------------------------------------------------------------- NOT a GOOD solution! Since it accept type and NOT variable: so: index = (str.isNumeric) ? to!int(str).ifThrown(0) : 0; is: temp.d(11): Error: template std.traits.isNumeric cannot deduce function from argument types !()(string), candidates are:
May 12
prev sibling next sibling parent reply Jonathan M Davis via Digitalmars-d-learn writes:
On Friday, May 12, 2017 08:32:03 k-five via Digitalmars-d-learn wrote:
 On Thursday, 11 May 2017 at 19:59:55 UTC, Jordan Wilson wrote:
 On Thursday, 11 May 2017 at 18:07:47 UTC, H. S. Teoh wrote:
 On Thu, May 11, 2017 at 05:55:03PM +0000, k-five via

 Digitalmars-d-learn wrote:
 On Thursday, 11 May 2017 at 17:18:37 UTC, crimaniak wrote:
 On Wednesday, 10 May 2017 at 12:40:41 UTC, k-five wrote:
---------------------------------------------------------
This reason is why I sometimes use isNumeric if I have heaps of strings I need to convert, to reduce exceptions. So something like: int index = (str.isNumeric) ? to!int(str).ifThrown(0) : 0; Jordan
-------------------------------------------------------------- Interesting! I was worried about performance and for that I did not want to use try-catch. So (isNumberic) is a good solution. http://dlang.org/phobos/std_traits.html#isNumeric
That's the wrong isNumeric. Unfortunately, both std.string and std.traits have an isNumeric. std.traits.isNumeric is an eponymous template that tests whether a type is an integral or floating point type, whereas std.string.isNumeric is a templated function which tests whether a string (or other range of characters) represents an integer or floating point literal. So, std.traits.isNumeric won't work at all for what you want, and std.string.isNumeric will sort of do what you want - the main caveat being that it will also accept floating point values, whereas to!int will not. So, if you have auto i = str.isNumeric ? to!int(str).ifThrown(0) : 0; then it will work but will still throw (and then be caught by ifThrown) if str is a floating point value. Alternatively, you could check something like auto i = str.all!isDigit ? to!int(str).ifThrown(0) : 0; (where all is in std.algorithm and isDigit is in std.ascii), and that _almost_ wouldn't need ifThrown, letting you do auto i = str.all!isDigit ? to!int(str) : 0; except that str could be an integral value that wouldn't fit in an int, in which case to!int would throw. But std.string.isNumeric will work so long as you're willing to have have an exception be thrown and caught if the string is a floating point literal. - Jonathan M Davis
May 12
parent k-five <vhsu30 yahoo.com> writes:
On Friday, 12 May 2017 at 09:03:39 UTC, Jonathan M Davis wrote:
 That's the wrong isNumeric. Unfortunately, both std.string and 
 std.traits have an isNumeric. std.traits.isNumeric is an 
 eponymous template that tests whether a type is an integral or 
 floating point type, whereas std.string.isNumeric is a 
 templated function which tests whether a string (or other range 
 of characters) represents an integer or floating point literal. 
 So, std.traits.isNumeric won't work at all for what you want, 
 and std.string.isNumeric will sort of do what you want - the 
 main caveat being that it will also accept floating point 
 values, whereas to!int will not.

 So, if you have

 auto i = str.isNumeric ? to!int(str).ifThrown(0) : 0;

 then it will work but will still throw (and then be caught by 
 ifThrown) if str is a floating point value. Alternatively, you 
 could check something like

 auto i = str.all!isDigit ? to!int(str).ifThrown(0) : 0;

 (where all is in std.algorithm and isDigit is in std.ascii), 
 and that _almost_ wouldn't need ifThrown, letting you do

 auto i = str.all!isDigit ? to!int(str) : 0;

 except that str could be an integral value that wouldn't fit in 
 an int, in which case to!int would throw. But 
 std.string.isNumeric will work so long as you're willing to 
 have have an exception be thrown and caught if the string is a 
 floating point literal.

 - Jonathan M Davis
----------------------------------------------------------------- Thank you for mentioning it. Since I had seen D-conference 2016 in YouTube and it talked about isNumeric in std.traits, then I used std.traits. and does not worked as I wanted. But std.string: isNumeric, worked. string str = "string"; int index = str.isNumeric ? to!int( str ) : 0; writeln( "index: ", index ); // 0 and without throwing any exceptions
May 12
prev sibling parent reply ag0aep6g <anonymous example.com> writes:
On 05/12/2017 10:32 AM, k-five wrote:
 Interesting! I was worried about performance and for that I did not want
 to use try-catch.
 So (isNumberic) is a good solution.
 http://dlang.org/phobos/std_traits.html#isNumeric
If you're doing this for speed, you better be benchmarking. Exceptions are slow when they're thrown. But if no exception is being thrown, try-catch is probably faster than checking isNumeric beforehand.
May 12
next sibling parent "H. S. Teoh via Digitalmars-d-learn" <digitalmars-d-learn puremagic.com> writes:
On Fri, May 12, 2017 at 12:47:04PM +0200, ag0aep6g via Digitalmars-d-learn
wrote:
 On 05/12/2017 10:32 AM, k-five wrote:
 Interesting! I was worried about performance and for that I did not
 want to use try-catch.
 So (isNumberic) is a good solution.
 http://dlang.org/phobos/std_traits.html#isNumeric
If you're doing this for speed, you better be benchmarking. Exceptions are slow when they're thrown. But if no exception is being thrown, try-catch is probably faster than checking isNumeric beforehand.
Yes, when it comes to performance-related issues, always profile, profile, profile. (Or benchmark, benchmark, benchmark. Anything that gives you actual measurements rather than subjective judgment calls.) Far too often, what we think will perform poorly is actually nowhere near the real bottleneck in the program, and we end up wasting too much time "optimizing" something that doesn't even make a noticeable difference in the end. Whereas, using a profiler early on will help you zero in on the real bottlenecks, and you could potentially make huge performance savings with much less effort. T -- Beware of bugs in the above code; I have only proved it correct, not tried it. -- Donald Knuth
May 12
prev sibling parent reply Jonathan M Davis via Digitalmars-d-learn writes:
On Friday, May 12, 2017 10:42:18 H. S. Teoh via Digitalmars-d-learn wrote:
 On Fri, May 12, 2017 at 12:47:04PM +0200, ag0aep6g via Digitalmars-d-learn 
wrote:
 On 05/12/2017 10:32 AM, k-five wrote:
 Interesting! I was worried about performance and for that I did not
 want to use try-catch.
 So (isNumberic) is a good solution.
 http://dlang.org/phobos/std_traits.html#isNumeric
If you're doing this for speed, you better be benchmarking. Exceptions are slow when they're thrown. But if no exception is being thrown, try-catch is probably faster than checking isNumeric beforehand.
Yes, when it comes to performance-related issues, always profile, profile, profile. (Or benchmark, benchmark, benchmark. Anything that gives you actual measurements rather than subjective judgment calls.) Far too often, what we think will perform poorly is actually nowhere near the real bottleneck in the program, and we end up wasting too much time "optimizing" something that doesn't even make a noticeable difference in the end. Whereas, using a profiler early on will help you zero in on the real bottlenecks, and you could potentially make huge performance savings with much less effort.
For the most part, when parsing a string, std.conv.to's approach of just parsing the string and throwing an exception if/when it fails is the most efficient, because it's only going to parse the string once, whereas calling a function to validate the string's format and _then_ do the conversion would mean parsing the string twice. It's just that if you are in a situation where the string is likely not to be in the correct format, then having a bunch of exceptions thrown will harm performance. To best handle that, we'd need an alternate conversion function that did something like return the failure condition and passed the result via an out parameter or one which took a default value and returned that on failure instead of what was actaully parsed. So, ideally, we'd have other functions in std.conv to handle such cases, but in the vast majority of cases, throwing an exception on failure is going to be the most efficient solution. But obviously, to know what's actually happening with your code, you're going to have to profile and benchmark it - especially if you're throwing exceptions on a regular basis but not super frequently, because then it's quickly an open question as to whether parsing twice to avoid the exception or letting the exception be thrown and caught would be faster. Odds are though that unless you're converting in a tight loop, the relative costs won't matter much, even if one is clearly more expensive than the other, simply because it's not a bottleneck in your program. But you won't know that for sure unless you profile. However, unless you're parsing a lot of invalid strings, I'd be very surprised if always parsing twice were more efficient than parsing only once and throwing an exception on failure. And D exceptions are fairly efficient at this point if you don't call toString, because we stripped out most of the string processing that they were doing up front before. It used to be pretty painful when you did a lot of tests that tested the error cases, because the exceptions really increased the time that the tests took, but that's no longer the case (IIRC, the improvements literally saved seconds of execution time in std.datetime's unit tests). - Jonathan M Davis
May 13
parent reply k-five <vhsu30 yahoo.com> writes:
On Saturday, 13 May 2017 at 09:05:17 UTC, Jonathan M Davis wrote:

 For the most part, when parsing a string, std.conv.to's 
 approach of just parsing the string and throwing an exception 
 if/when it fails is the most efficient, because it's only going 
 to parse the string once, whereas calling a function to 
 validate the string's format and _then_ do the conversion would 
 mean parsing the string twice.It's just that if you are in a 
 situation where the string is likely not to be in the correct 
 format, then having a bunch of exceptions thrown will harm 
 performance. To best handle that, we'd need an alternate 
 conversion function that did something like return the failure 
 condition and passed the result via an out parameter or one 
 which took a default value and returned that on failure instead 
 of what was actaully parsed. So, ideally, we'd have other 
 functions in std.conv to handle such cases, but in the vast 
 majority of cases, throwing an exception on failure is going to 
 be the most efficient solution.
I did not know this.
 But obviously, to know what's actually happening with your 
 code, you're going to have to profile and benchmark it -
Can you please give a link or page or something to read about profile or benchmark. I have no experience with those. ------------------------------------------------------------------- For a such purpose I already used std::stringstream in C++, and I assumed may or may not D has a such family. ( to!, parse!, ... ) Not only an invalid string like "word" for to!int, makes it being thrown, but an empty string like: "" also makes it. string str = "word"; int index = to!int( str ); // throws str = ""; int index = to!int( str ); // throws, as well! Of course throwing is useful some times, but definitely not ALWAYS, and it is better to have a convert function that never throws anything. Although [Andrei Alexandrescu] told me that the parse! family is used for such a case:
 Use the "parse" family: 
 https://dlang.org/phobos/std_conv.html#parse -- Andrei
but it throws as well.
May 13
parent Bastiaan Veelo <Bastiaan Veelo.net> writes:
On Saturday, 13 May 2017 at 09:51:40 UTC, k-five wrote:
 On Saturday, 13 May 2017 at 09:05:17 UTC, Jonathan M Davis
 But obviously, to know what's actually happening with your 
 code, you're going to have to profile and benchmark it -
Can you please give a link or page or something to read about profile or benchmark. I have no experience with those.
Profiling: Halfway down this page: http://www.digitalmars.com/ctg/trace.html Two programs for visualising bottlenecks: https://bitbucket.org/andrewtrotman/d-profile-viewer https://code.dlang.org/packages/profdump Benchmarking: https://youtu.be/QELK73JSpFk?list=PL3jwVPmk_PRxo23yyoc0Ip_cP3-rCm7eB (fresh from DConf) https://dlang.org/library/std/datetime/benchmark.html https://code.dlang.org/packages/std_benchmark https://code.dlang.org/packages/benchmarkplotter
May 13