Thread overview | ||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|
|
April 22, 2017 Default-valued nothrow @nogc std.conv:to | ||||
---|---|---|---|---|
| ||||
Have anyone tried to implement a variant of `std.conv.to` that can be `nothrow @nogc` if the exception handling is replaced by an extra second parameter (`defaultValue`) returned iff the call to `to` throws? I currently have a solution https://github.com/nordlow/phobos-next/blob/b7a5c589d890f6b7bef7c5f2588fa93d90d19d62/src/conv_ex.d#L10 that is `nothrow` but not (yet) `@nogc`: CommonType!(T, U) toWithDefault(T, U, S)(S value, U defaultValue) if (haveCommonType!(T, U)) { try { import std.conv : to; return value.to!T; } catch (Exception e) // assume ConvException. TODO can we capture ConvException instead make it inferred nothrow { return defaultValue; } } Is there any way I can make it `@nogc` without having to modify the code in `std.conv`? Further, can anybody think of a more consice naming than `toWithDefault`? |
April 22, 2017 Re: Default-valued nothrow @nogc std.conv:to | ||||
---|---|---|---|---|
| ||||
Posted in reply to Nordlöw | On Saturday, 22 April 2017 at 12:14:26 UTC, Nordlöw wrote:
> Is there any way I can make it `@nogc` without having to modify the code in `std.conv`?
If I get this to work, I'm gonna try pushing it into std.conv.
|
April 22, 2017 Re: Default-valued nothrow @nogc std.conv:to | ||||
---|---|---|---|---|
| ||||
Posted in reply to Nordlöw | On Saturday, 22 April 2017 at 12:14:26 UTC, Nordlöw wrote:
> if (haveCommonType!(T, U))
Defined as:
/// Is `true` iff `Types` all share a common type.
enum bool haveCommonType(Types...) = !is(CommonType!Types == void);
import std.traits : CommonType;
|
April 22, 2017 Re: Default-valued nothrow @nogc std.conv:to | ||||
---|---|---|---|---|
| ||||
Posted in reply to Nordlöw | On Saturday, 22 April 2017 at 12:16:19 UTC, Nordlöw wrote: > On Saturday, 22 April 2017 at 12:14:26 UTC, Nordlöw wrote: >> Is there any way I can make it `@nogc` without having to modify the code in `std.conv`? > > If I get this to work, I'm gonna try pushing it into std.conv. If defaultValue is not lazy, it's potentially wasteful. But at the moment, lazy are never inferred as nothrow: https://issues.dlang.org/show_bug.cgi?id=12647 |
April 22, 2017 Re: Default-valued nothrow @nogc std.conv:to | ||||
---|---|---|---|---|
| ||||
Posted in reply to Stanislav Blinov | On Saturday, 22 April 2017 at 15:36:56 UTC, Stanislav Blinov wrote:
> On Saturday, 22 April 2017 at 12:16:19 UTC, Nordlöw wrote:
>> On Saturday, 22 April 2017 at 12:14:26 UTC, Nordlöw wrote:
>>> Is there any way I can make it `@nogc` without having to modify the code in `std.conv`?
>>
>> If I get this to work, I'm gonna try pushing it into std.conv.
>
> If defaultValue is not lazy, it's potentially wasteful.
What do you mean with "potentially wasteful"?
Excess calls to copy constructors?
|
April 22, 2017 Re: Default-valued nothrow @nogc std.conv:to | ||||
---|---|---|---|---|
| ||||
Posted in reply to Nordlöw | On Saturday, 22 April 2017 at 16:41:00 UTC, Nordlöw wrote:
>> If defaultValue is not lazy, it's potentially wasteful.
>
> What do you mean with "potentially wasteful"?
>
> Excess calls to copy constructors?
Evaluation of an expression the result of which might not be used. defaultValue could be anything: a literal, an lvalue, a result of a function call...
|
April 22, 2017 Re: Default-valued nothrow @nogc std.conv:to | ||||
---|---|---|---|---|
| ||||
Posted in reply to Stanislav Blinov | On 4/22/17 6:57 PM, Stanislav Blinov wrote:
> On Saturday, 22 April 2017 at 16:41:00 UTC, Nordlöw wrote:
>
>>> If defaultValue is not lazy, it's potentially wasteful.
>>
>> What do you mean with "potentially wasteful"?
>>
>> Excess calls to copy constructors?
>
> Evaluation of an expression the result of which might not be used.
> defaultValue could be anything: a literal, an lvalue, a result of a
> function call...
IMO you are overenginering this. defaultValue will most likely be something distinct such as compile-time constant.
---
Dmitry Olshansky
|
April 22, 2017 Re: Default-valued nothrow @nogc std.conv:to | ||||
---|---|---|---|---|
| ||||
Posted in reply to Dmitry Olshansky | On Saturday, 22 April 2017 at 18:26:56 UTC, Dmitry Olshansky wrote:
> On 4/22/17 6:57 PM, Stanislav Blinov wrote:
>> On Saturday, 22 April 2017 at 16:41:00 UTC, Nordlöw wrote:
>>
>>>> If defaultValue is not lazy, it's potentially wasteful.
>>>
>>> What do you mean with "potentially wasteful"?
>>>
>>> Excess calls to copy constructors?
>>
>> Evaluation of an expression the result of which might not be used.
>> defaultValue could be anything: a literal, an lvalue, a result of a
>> function call...
>
> IMO you are overenginering this. defaultValue will most likely be something distinct such as compile-time constant.
I'm looking at it from the perspective of it being added to Phobos, which seems to be Nordlöw's intent. There should not be any assumptions in that scenario, or there should be an overload for the "most likely" case.
The signature says: defaultValue will be anything convertible to typeof(defaultValue), and is going to be evaluated regardless of whether or not std.conv.to() call throws.
All I'm saying is the purpose *suggests* that the defaultValue parameter should be lazy, and that that currently annotating it so defeats that purpose is due to a bug. Although one could work around the bug for the time being by using std.exception.assumeWontThrow.
|
April 22, 2017 Re: Default-valued nothrow @nogc std.conv:to | ||||
---|---|---|---|---|
| ||||
Posted in reply to Nordlöw | On Saturday, 22 April 2017 at 12:16:19 UTC, Nordlöw wrote:
> On Saturday, 22 April 2017 at 12:14:26 UTC, Nordlöw wrote:
> If I get this to work, I'm gonna try pushing it into std.conv.
Another bit to pick on is the return value.
auto x = toWithDefault!int("1", 0.0f);
typeof(x) will be float even though the caller requested a conversion to int.
Probably should be
T toWithDefault(T,S,U)(S v, /*lazy*/ U defaultValue)
if (is(typeof(() { T r = defaultValue; })))
{
//...
}
|
April 24, 2017 Re: Default-valued nothrow @nogc std.conv:to | ||||
---|---|---|---|---|
| ||||
Posted in reply to Nordlöw | On Saturday, 22 April 2017 at 12:14:26 UTC, Nordlöw wrote: > Have anyone tried to implement a variant of `std.conv.to` that can be `nothrow @nogc` if the exception handling is replaced by an extra second parameter (`defaultValue`) returned iff the call to `to` throws? There is common ifThrown template in Phobos: https://dlang.org/phobos/std_exception.html#ifThrown I think it's better to add nothrow ifThrown implementation if needed. As for me, for such cases, where input data can be not relevant, is better to use Nullable type to indicate the error. In this case, an input value equal to the default value does not cause problems. Something like this: import std.typecons: Nullable; Nullable!T nullableTo(T, S)(S source) { import std.conv : to; try return Nullable!T(source.to!T); catch(Exception e) return Nullable!T(); } T orElse(T)(Nullable!T n, T value){ return n.isNull() ? value : n.get; } unittest { assert(! "0".nullableTo!int.isNull); assert("0.0".nullableTo!int.isNull); assert("123.45".nullableTo!int.isNull); assert("123".nullableTo!int.get == 123); // And easy convertable to default value variant assert("123.45".nullableTo!int.orElse(5) == 5); } |
Copyright © 1999-2021 by the D Language Foundation