Re: Why does this code only work with `std.conv.to` whilst not with `cast`?

2023-01-08 Thread matheus via Digitalmars-d-learn

On Sunday, 8 January 2023 at 12:39:37 UTC, thebluepandabear wrote:

...
The `foreach` worked for that case since `bark` is a method of 
`IDog`. `update` is not so a conversion to `Button[]` is needed.




In that case, you could do a casting like this:

import std.stdio, std.conv;

interface IDog {
void bark();
}

class Dog: IDog{
string s;
this(string _s){s = _s;}
void bark(){writeln(s);}
void update(string _s){ s ~= " - " ~ _s; }
}

class List{
IDog[] dogs;
void add(T)(T d){ dogs ~= d;  }
}

void main(){
auto d1 = new Dog("meaw!");
auto d2 = new Dog("wof!");
auto l = new List();
l.add(d1);
l.add(d2);

foreach(i,d; l.dogs){ // I'm using 'i' just to show each 
update.

(cast(Dog)d).update(to!string(i));
d.bark();
}
}

Prints:

meaw! - 0
wof! - 1

Matheus.


Re: Why does this code only work with `std.conv.to` whilst not with `cast`?

2023-01-08 Thread matheus via Digitalmars-d-learn

On Sunday, 8 January 2023 at 11:29:10 UTC, thebluepandabear wrote:

...


There is an explanation here: 
https://forum.dlang.org/post/tqukutfzeaxedunuv...@forum.dlang.org


But in any case I'd like to point it out that I think you could 
do that foreach without casting or std.conv by just omitting the 
type of the variable you're iterating:


import std.stdio, std.conv;

interface IDog {
void bark();
}

class Dog: IDog{
string s;
this(string _s){s = _s;}
void bark(){writeln(s);}
}

class List{
IDog[] dogs;
void add(T)(T d){ dogs ~= d;  }
}

void main(){
auto d1 = new Dog("meaw!");
auto d2 = new Dog("wof!");
auto l = new List();
l.add(d1);
l.add(d2);

foreach(d; l.dogs){ // No type informed for "d"
d.bark();
}
}

Prints:

meaw!
wof!

Matheus.


Re: Why does this code only work with `std.conv.to` whilst not with `cast`?

2023-01-08 Thread thebluepandabear via Digitalmars-d-learn

On Sunday, 8 January 2023 at 12:35:38 UTC, matheus wrote:
On Sunday, 8 January 2023 at 11:29:10 UTC, thebluepandabear 
wrote:

...


There is an explanation here: 
https://forum.dlang.org/post/tqukutfzeaxedunuv...@forum.dlang.org


But in any case I'd like to point it out that I think you could 
do that foreach without casting or std.conv by just omitting 
the type of the variable you're iterating:


import std.stdio, std.conv;

interface IDog {
void bark();
}

class Dog: IDog{
string s;
this(string _s){s = _s;}
void bark(){writeln(s);}
}

class List{
IDog[] dogs;
void add(T)(T d){ dogs ~= d;  }
}

void main(){
auto d1 = new Dog("meaw!");
auto d2 = new Dog("wof!");
auto l = new List();
l.add(d1);
l.add(d2);

foreach(d; l.dogs){ // No type informed for "d"
d.bark();
}
}

Prints:

meaw!
wof!

Matheus.


The `foreach` worked for that case since `bark` is a method of 
`IDog`. `update` is not so a conversion to `Button[]` is needed.


I will look at your resource, thanks.


Re: Why does this code only work with `std.conv.to` whilst not with `cast`?

2023-01-08 Thread ag0aep6g via Digitalmars-d-learn

On 08.01.23 12:29, thebluepandabear wrote:

```D
interface ICustomDrawable {
     void render(sfRenderWindow* renderWindow);
}

[...]> class Button : ICustomDrawable {
[...]

}

[...]

class StackLayout : ICustomDrawable {

[...]

     ICustomDrawable[] _children;
}
```

For some reason, when I want to cast the `children` (property), only the 
second example works:


1.

```D
foreach (Button button; cast(Button[])(_boardSizeRow.children)) {
     button.update(event, _renderWindow);
}
```

2.

```D
foreach (Button button; to!(Button[])(_boardSizeRow.children)) {
     button.update(event, _renderWindow);
}
```


Two things you need to know:

1. While an interface reference implicitly converts to a compatible 
class reference, the resulting pointer is slightly different.



interface I {}
class C : I {}
void main()
{
C c = new C;
I i = c;
import std.stdio;
writeln(cast(void*) c); /* e.g. 7F3C140A7000 */
writeln(cast(void*) i); /* e.g. 7F3C140A7010 */
}


2. Casting from one array type to another is done "as a type paint"[1]. 
The elements of the array are reinterpreted, not converted.


But reinterpreting interface references as class references won't work, 
because the pointers will be wrong. You need to convert each element of 
the array (which is what `to` does).



[1] https://dlang.org/spec/expression.html#cast_array


Why does this code only work with `std.conv.to` whilst not with `cast`?

2023-01-08 Thread thebluepandabear via Digitalmars-d-learn
I've been writing some code and I have been experimenting with 
casting. I've found that sometimes only `std.conv.to!` does the 
job over casting, and I am unsure why this is the case as I 
assumed that they are both the same.


I have the following interface:

```D
interface ICustomDrawable {
void render(sfRenderWindow* renderWindow);
}
```

And the following class that implements that interface:

```D
class Button : ICustomDrawable {
...
override void render(sfRenderWindow* renderWindow) {
...
}
}
```

And this class which uses `ICustomDrawable`:

```D
class StackLayout : ICustomDrawable {
   ...
void addChild(T)(T child) {
static assert(is(T : ICustomDrawable), "Invalid type T 
for child");

...
}
...
ICustomDrawable[] _children;
}
```

For some reason, when I want to cast the `children` (property), 
only the second example works:


1.

```D
foreach (Button button; cast(Button[])(_boardSizeRow.children)) {
button.update(event, _renderWindow);
}
```

2.

```D
foreach (Button button; to!(Button[])(_boardSizeRow.children)) {
button.update(event, _renderWindow);
}
```

When I run the first code example I get a black screen, whilst 
with the second I do not. I find this very strange as when I 
write to the console the 'type', it is the same for both 
scenarios.


Help would be appreciated as to why this is happening so I can 
better understand how D works.




Re: std.conv.to

2022-06-20 Thread Steven Schveighoffer via Digitalmars-d-learn

On 6/17/22 8:48 AM, harakim wrote:

On Friday, 17 June 2022 at 12:31:45 UTC, harakim wrote:
I can generically convert a string to a type using to!type. I have a 
read function that does that. I have simplified the example below:


```d
int readNumber()
{
    return read!int(val => to!int(val), "number");
}

string readTime()
{
    return read!string(val => toTime(val), "time");
}

private T read(T)(T function(string) transform, string typeName)
{
    string input = readln();
    return transform(input);
}
```
However, I want to be able to convert my own custom types as well. How 
do I do that? Is there an operator overload I need to override for 
that? Do I have to static if on the template type and call the object?


I have no idea why I was stuck on this problem for so long. I can 
specify anything I want in the transform and I even do in my own example 
lol. I am still curious if there is a way to make your type work with 
to!MyCustomType(source)


`to` uses natural hints that it can find via introspection. As others 
have pointed out, you can define a constructor in the target type to 
take the source type. To go the other way, you can define an `opCast` in 
the source type (if that's possible). If you want to convert to string 
(a specialized case), use a `toString` member function.


For class to class conversion, `to` will try a dynamic cast if none of 
the above is the case.


I believe there is no specific hook aside from these that allows you to 
define a conversion path.


-Steve


Re: std.conv.to

2022-06-17 Thread Salih Dincer via Digitalmars-d-learn

On Friday, 17 June 2022 at 18:40:59 UTC, Ali Çehreli wrote:

On 6/17/22 10:04, Salih Dincer wrote:

> Isn't foo and bar the same thing?  I don't understand what's
the
> difference!
> ```d
>auto foo = to!Foo("123"); //??
>auto bar = Foo("321");
> ```
Yes, they are the same thing.


But (!) `to!` inconsiderately smuggled into the code is bubble. 
So we will obviously be deceived at a later moment. Thereby 
making nonsense further clamour for shorten...:)


Then how did the evolution of the code evolve into the current 
form?


```d
   auto zar = "123".to!Foo;
   auto bar = to!(Foo)("123");
   auto foo = to!Foo("123"); // <-- this line is bubble
```

SDB@79


Re: std.conv.to

2022-06-17 Thread Ali Çehreli via Digitalmars-d-learn

On 6/17/22 10:04, Salih Dincer wrote:

> Isn't foo and bar the same thing?  I don't understand what's the
> difference!

>auto foo = to!Foo("123"); //??

>auto bar = Foo("321");

Yes, they are the same thing.

The OP was looking for a generic way of converting any type to any other 
type as long as there is a way. (Think a function template.) std.conv.to 
can do that because it considers the constructors as well.


Ali



Re: std.conv.to

2022-06-17 Thread harakim via Digitalmars-d-learn

On Friday, 17 June 2022 at 12:53:53 UTC, bauss wrote:
Just add a constructor to your type that takes the value of 
what you want to convert.


Working example:

```d
struct Foo
{
int value;

this(int v)
{
value = v;
}

this(string v)
{
this(to!int(v));
}
}

void main()
{
auto foo = to!Foo("123");

writeln(foo.value);
}
```


D is full of good surprises. Thanks.


Re: std.conv.to

2022-06-17 Thread Salih Dincer via Digitalmars-d-learn

On Friday, 17 June 2022 at 12:53:53 UTC, bauss wrote:


Just add a constructor to your type that takes the value of 
what you want to convert.


Isn't foo and bar the same thing?  I don't understand what's the 
difference!  By the way, what's the question?  Is this the answer 
to the question?


```d
void main()
{
  auto foo = to!Foo("123"); //??
  typeid(foo).writeln(": ", foo);

  assert("123".to!Foo == foo);
  assert(123.to!Foo == foo);

  auto bar = Foo("321");
  typeid(bar).writeln(": ", bar);

  assert("321".to!Foo == bar);
  assert(321.to!Foo == bar);
}
```
SDB@79



Re: std.conv.to

2022-06-17 Thread bauss via Digitalmars-d-learn

On Friday, 17 June 2022 at 12:48:56 UTC, harakim wrote:

On Friday, 17 June 2022 at 12:31:45 UTC, harakim wrote:
I can generically convert a string to a type using to!type. I 
have a read function that does that. I have simplified the 
example below:


```d
int readNumber()
{
return read!int(val => to!int(val), "number");
}

string readTime()
{
return read!string(val => toTime(val), "time");
}

	private T read(T)(T function(string) transform, string 
typeName)

{
string input = readln();
return transform(input);
}
```
However, I want to be able to convert my own custom types as 
well. How do I do that? Is there an operator overload I need 
to override for that? Do I have to static if on the template 
type and call the object?


I have no idea why I was stuck on this problem for so long. I 
can specify anything I want in the transform and I even do in 
my own example lol. I am still curious if there is a way to 
make your type work with to!MyCustomType(source)


Just add a constructor to your type that takes the value of what 
you want to convert.


Working example:

```d
struct Foo
{
int value;

this(int v)
{
value = v;
}

this(string v)
{
this(to!int(v));
}
}

void main()
{
auto foo = to!Foo("123");

writeln(foo.value);
}
```


Re: std.conv.to

2022-06-17 Thread harakim via Digitalmars-d-learn

On Friday, 17 June 2022 at 12:31:45 UTC, harakim wrote:
I can generically convert a string to a type using to!type. I 
have a read function that does that. I have simplified the 
example below:


```d
int readNumber()
{
return read!int(val => to!int(val), "number");
}

string readTime()
{
return read!string(val => toTime(val), "time");
}

	private T read(T)(T function(string) transform, string 
typeName)

{
string input = readln();
return transform(input);
}
```
However, I want to be able to convert my own custom types as 
well. How do I do that? Is there an operator overload I need to 
override for that? Do I have to static if on the template type 
and call the object?


I have no idea why I was stuck on this problem for so long. I can 
specify anything I want in the transform and I even do in my own 
example lol. I am still curious if there is a way to make your 
type work with to!MyCustomType(source)


std.conv.to

2022-06-17 Thread harakim via Digitalmars-d-learn
I can generically convert a string to a type using to!type. I 
have a read function that does that. I have simplified the 
example below:


```d
int readNumber()
{
return read!int(val => to!int(val), "number");
}

string readTime()
{
return read!string(val => toTime(val), "time");
}

private T read(T)(T function(string) transform, string typeName)
{
string input = readln();
return transform(input);
}
```
However, I want to be able to convert my own custom types as 
well. How do I do that? Is there an operator overload I need to 
override for that? Do I have to static if on the template type 
and call the object?


Re: Unexpected result with std.conv.to

2019-11-14 Thread Joel via Digitalmars-d-learn

On Friday, 15 November 2019 at 04:26:58 UTC, Jon Degenhardt wrote:

On Friday, 15 November 2019 at 03:51:04 UTC, Joel wrote:
I made a feature that converts, say, [9:59am] -> [10:00am] to 
1 minute. but found '9'.to!int = 57 (not 9).


Doesn't seem right... I'm guessing that's standard though, 
same with ldc.


Use a string or char[] array. e.g. writeln("9".to!int) => 9.

With a single 'char' what is being produced is the ascii value 
of the character.


Thanks, Jon Degenhardt. I did work it out.


Re: Unexpected result with std.conv.to

2019-11-14 Thread Jon Degenhardt via Digitalmars-d-learn

On Friday, 15 November 2019 at 03:51:04 UTC, Joel wrote:
I made a feature that converts, say, [9:59am] -> [10:00am] to 1 
minute. but found '9'.to!int = 57 (not 9).


Doesn't seem right... I'm guessing that's standard though, same 
with ldc.


Use a string or char[] array. e.g. writeln("9".to!int) => 9.

With a single 'char' what is being produced is the ascii value of 
the character.


Unexpected result with std.conv.to

2019-11-14 Thread Joel via Digitalmars-d-learn
I made a feature that converts, say, [9:59am] -> [10:00am] to 1 
minute. but found '9'.to!int = 57 (not 9).


Doesn't seem right... I'm guessing that's standard though, same 
with ldc.


Re: tryTo: non-throwing variant of std.conv.to

2018-08-15 Thread Per Nordlöw via Digitalmars-d-learn
On Wednesday, 15 August 2018 at 10:38:23 UTC, Jonathan M Davis 
wrote:
Would it be sane to add these to std.conv alongside existing 
std.conv.to so that underlying logic in std.conv.to can be 
reused?


If so, AFAICT, existing std.conv.to should be implemented on


Put something together to get early feedback on the idea:

https://github.com/dlang/phobos/pull/6665


Re: tryTo: non-throwing variant of std.conv.to

2018-08-15 Thread Per Nordlöw via Digitalmars-d-learn

On Wednesday, 15 August 2018 at 09:26:26 UTC, Seb wrote:
If so, AFAICT, existing std.conv.to should be implemented on 
top of std.conv.tryTo.


Well, for now you can use `ifThrown` from std.exception:

https://dlang.org/phobos/std_exception.html#ifThrown

---
"foo".to!int.ifThrown(42)


But the whole idea is to avoid both throwing and catching 
exceptions at all. As this results in orders of magnitudes of 
drop in performance for the throwing case. That's the reason why 
Folly has this aswell.


Thanks anyway, Seb.


Re: tryTo: non-throwing variant of std.conv.to

2018-08-15 Thread Jonathan M Davis via Digitalmars-d-learn
On Wednesday, August 15, 2018 3:21:29 AM MDT Per Nordlöw via Digitalmars-d-
learn wrote:
> Have anybody thought about non-throwing variants of std.conv.to
> typically named `tryTo`
> similar to what Folly
>
> https://github.com/facebook/folly/blob/master/folly/docs/Conv.md#non-throw
> ing-interfaces
>
> does, for instance, as
>
>  tryTo(str).then([](int i) { use(i); });
>
> ?
>
> Would it be sane to add these to std.conv alongside existing
> std.conv.to so that underlying logic in std.conv.to can be reused?
>
> If so, AFAICT, existing std.conv.to should be implemented on top
> of std.conv.tryTo.

Yes. I've considered writing a set of conversion functions like std.conv.to
which return a Nullable!T (where the target type is T) and return
Nullable!T.init when the conversion fails rather than throwing, and they
really should be in std.conv alongside to, reusing logic as much as
reasonably possible, but it's not a small project. It's come up off and on
for a while now, so I expect that someone will do it eventually (and I may
at some point if no one else does), but obviously, someone has to actually
take the time to do it, or it's not going to happen.

- Jonathan M Davis






Re: tryTo: non-throwing variant of std.conv.to

2018-08-15 Thread Seb via Digitalmars-d-learn

On Wednesday, 15 August 2018 at 09:21:29 UTC, Per Nordlöw wrote:
Have anybody thought about non-throwing variants of std.conv.to 
typically named `tryTo`

similar to what Folly

https://github.com/facebook/folly/blob/master/folly/docs/Conv.md#non-throwing-interfaces

does, for instance, as

tryTo(str).then([](int i) { use(i); });

?

Would it be sane to add these to std.conv alongside existing 
std.conv.to so that underlying logic in std.conv.to can be 
reused?


If so, AFAICT, existing std.conv.to should be implemented on 
top of std.conv.tryTo.


Well, for now you can use `ifThrown` from std.exception:

https://dlang.org/phobos/std_exception.html#ifThrown

---
"foo".to!int.ifThrown(42)
---

https://run.dlang.io/is/nlZKOw

Usage of optionals/nullables is sadly not very common in Phobos 
and I think if we want everything to work nicely, we probably 
have to start a new standard library (or do massive refactorings 
of the existing one.)


tryTo: non-throwing variant of std.conv.to

2018-08-15 Thread Per Nordlöw via Digitalmars-d-learn
Have anybody thought about non-throwing variants of std.conv.to 
typically named `tryTo`

similar to what Folly

https://github.com/facebook/folly/blob/master/folly/docs/Conv.md#non-throwing-interfaces

does, for instance, as

tryTo(str).then([](int i) { use(i); });

?

Would it be sane to add these to std.conv alongside existing 
std.conv.to so that underlying logic in std.conv.to can be reused?


If so, AFAICT, existing std.conv.to should be implemented on top 
of std.conv.tryTo.


Re: Nothrow std.conv.to with explicit default value

2018-06-21 Thread Per Nordlöw via Digitalmars-d-learn

On Wednesday, 20 June 2018 at 14:39:48 UTC, Per Nordlöw wrote:
Is there a way to avoid compile-time-string-concat plus mixin 
here?


Using __traits(getMember, ...) should compile faster, right?

T toDefaulted(T)(scope const(char)[] value, T defaultValue) @safe 
pure nothrow @nogc

if (is(T == enum))
{
// doesn't need `std.conv.to`
switch (value)
{
static foreach (member; __traits(allMembers, T)) // 
prevents call to slower `EnumMembers`

{
case member:
return __traits(getMember, T, member); // NOTE this 
is slower: mixin(`return T.` ~ member ~ `;`);

}
default:
return defaultValue;
}
}



Re: Nothrow std.conv.to with explicit default value

2018-06-20 Thread Per Nordlöw via Digitalmars-d-learn

On Wednesday, 20 June 2018 at 09:54:29 UTC, Per Nordlöw wrote:

T toDefaulted(T)(scope const(char)[] value,
 T defaultValue) @safe pure nothrow @nogc
if (is(T == enum))
{
switch (value)
{
static foreach (index, member; __traits(allMembers, T))
{
case member:
return cast(T)(index);
}


Oops, this doesn't work for enums with "holes". How do I most 
easily fix that?


This is my solution:

T toDefaulted(T)(scope const(char)[] value, T defaultValue) @safe 
pure nothrow @nogc

if (is(T == enum))
{
switch (value)
{
static foreach (member; __traits(allMembers, T))
{
case member:
mixin(`return T.` ~ member ~ `;`);
}
default:
return defaultValue;
}
}

Is there a way to avoid compile-time-string-concat plus mixin 
here?


Re: Nothrow std.conv.to with explicit default value

2018-06-20 Thread Jonathan M Davis via Digitalmars-d-learn
On Wednesday, June 20, 2018 09:37:00 Per Nordlöw via Digitalmars-d-learn 
wrote:
> On Wednesday, 20 June 2018 at 09:27:14 UTC, Per Nordlöw wrote:
> > On Monday, 18 June 2018 at 21:10:03 UTC, Steven Schveighoffer
> >
> > wrote:
> >> It just means re-doing std.conv.to, which is pretty hairy, but
> >> also pretty well-organized.
> >
> > Ok. Where in std.conv do the string-to-enum conversions take
> > place?
>
> AFAICT, string-to-enum-conversion must include a switch
> containing a static foreach over all the enumerators, right?

If you want to know where std.conv deals with converting enums, look for
EnumMembers, since that's the trait to get all of the members of an enum.

- Jonathan M Davis




Re: Nothrow std.conv.to with explicit default value

2018-06-20 Thread Per Nordlöw via Digitalmars-d-learn

On Wednesday, 20 June 2018 at 09:37:00 UTC, Per Nordlöw wrote:
AFAICT, string-to-enum-conversion must include a switch 
containing a static foreach over all the enumerators, right?


My suggestion for nothrow @nogc string-to-enum conversion with 
default value



T toDefaulted(T)(scope const(char)[] value,
 T defaultValue) @safe pure nothrow @nogc
if (is(T == enum))
{
switch (value)
{
static foreach (index, member; __traits(allMembers, T))
{
case member:
return cast(T)(index);
}
default:
return defaultValue;
}
}

@safe pure nothrow /*TODO @nogc*/ unittest
{
enum E { unknown, x, y, z }
assert("x".toDefaulted!(E)(E.init) == E.x);
assert("_".toDefaulted!(E)(E.init) == E.unknown);
}


Re: Nothrow std.conv.to with explicit default value

2018-06-20 Thread Per Nordlöw via Digitalmars-d-learn

On Wednesday, 20 June 2018 at 09:52:04 UTC, Per Nordlöw wrote:
My suggestion for nothrow @nogc string-to-enum conversion with 
default value



T toDefaulted(T)(scope const(char)[] value,
 T defaultValue) @safe pure nothrow @nogc
if (is(T == enum))
{
switch (value)
{
static foreach (index, member; __traits(allMembers, T))
{
case member:
return cast(T)(index);
}


Oops, this doesn't work for enums with "holes". How do I most 
easily fix that?


Re: Nothrow std.conv.to with explicit default value

2018-06-20 Thread Per Nordlöw via Digitalmars-d-learn

On Wednesday, 20 June 2018 at 09:27:14 UTC, Per Nordlöw wrote:
On Monday, 18 June 2018 at 21:10:03 UTC, Steven Schveighoffer 
wrote:
It just means re-doing std.conv.to, which is pretty hairy, but 
also pretty well-organized.


Ok. Where in std.conv do the string-to-enum conversions take 
place?


AFAICT, string-to-enum-conversion must include a switch 
containing a static foreach over all the enumerators, right?


Re: Nothrow std.conv.to with explicit default value

2018-06-20 Thread Per Nordlöw via Digitalmars-d-learn
On Monday, 18 June 2018 at 21:10:03 UTC, Steven Schveighoffer 
wrote:
It just means re-doing std.conv.to, which is pretty hairy, but 
also pretty well-organized.


Ok. Where in std.conv do the string-to-enum conversions take 
place?


Re: Nothrow std.conv.to with explicit default value

2018-06-18 Thread Steven Schveighoffer via Digitalmars-d-learn

On 6/18/18 4:48 PM, Per Nordlöw wrote:
The problem with this code is that throwing exceptions for the default 
case is costly at least with dmd. Is there another way to do this?


Yes, have an internal implementation which doesn't throw, but rather 
returns an error code. Then you can call that and throw or use default 
value based on the return value.


It just means re-doing std.conv.to, which is pretty hairy, but also 
pretty well-organized.


-Steve


Re: Nothrow std.conv.to with explicit default value

2018-06-18 Thread Adam D. Ruppe via Digitalmars-d-learn

On Monday, 18 June 2018 at 20:48:55 UTC, Per Nordlöw wrote:

T toDefaulted(T, S, U)(S value, /*lazy*/ U defaultValue)
if (is(typeof(() { T r = defaultValue; }))) // TODO use 
std.traits.isAssignable!(T, U) ?


why not just make it

T toDefaulted(T, S)(S value, T defaultValue)

and forget U entirely?

The problem with this code is that throwing exceptions for the 
default case is costly at least with dmd. Is there another way 
to do this?


It depends on what the types are. If it is like string to int, 
you can simply scan the string for the appropriate format.


For other conversions though, I don't think you can tell in 
general. User-defined types might not even tell you except by 
exception.


Nothrow std.conv.to with explicit default value

2018-06-18 Thread Per Nordlöw via Digitalmars-d-learn

I have a nothrow variant of std.conv.to defined as follows:

T toDefaulted(T, S, U)(S value, /*lazy*/ U defaultValue)
if (is(typeof(() { T r = defaultValue; }))) // TODO use 
std.traits.isAssignable!(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;
}
}

The problem with this code is that throwing exceptions for the 
default case is costly at least with dmd. Is there another way to 
do this?


Re: std.conv.to!string refuses to convert a char* to string.

2017-12-09 Thread Venkat via Digitalmars-d-learn
Thank you, core.runtime.Runtime.initialize() fixed the issue. I 
am now able to use to!string as well. I found your posts and Ali 
Çehreli's posts on this subject. I think I have some 
understanding now.


Re: std.conv.to!string refuses to convert a char* to string.

2017-12-09 Thread Mike Parker via Digitalmars-d-learn

On Saturday, 9 December 2017 at 06:14:36 UTC, Venkat wrote:
Thanks for the quick response. std.string.fromStringz did the 
trick. I am not sure what was the deal with to!string.


Be careful with fromStringz. It doesn't allocate a new string, so 
the returned string can easily become corrupted if the C string 
it's referencing falls off the stack.


As for your problem with to!string, it isn't actually to!string 
that's the issue. It appears to have something to do with the 
memory allocated from the GC. I assume this is a shared library. 
Random thoughts -- Have you initialized DRuntime? Have you 
registered the calling thread with the GC?


Re: std.conv.to!string refuses to convert a char* to string.

2017-12-08 Thread Venkat via Digitalmars-d-learn
Thanks for the quick response. std.string.fromStringz did the 
trick. I am not sure what was the deal with to!string.


Re: std.conv.to!string refuses to convert a char* to string.

2017-12-08 Thread Neia Neutuladh via Digitalmars-d-learn

On Saturday, 9 December 2017 at 05:55:21 UTC, Venkat wrote:
I am trying out the DJni library 
(https://github.com/Monnoroch/DJni). For some reason 
std.conv.to!string doesn't want to convert a char* to a 
string.The lines below are taken from the log. I see that the 
last frame is at gc_qalloc. I am not sure why it failed there. 
Can anybody elaborate on what is going on here ? Thanks in 
advance.


I've got no idea, but can you verify that you can print it with 
printf? Can you allocate other GC memory? Can you try using 
fromStringz instead of to!string and see what that does?


Just shots in the dark...


std.conv.to!string refuses to convert a char* to string.

2017-12-08 Thread Venkat via Digitalmars-d-learn
I am trying out the DJni library 
(https://github.com/Monnoroch/DJni). For some reason 
std.conv.to!string doesn't want to convert a char* to a 
string.The lines below are taken from the log. I see that the 
last frame is at gc_qalloc. I am not sure why it failed there. 
Can anybody elaborate on what is going on here ? Thanks in 
advance.


 91
 92
 93 Stack: [0x7f749dfd9000,0x7f749e0da000],  
sp=0x7f749e0d8600,  free space=1021k
 94 Native frames: (J=compiled Java code, j=interpreted, Vv=VM 
code, C=native code)

 95 C  [libPrompt.so+0x6b0cc]  gc_qalloc+0x2c
 96 C  [libPrompt.so+0x7bf18]  
_D2rt8lifetime12__arrayAllocFNaNbmxC8TypeInfoxQlZS4core6memory8BlkInfo_+0xec

 97 C  [libPrompt.so+0x6c2fa]  _d_newarrayU+0x86
 98 C  [libPrompt.so+0x593a7]  
_D6object__T4_dupTxaTaZQlFNaNbAxaZAa+0x1f
 99 C  [libPrompt.so+0x59384]  
_D6object__T11_trustedDupTxaTaZQtFNaNbNeAxaZAa+0x20
100 C  [libPrompt.so+0x59360]  
_D6object__T3dupTaZQhFNaNbNdNfAxaZAa+0x20
101 C  [libPrompt.so+0x5932a]  
_D3std4conv__T6toImplTAyaTPxaZQqFQhZ9__lambda2MFNaNbZQBf+0x3e
102 C  [libPrompt.so+0x592ea]  
_D3std4conv__T6toImplTAyaTPxaZQqFNaNbQlZQs+0x16
103 C  [libPrompt.so+0x592d1]  
_D3std4conv__T2toTAyaZ__TQlTPxaZQsFNaNbQlZQy+0x9

104 C  [libPrompt.so+0x59289]  Java_Prompt_getLine+0x61
105 j  Prompt.getLine(Ljava/lang/String;)Ljava/lang/String;+0
106 j  Prompt.main([Ljava/lang/String;)V+11
107 v  ~StubRoutines::call_stub
108 V  [libjvm.so+0x690c66]  JavaCalls::call_helper(JavaValue*, 
methodHandle*, JavaCallArguments*, Thread*)+0x1056
109 V  [libjvm.so+0x6d2072]  jni_invoke_static(JNIEnv_*, 
JavaValue*, _jobject*, JNICallType, _jmethodID*, 
JNI_ArgumentPusher*, Thread*)+0x362

110 V  [libjvm.so+0x6ee8da]  jni_CallStaticVoidMethod+0x17a
111 C  [libjli.so+0x7bdf]  JavaMain+0x81f
112 C  [libpthread.so.0+0x8184]  start_thread+0xc4
113
114 Java frames: (J=compiled Java code, j=interpreted, Vv=VM code)
115 j  Prompt.getLine(Ljava/lang/String;)Ljava/lang/String;+0
116 j  Prompt.main([Ljava/lang/String;)V+11





Using std.conv.to with std.typecons.Typedef

2016-01-11 Thread Saurabh Das via Digitalmars-d-learn
I am trying to create 2 types which contain integral values but 
should not be compatible with each other. std.typecons.Typedef 
seems perfect for this:


alias QuestionId = Typedef!(long, long.init, "QuestionId");
alias StudentId = Typedef!(long, long.init, "StudentId");

However I'm failing to use using std.conv.to:
QuestionId q = to!QuestionId("34"); <-- gives compile errors

(This is a reduced example, the actual use case is to use std.csv 
to read in a structure from file, which in turn calls to!xyz)


How can I get std.conv to understand std.typecons.Typedef? In 
general, is there a better solution to orthogonal types than 
Typedef?


Thanks,
Saurabh



Re: Using std.conv.to with std.typecons.Typedef

2016-01-11 Thread Tobi G. via Digitalmars-d-learn

On Monday, 11 January 2016 at 08:03:19 UTC, Saurabh Das wrote:


How can I get std.conv to understand std.typecons.Typedef?


You can do something like this:

QuestionId q = to!(TypedefType!QuestionId)("43");

In general, is there a better solution to orthogonal types than 
Typedef?


Typedef is a reasonably solution, for this in my opinion.

togrue



Re: Using std.conv.to with std.typecons.Typedef

2016-01-11 Thread Tobi G. via Digitalmars-d-learn

On Monday, 11 January 2016 at 12:15:55 UTC, Saurabh Das wrote:


Any ideas?


Yes. Because Typedef is introducing new Types, which csvReader 
doesn't know what they are,

you'll need a little workaround and cast the values yourself.

import std.csv, std.stdio, std.algorithm, std.range;

enum csvTxt = "10, 20
30, 40
50, 50";

myStuff = csvTxt.csvReader!(Tuple!(long, long))
.map!(a => MyStuff(cast(QuestionId)a[0], cast(StudentId) a[1]))
.array;


The .map does nothing other as getting the information out of the 
Tuple 'a' and constructing a struct of the type MyStuff.


togrue


Re: Using std.conv.to with std.typecons.Typedef

2016-01-11 Thread Saurabh Das via Digitalmars-d-learn

On Monday, 11 January 2016 at 12:01:30 UTC, Tobi G. wrote:

On Monday, 11 January 2016 at 08:03:19 UTC, Saurabh Das wrote:


How can I get std.conv to understand std.typecons.Typedef?


You can do something like this:

QuestionId q = to!(TypedefType!QuestionId)("43");

In general, is there a better solution to orthogonal types 
than Typedef?


Typedef is a reasonably solution, for this in my opinion.

togrue


Oh excellent. Yes that works for a standalone conversion.  Do you 
know how I can use this with std.csv?


import std.typecons;
alias QuestionId = Typedef!(long, long.init, "QuestionId");
alias StudentId = Typedef!(long, long.init, "StudentId");

struct MyStuff
{
QuestionId q;
StudentId s;
}

void main()
{
import std.csv, std.stdio, std.algorithm, std.range;

File("file.csv").byLine.joiner("\n").csvReader!(MyStuff)(null).array;

}

This doesn't work. But if MyStuff is defined as: struct MyStuff { 
int q, s; }, then it works.


Any ideas?




Re: Using std.conv.to with std.typecons.Typedef

2016-01-11 Thread Saurabh Das via Digitalmars-d-learn

On Monday, 11 January 2016 at 12:59:05 UTC, Tobi G. wrote:

On Monday, 11 January 2016 at 12:15:55 UTC, Saurabh Das wrote:


Any ideas?


Yes. Because Typedef is introducing new Types, which csvReader 
doesn't know what they are,

you'll need a little workaround and cast the values yourself.

import std.csv, std.stdio, std.algorithm, std.range;

enum csvTxt = "10, 20
30, 40
50, 50";

myStuff = csvTxt.csvReader!(Tuple!(long, long))
.map!(a => MyStuff(cast(QuestionId)a[0], cast(StudentId) a[1]))
.array;


The .map does nothing other as getting the information out of 
the Tuple 'a' and constructing a struct of the type MyStuff.


togrue


Yes that does make sense. I could read in a POD struct and 
convert it to a typed one.


Though I was hoping for a more elegant solution... This'll have 
to do I guess.


Thanks!



Re: std.conv.to!string(array), strange compile error

2015-11-14 Thread BBaz via Digitalmars-d-learn

On Saturday, 14 November 2015 at 12:46:21 UTC, Relja wrote:
I've got this strange compile error using 
std.conv.to!string(double[3]) - or any static array type. It's 
called in toString override function of a template matrix 
class, I'm building as a D learning project.


[...]


Maybe try to use a full slice after a 'static if' in case the 
template type is static array:


--
{
ElementType!T[] something;
static if (isStaticArray!T)
something = value[]; // slice to get a dyn array
else
something = value; // already a dyn array
}
--

and you work on something when it only works on dyn array. You 
can also slice the whole static array each time the problem 
occurrs


Re: std.conv.to!string(array), strange compile error

2015-11-14 Thread Relja via Digitalmars-d-learn

On Saturday, 14 November 2015 at 12:55:52 UTC, BBaz wrote:

On Saturday, 14 November 2015 at 12:46:21 UTC, Relja wrote:
I've got this strange compile error using 
std.conv.to!string(double[3]) - or any static array type. It's 
called in toString override function of a template matrix 
class, I'm building as a D learning project.


[...]


Maybe try to use a full slice after a 'static if' in case the 
template type is static array:


--
{
ElementType!T[] something;
static if (isStaticArray!T)
something = value[]; // slice to get a dyn array
else
something = value; // already a dyn array
}
--

and you work on something when it only works on dyn array. You 
can also slice the whole static array each time the problem 
occurrs


I'm not sure if I understand you fully, but I think you 
misunderstood me - std.conv.to!string() works on a static array, 
when called directly on the array object, but gives the compile 
error when called on the returning object from a function.


Here is simpler example, which shows the same compile error:

import std.conv;

float[3] getFloat3() {
return [1, 2, 3];
}

void main() {
getFloat3().to!string; // does not compile
(new float[3]).to!string; // compiles
}

On this example, compiler error message is the same as above:
source/app.d(10,12): Error: template std.conv.to cannot deduce 
function from argument types !(string)(float[3]), candidates are:

/usr/include/dlang/dmd/std/conv.d(293,1):std.conv.to(T)
dmd failed with exit code 1.

But then again, your suggestion got me to try this:
getFloat3()[].to!string;

This does compile! Can somebody elaborate, and tell us whats 
going on here? I feel that this does not solve my issue, but only 
makes me stay away from calling std.conv.to in this way.


Thanks,
Relja


Re: std.conv.to!string(array), strange compile error

2015-11-14 Thread anonymous via Digitalmars-d-learn

On 14.11.2015 15:17, Relja wrote:

- std.conv.to!string() works on a static array, when called directly on
the array object, but gives the compile error when called on the
returning object from a function.

[...]

void main() {
 getFloat3().to!string; // does not compile
 (new float[3]).to!string; // compiles
}


`new float[3]` is not a static array. Its type is not `float[3]`, it's 
`float[]`.


Re: std.conv.to!string(array), strange compile error

2015-11-14 Thread Relja via Digitalmars-d-learn

On Saturday, 14 November 2015 at 14:30:06 UTC, anonymous wrote:

On 14.11.2015 15:17, Relja wrote:
- std.conv.to!string() works on a static array, when called 
directly on
the array object, but gives the compile error when called on 
the

returning object from a function.

[...]

void main() {
 getFloat3().to!string; // does not compile
 (new float[3]).to!string; // compiles
}


`new float[3]` is not a static array. Its type is not 
`float[3]`, it's `float[]`.


Oh, my bad, sorry. No mather, issue still stands:

float[3] array;
array.to!string; // compiles


std.conv.to!string(array), strange compile error

2015-11-14 Thread Relja via Digitalmars-d-learn
I've got this strange compile error using 
std.conv.to!string(double[3]) - or any static array type. It's 
called in toString override function of a template matrix class, 
I'm building as a D learning project.


Here is the toString method:
override string toString() const
{
string outs;
outs ~= "[";

for (size_t i = 0; i < rows; ++i)
{
outs ~= this.opIndex(i, 0).to!string;
for (size_t j = 1; j < cols; ++j)
{
outs~= ", " ~ this.opIndex(i, j).to!string;
}
if (i == rows - 1) // last row
outs ~= "]";
else
outs ~= ";\n";
}
return outs;
}

And here is the opIndex (const version):
const(T) opIndex(ulong r, ulong c) const
in
{
assert(r < _rows && c < _cols);
}
body
{
return _begin[c*_strides[1] + r*_strides[0]];
}

Error occurs on lines with "this.opIndex().to!string", when 
template type is static array, e.g. double[3]:


source/matrix.d(248,30): Error: template std.conv.to cannot 
deduce function from argument types !(string)(const(double[3])), 
candidates are:

/usr/include/dlang/dmd/std/conv.d(293,1):    std.conv.to(T)
source/matrix.d(251,37): Error: template std.conv.to cannot 
deduce function from argument types !(string)(const(double[3])), 
candidates are:

/usr/include/dlang/dmd/std/conv.d(293,1):std.conv.to(T)
source/main.d(17,2): Error: template instance 
matrix.Matrix!(double[3]) error instantiating


Lines 248 and 251 are the opIndex.to!string calls.


Anyhow, I've changed opIndex() calls in the toString with matrix 
array indexing implementation (_begin[row*col_stride + 
col*item_stride]), and the conversion works properly (as it 
should on any array type, and gives normal output). So I've made 
a little test with compile-time messages:


override string toString() const
{
string outs;
outs ~= "[";

pragma(msg, typeof(_begin[0]).stringof);
pragma(msg, typeof(this.opIndex(0, 0)).stringof);

this._begin[0].to!string;
(this.opIndex(0, 0)).to!string;

.

And here's the compile output:

const(double[3])
const(double[3])
source/matrix.d(250): Error: template std.conv.to cannot deduce 
function from argument types !(string)(const(double[3])), 
candidates are:

/usr/include/dlang/dmd/std/conv.d(293):std.conv.to(T)

Line 250 is opIndex().to!string, line above compiles ok.

So even opIndex has the same return type as the array itself, 
to!string produces compile error on the opIndex.to!string call, 
and on the array.to!string does not. Could this be a bug in the 
compiler, or am I doing something wrong with the opIndex (or any 
other) method declaration?


System is x64 Manjaro linux(arch based distro), compiler is dmd 
v2.069 (up-to-date from AUR, as libphobos is), and I have no 
other D compilers installed. Im' not sure how to check exact 
version of the libphobos - if anyone can tell me how to check it, 
please tell me, and I'll post it.


Any other suggestion about above code is welcome!

Thanks,
Relja Ljubobratovic




Re: std.conv.to!string(array), strange compile error

2015-11-14 Thread anonymous via Digitalmars-d-learn

On 14.11.2015 15:40, Relja wrote:

float[3] array;
array.to!string; // compiles


Alright, full test case:


import std.conv;

float[3] getFloat3() {
return [1, 2, 3];
}

void main() {
getFloat3().to!string; // does not compile
float[3] a;
a.to!string; // compiles
}


Yeah, that's odd.

Looking at std.conv, `to` is this [1]:


template to(T)
{
T to(A...)(A args)
if (!isRawStaticArray!A)
{
return toImpl!T(args);
}

// Fix issue 6175
T to(S)(ref S arg)
if (isRawStaticArray!S)
{
return toImpl!T(arg);
}
}


So static arrays are taken by reference. That explains why return values 
from functions are rejected: they're rvalues and can't be passed by 
reference.


Apparently, that oddity is a fix for issue 6175 [2] which seems to be 
about `to` returning a slice of a local variable (which is bad). I don't 
know the details of the issue or the fix, but I've got a feeling that 
there must be a better fix.


Taking the data by reference, but otherwise doing the same as before 
would mean that `to` simply slices a static array when asked to make a 
dynamic array of it, rather than copying the data. And indeed, that 
seems to be the case:



float[] f()
{
import std.conv;
float[3] a = [1, 2, 3];
return a.to!(float[]);
}
void main()
{
auto a = f();
import std.stdio;
writeln(a); /* prints garbage */
}


I don't know if that's considered acceptable. I'm not a fan.

[1] 
https://github.com/D-Programming-Language/phobos/blob/48d57e36e74379291a52087fcd1aa0dc19ff9a70/std/conv.d#L293-L307

[2] https://issues.dlang.org/show_bug.cgi?id=6175


Re: std.conv.to!string(array), strange compile error

2015-11-14 Thread Relja via Digitalmars-d-learn

On Saturday, 14 November 2015 at 18:52:54 UTC, anonymous wrote:

On 14.11.2015 15:40, Relja wrote:

[...]


Alright, full test case:


import std.conv;

[...]


Great explanation! Thank you!


Struct toString works but not std.conv.to!string

2015-10-13 Thread Nordlöw via Digitalmars-d-learn

I have defined a struct UTCOffset in

https://github.com/nordlow/justd/blob/master/datetime_ex.d

Everything works as desired except for

import std.conv : to;
assert(UTCOffset(+14, 0).to!string == "UTC+14:00");

which fails as

/usr/include/dmd/phobos/std/conv.d(293,14): Error: template 
instance isRawStaticArray!() does not match template declaration 
isRawStaticArray(T, A...)
datetime_ex.d(129,29): Error: cannot resolve type for 
UTCOffset(cast(ubyte)0u).this(cast(byte)14, 
cast(ubyte)0u).to!string


I don't understand what's wrong.


Re: Struct toString works but not std.conv.to!string

2015-10-13 Thread Jonathan M Davis via Digitalmars-d-learn
On Tuesday, October 13, 2015 21:07:07 Nordlöw via Digitalmars-d-learn wrote:
> I have defined a struct UTCOffset in
>
> https://github.com/nordlow/justd/blob/master/datetime_ex.d
>
> Everything works as desired except for
>
>  import std.conv : to;
>  assert(UTCOffset(+14, 0).to!string == "UTC+14:00");
>
> which fails as
>
> /usr/include/dmd/phobos/std/conv.d(293,14): Error: template
> instance isRawStaticArray!() does not match template declaration
> isRawStaticArray(T, A...)
> datetime_ex.d(129,29): Error: cannot resolve type for
> UTCOffset(cast(ubyte)0u).this(cast(byte)14,
> cast(ubyte)0u).to!string
>
> I don't understand what's wrong.

Just glancing at your code, you've marked toString with @property, which is
kind of a weird thing to do, nd if we ever make @property enforce that it's
not called with parens, then that code won't work. So, you might try moving
that @property: to after toString and see if that fixes your problem. But
given the error, my guess is that the problem relates to the fact that you
templatized the constructor, which is often problematic, and whatever type
introspection std.conv.to is doing could be choking on that. So, you should
probably try making it so that the constructor isn't templatized and see if
that fixes the problem.

- Jonathan M Davis




Re: Struct toString works but not std.conv.to!string

2015-10-13 Thread Ali Çehreli via Digitalmars-d-learn

On 10/13/2015 02:07 PM, Nordlöw wrote:

I have defined a struct UTCOffset in

https://github.com/nordlow/justd/blob/master/datetime_ex.d

Everything works as desired except for

 import std.conv : to;
 assert(UTCOffset(+14, 0).to!string == "UTC+14:00");

which fails as

/usr/include/dmd/phobos/std/conv.d(293,14): Error: template instance
isRawStaticArray!() does not match template declaration
isRawStaticArray(T, A...)
datetime_ex.d(129,29): Error: cannot resolve type for
UTCOffset(cast(ubyte)0u).this(cast(byte)14, cast(ubyte)0u).to!string

I don't understand what's wrong.


Reduced with a workaround:

struct UTCOffset
{
import std.conv : to;// Move to module scope to compile

string toString() const
{
return "hello";
}
}

void main() {
import std.conv : to;
UTCOffset().to!string;
}

This is an issue that I know to be known. :) I think it is about private 
definitions (isRawStaticArray) of modules not working outside? or when 
in inner scopes? Something like that...


Ali



Re: Struct toString works but not std.conv.to!string

2015-10-13 Thread anonymous via Digitalmars-d-learn

On Tuesday, 13 October 2015 at 22:21:43 UTC, Ali Çehreli wrote:

Reduced with a workaround:

struct UTCOffset
{
import std.conv : to;// Move to module scope to compile


This introduces UTCOffset.to as an alias to std.conv.to.


string toString() const
{
return "hello";
}
}

void main() {
import std.conv : to;


This ends up being ignored, because UTCOffset has a member called 
`to`.



UTCOffset().to!string;


This does not do call std.conv.to through UFCS. Instead, it calls 
UTCOffset's static alias of std.conv.to without an argument.


That is: `UTCOffset().to!string;` = `UTCOffset.to!string;` = 
`std.conv.to!string;`



}




Re: Struct toString works but not std.conv.to!string

2015-10-13 Thread Nordlöw via Digitalmars-d-learn
On Tuesday, 13 October 2015 at 21:50:54 UTC, Jonathan M Davis 
wrote:
Just glancing at your code, you've marked toString with 
@property, which is kind of a weird thing to do, nd if we ever 
make @property enforce that it's not called with parens, then 
that code won't work. So, you might try moving that @property: 
to after toString and see if that fixes your problem. But given 
the error, my guess is that the problem relates to the fact 
that you templatized the constructor, which is often 
problematic, and whatever type introspection std.conv.to is 
doing could be choking on that. So, you should probably try 
making it so that the constructor isn't templatized and see if 
that fixes the problem.


- Jonathan M Davis


None of you advice helped.

Fortunately I found a solution:

If I move

import std.conv : to;

into the function scopes

the problem goes away.

Thanks, anyway, for you time.


Re: Purity of std.conv.to!string

2015-09-28 Thread Nordlöw via Digitalmars-d-learn

On Sunday, 27 September 2015 at 05:52:26 UTC, Jack Stouffer wrote:
Please make an issue on https://issues.dlang.org and I'll take 
a look a this later. Most of the functions in std.conv are 
templated so it must be some internal function that's not 
properly annotated, or it's using manual memory management.


Already file here:

https://issues.dlang.org/show_bug.cgi?id=3437
https://issues.dlang.org/show_bug.cgi?id=4850


Re: Purity of std.conv.to!string

2015-09-27 Thread Daniel Murphy via Digitalmars-d-learn

On 27/09/2015 3:14 AM, cym13 wrote:

On Saturday, 26 September 2015 at 17:08:00 UTC, Nordlöw wrote:

Why is the following code not pure:

float x = 3.14;
import std.conv : to;
auto y = x.to!string;


???

Is there a reason for it not being pure? If not, this is a serious
problem as this is such a fundamental function.


Probably because it uses C's float formatting functions, and they 
probably set errno and therefore aren't pure.




Maybe because of floating point numbers uncertainty that would cause the
resulting string to be different for two equivalent inputs? I can't seem
to put an example together though.


No, it doesn't work like that.


Re: Purity of std.conv.to!string

2015-09-26 Thread Xinok via Digitalmars-d-learn

On Saturday, 26 September 2015 at 17:08:00 UTC, Nordlöw wrote:

Why is the following code not pure:

float x = 3.14;
import std.conv : to;
auto y = x.to!string;


???

Is there a reason for it not being pure? If not, this is a 
serious problem as this is such a fundamental function.


I don't know the exact reason but I found a couple of functions 
which could be marked pure which are not, including 
strippedOctalLiteral and isOctalLiteralString. It's possible that 
some function was simply overlooked and needs to be marked pure 
or infer purity.


The larger issue at hand is that the compiler doesn't tell you 
where an impurity lies, merely that it exists. I mentioned this 
issue not too long ago while experiencing my own difficulties 
respecting purity.


Re: Purity of std.conv.to!string

2015-09-26 Thread cym13 via Digitalmars-d-learn

On Saturday, 26 September 2015 at 17:08:00 UTC, Nordlöw wrote:

Why is the following code not pure:

float x = 3.14;
import std.conv : to;
auto y = x.to!string;


???

Is there a reason for it not being pure? If not, this is a 
serious problem as this is such a fundamental function.


Maybe because of floating point numbers uncertainty that would 
cause the resulting string to be different for two equivalent 
inputs? I can't seem to put an example together though.




Purity of std.conv.to!string

2015-09-26 Thread Nordlöw via Digitalmars-d-learn

Why is the following code not pure:

float x = 3.14;
import std.conv : to;
auto y = x.to!string;


???

Is there a reason for it not being pure? If not, this is a 
serious problem as this is such a fundamental function.


Re: Purity of std.conv.to!string

2015-09-26 Thread Jack Stouffer via Digitalmars-d-learn

On Saturday, 26 September 2015 at 17:08:00 UTC, Nordlöw wrote:

Why is the following code not pure:

float x = 3.14;
import std.conv : to;
auto y = x.to!string;


???

Is there a reason for it not being pure? If not, this is a 
serious problem as this is such a fundamental function.


Please make an issue on https://issues.dlang.org and I'll take a 
look a this later. Most of the functions in std.conv are 
templated so it must be some internal function that's not 
properly annotated, or it's using manual memory management.


Re: Fuzzy Levenshtein variant of std.conv.to

2015-04-29 Thread via Digitalmars-d-learn

On Tuesday, 28 April 2015 at 23:09:27 UTC, Per Nordlöw wrote:

On Tuesday, 28 April 2015 at 16:20:24 UTC, Per Nordlöw wrote:

I update my Github repo. I had forgotten to push my latest 
changes.


I solved it.


Re: Fuzzy Levenshtein variant of std.conv.to

2015-04-29 Thread Jakob Ovrum via Digitalmars-d-learn

On Wednesday, 29 April 2015 at 14:46:04 UTC, Per Nordlöw wrote:

On Tuesday, 28 April 2015 at 23:09:27 UTC, Per Nordlöw wrote:

On Tuesday, 28 April 2015 at 16:20:24 UTC, Per Nordlöw wrote:

I update my Github repo. I had forgotten to push my latest 
changes.


I solved it.


I started working on this yesterday before you solved it, and 
ended up finishing a solution. It was a fun excercise, thanks.


https://gist.github.com/JakobOvrum/515737710619a9d97273

It uses a loop instead of a range composition because of the 
early return when the Levenshtein distance is 0; that would be 
clumsy to express with ranges.


Re: Fuzzy Levenshtein variant of std.conv.to

2015-04-28 Thread via Digitalmars-d-learn

On Tuesday, 28 April 2015 at 16:20:24 UTC, Per Nordlöw wrote:

I update my Github repo. I had forgotten to push my latest 
changes.


Fuzzy Levenshtein variant of std.conv.to

2015-04-28 Thread via Digitalmars-d-learn

At

https://github.com/nordlow/justd/blob/master/conv_ex.d

I'm trying to figure out how to best implement a fuzzy variant of 
std.conv.to when converting a string to an enum.


I'm almost there but I'm uncertain how to best pick the index of 
the smallest element in `distances` and then convert it to the 
corresponding enumerator for when `U` is an enum.


Help please.


opCast and std.conv.to

2015-02-22 Thread via Digitalmars-d-learn
I tried to override the opCast operator in a class to be able to 
explicitly convert the class to a string, but to!string just 
returns the name of the class.
Do opCast and to! together not work with strings and does that 
mean that i have to use alias this?


Re: opCast and std.conv.to

2015-02-22 Thread Adam D. Ruppe via Digitalmars-d-learn

On Sunday, 22 February 2015 at 13:04:56 UTC, Jacques Müller wrote:
I tried to override the opCast operator in a class to be able 
to explicitly convert the class to a string, but to!string just 
returns the name of the class.


to!string actually forwards to a special function, string 
toString() {} which you'll need to implement and override from 
the base class.


It might need to be const too

override string toString() const { }

the compiler will tell you.


Re: opCast and std.conv.to

2015-02-22 Thread via Digitalmars-d-learn

On Sunday, 22 February 2015 at 13:15:31 UTC, Adam D. Ruppe wrote:
to!string actually forwards to a special function, string 
toString() {} which you'll need to implement and override from 
the base class.


Thanks, that's good to know.
I was just wondering why my code wasn't working correctly.



Re: std.conv.to purity

2015-02-14 Thread ketmar via Digitalmars-d-learn
On Sat, 14 Feb 2015 11:29:28 +, Jack Applegame wrote:

 why std.conv.to is not pure?
 
 string foo(real v) pure { return v.to!string; }
 // Error: pure function 'foo' cannot call impure function
 'std.conv.to!string.to!(real).to'

'cause float-string conversion is damned hard task. to perform this 
conversion `to!` falls back to `formatValue` from std.format, which in 
turn using `snprintf()` from libc.

signature.asc
Description: PGP signature


std.conv.to purity

2015-02-14 Thread Jack Applegame via Digitalmars-d-learn

why std.conv.to is not pure?

string foo(real v) pure { return v.to!string; }
// Error: pure function 'foo' cannot call impure function 
'std.conv.to!string.to!(real).to'


Re: std.conv.to purity

2015-02-14 Thread Gary Willoughby via Digitalmars-d-learn

On Saturday, 14 February 2015 at 12:24:51 UTC, ketmar wrote:

On Sat, 14 Feb 2015 11:29:28 +, Jack Applegame wrote:


why std.conv.to is not pure?

string foo(real v) pure { return v.to!string; }
// Error: pure function 'foo' cannot call impure function
'std.conv.to!string.to!(real).to'


'cause float-string conversion is damned hard task. to perform 
this
conversion `to!` falls back to `formatValue` from std.format, 
which in

turn using `snprintf()` from libc.


Forgive me being a bit dense but that doesn't necessarily mean 
it's impure though, right?


Re: std.conv.to purity

2015-02-14 Thread ketmar via Digitalmars-d-learn
On Sat, 14 Feb 2015 19:59:58 +, Gary Willoughby wrote:

 On Saturday, 14 February 2015 at 12:24:51 UTC, ketmar wrote:
 On Sat, 14 Feb 2015 11:29:28 +, Jack Applegame wrote:

 why std.conv.to is not pure?
 
 string foo(real v) pure { return v.to!string; }
 // Error: pure function 'foo' cannot call impure function
 'std.conv.to!string.to!(real).to'

 'cause float-string conversion is damned hard task. to perform this
 conversion `to!` falls back to `formatValue` from std.format,
 which in turn using `snprintf()` from libc.
 
 Forgive me being a bit dense but that doesn't necessarily mean it's
 impure though, right?

yes, you are right, it *may* be pure. yet `snprintf()` can't be marked as 
`pure`, so it contaminates everything. and there are no guarantees that 
`snprintf()` is pure even for known arguments (compiler can't prove that, 
and libc is free to do any funny things in it), so it will be wrong to 
just force-reimport it as `pure`.

tl;dr: we need native D float-string converter to allow purity in this 
case. you are free to force-hack purity flag on function if you want, but 
this can be wrong and may lead to various heisenbugs.

native pure D converter will also allow CTFE, btw, which is impossible 
now.

signature.asc
Description: PGP signature


Re: std.conv.to purity

2015-02-14 Thread Brad Roberts via Digitalmars-d-learn
While snprintf might be one thing that provides to be an interesting 
obstacle, the better answer to why std.conv.to isnt pure is that no one 
has invested the time to work through issues like that to make it so. 
It _should_ be pure.


On 2/14/2015 12:32 PM, ketmar via Digitalmars-d-learn wrote:

On Sat, 14 Feb 2015 19:59:58 +, Gary Willoughby wrote:


On Saturday, 14 February 2015 at 12:24:51 UTC, ketmar wrote:

On Sat, 14 Feb 2015 11:29:28 +, Jack Applegame wrote:


why std.conv.to is not pure?

string foo(real v) pure { return v.to!string; }
// Error: pure function 'foo' cannot call impure function
'std.conv.to!string.to!(real).to'


'cause float-string conversion is damned hard task. to perform this
conversion `to!` falls back to `formatValue` from std.format,
which in turn using `snprintf()` from libc.


Forgive me being a bit dense but that doesn't necessarily mean it's
impure though, right?


yes, you are right, it *may* be pure. yet `snprintf()` can't be marked as
`pure`, so it contaminates everything. and there are no guarantees that
`snprintf()` is pure even for known arguments (compiler can't prove that,
and libc is free to do any funny things in it), so it will be wrong to
just force-reimport it as `pure`.

tl;dr: we need native D float-string converter to allow purity in this
case. you are free to force-hack purity flag on function if you want, but
this can be wrong and may lead to various heisenbugs.

native pure D converter will also allow CTFE, btw, which is impossible
now.



std.conv.to vs. casting

2013-07-04 Thread CJS
I'm having trouble understanding the difference between casting 
and std.conv.to. Any help?


Re: std.conv.to vs. casting

2013-07-04 Thread monarch_dodra

On Thursday, 4 July 2013 at 06:18:21 UTC, CJS wrote:
I'm having trouble understanding the difference between casting 
and std.conv.to. Any help?


Casting merely changes the observed type, whereas to does a 
deep conversion.


Observe:


import std.stdio;
import std.conv;

void main()
{
int[] ints  = [1, 2, 3];
auto bytes1 = cast(ubyte[])(ints);
auto bytes2 = to!(ubyte[])(ints);
writeln(bytes1);
writeln(bytes2);
}

[1, 0, 0, 0, 2, 0, 0, 0, 3, 0, 0, 0]
[1, 2, 3]


To is very useful to do true type conversion. It can change 
string width. Finally, to is able to do string interpretation. 
EG:



import std.stdio;
import std.conv;

void main()
{
int[] ints  = to!(int[])([1, 2, 3]);
writeln(ints);
}

[1, 2, 3]


To is very convenient because it is a one stop shop: It doesn't 
matter what you want to do: to will do it. You don't need to 
mix/match calls to atoi/itoa/encode/decode etc. Furthermore, it 
is safe: if anything fails, to will throw. It will also throw if 
you overflow:



import std.conv;

void main()
{
int a = 500;
ubyte b = cast(ubyte)(a); //No problem here: Silent overflow
ubyte c = to!ubyte(a);//Runtime overflow exception
}


Hope that helps :)


Re: std.conv.to vs. casting

2013-07-04 Thread Joseph Rushton Wakeling
On 07/04/2013 10:14 AM, monarch_dodra wrote:
 Casting merely changes the observed type, whereas to does a deep 
 conversion.

What are the speed implications of to compared to cast?

I ask because I see various casts in Phobos, and wonder if there isn't improved
safety in preferring instead to use to, so long as the optimal speed is there
with appropriate compiler optimizations.

I'm particularly concerned here because of a bug I observed that would have been
caught if to had been used rather than cast:
http://d.puremagic.com/issues/show_bug.cgi?id=10322#c4

(I'm working on a fix, it's just time constraints that have delayed delivering 
it:-)


Re: std.conv.to vs. casting

2013-07-04 Thread monarch_dodra
On Thursday, 4 July 2013 at 09:31:42 UTC, Joseph Rushton Wakeling 
wrote:

On 07/04/2013 10:14 AM, monarch_dodra wrote:
Casting merely changes the observed type, whereas to does 
a deep conversion.


What are the speed implications of to compared to cast?

I ask because I see various casts in Phobos, and wonder if 
there isn't improved
safety in preferring instead to use to, so long as the optimal 
speed is there

with appropriate compiler optimizations.

I'm particularly concerned here because of a bug I observed 
that would have been

caught if to had been used rather than cast:
http://d.puremagic.com/issues/show_bug.cgi?id=10322#c4

(I'm working on a fix, it's just time constraints that have 
delayed delivering it:-)


Speed implications, it mostly only means doing an if (a  
T.max). It also means adding code to handle a throw. Finally, it 
means the function can't be marked nothrow.


I'd argue that to should really only be used for legitimate 
cases where the runtime can create out of range values, and you 
want to catch that as an exception. Speed should not be a real 
issue*.


I didn't go into the details, but in your bug report, it seems 
like it is more of an implementation error ? In that case, an 
ERROR would be better.


*Speed wise, it is not a problem I'd say, except maybe in range 
primitives, espcially empty, front and opIndex, and to a certain, 
popFront. It depends on the relative cost of the operation of 
course.


For example: Cycle provides RA indexing. the code is written as:
return source[(currentIndex + inputIndex) % length];

In this specific case, there is an overflow risk, even though RA 
access should be un-bounded. However, it is not checked, as the 
implications to calling to would be problematic. Placing an 
assert there is better, so release does not have to pay for the 
check.


Re: std.conv.to vs. casting

2013-07-04 Thread Joseph Rushton Wakeling
On Thursday, 4 July 2013 at 10:32:26 UTC, Joseph Rushton Wakeling 
wrote:
I can prepare a reduced example but it's probably simpler for 
me to just prepare a bugfix and do some benchmarks.


By the way, CJS -- sorry to have hijacked your query.  But I 
think you had your answer already :-)


Re: std.conv.to vs. casting

2013-07-04 Thread Joseph Rushton Wakeling

On Thursday, 4 July 2013 at 10:23:22 UTC, monarch_dodra wrote:
I'm trying to read the bug entry, but I don't get it. Maybe a 
reduced case to explain?


Point is, the skip() function in std.random.RandomSample can be 
called with the floating-point variable _Vprime equal to nan, 
_if_ popFront() or index() are called before front().


If isNan(_Vprime)  !_algorithmA then skip() will generate 
incorrect results.


I was asking about the speed of isNan compared to if(boolean) 
because I was considering killing the bool _first and just using 
isNan(_Vprime) to check if the first sample point has already 
been generated.


I can prepare a reduced example but it's probably simpler for me 
to just prepare a bugfix and do some benchmarks.


Re: std.conv.to vs. casting

2013-07-04 Thread CJS


By the way, CJS -- sorry to have hijacked your query.  But I 
think you had your answer already :-)


Yes. It was a very helpful answer. I'm just glad the question I 
asked was apparently relevant to other users as well.


Re: std.conv.to vs. casting

2013-07-04 Thread Ali Çehreli

On 07/04/2013 03:15 AM, Joseph Rushton Wakeling wrote:

 The cast should be safe, as it's a size_t to a double.

I am commenting without fully understanding the context: Both size_t and 
double are 64 bit types on a 64-bit system. double.mant_dig being 53, 
converting from size_t to double loses information for many values.


import std.stdio;
import std.conv;

void main()
{
size_t i = 0x8000___0001;
double d0 = i.to!double;
double d1 = cast(double)i;

writefln(%s, i);
writefln(%f, d0);
writefln(%f, d1);
}

Prints

9223372036854775809
9223372036854775808.00
9223372036854775808.00

Still, the same information loss in a comparison may make one think that 
it actually worked! :p


assert(d0 == i);// passes!
assert(d1 == i);// passes!

Ali



Re: std.conv.to vs. casting

2013-07-04 Thread H. S. Teoh
On Thu, Jul 04, 2013 at 06:43:16PM +0200, Joseph Rushton Wakeling wrote:
 On 07/04/2013 06:16 PM, Ali Çehreli wrote:
  I am commenting without fully understanding the context: Both size_t
  and double are 64 bit types on a 64-bit system. double.mant_dig
  being 53, converting from size_t to double loses information for
  many values.
 
 Oh, bugger.  You mean that because it needs space to store the
 exponent, it has a reduced number of significant figures compared to
 size_t?
[...]

Yes. See:

http://en.wikipedia.org/wiki/Double-precision_floating-point_format

Of the 64 bits, only 53 are available for storing the mantissa (well,
actually 52, but the first bit is always 1 except when the exponent is
zero so it's not stored -- you get it for free). Of the remaining bits,
11 are reserved for storing the exponent, and the last for storing the
sign.

So the maximum precision a double can have is 53 bits. If you have a
value that requires more than that, the representation will be inexact.


T

-- 
Programming is not just an act of telling a computer what to do: it is
also an act of telling other programmers what you wished the computer to
do. Both are important, and the latter deserves care. -- Andrew Morton


Re: std.conv.to vs. casting

2013-07-04 Thread monarch_dodra

On Thursday, 4 July 2013 at 16:16:08 UTC, Ali Çehreli wrote:

On 07/04/2013 03:15 AM, Joseph Rushton Wakeling wrote:

 The cast should be safe, as it's a size_t to a double.

I am commenting without fully understanding the context: Both 
size_t and double are 64 bit types on a 64-bit system. 
double.mant_dig being 53, converting from size_t to double 
loses information for many values.


It's not about losing information, it's about being out of range.

For example, to!float(2.0^^50) will throw an exception.


Re: std.conv.to can't convert to bool?

2011-03-28 Thread Jesse Phillips
Andrej Mitrovic Wrote:

 Wow not a minute later and I get bitten by my own solution. A C
 function returned 1 for a supported feature, and -1 otherwise. And of
 course -1 got converted to true, so then I had a bug in my code.
 
 Damn silly C functions which return -1 when they should return 0.
 
 Or damn me for not RTFM'ing.

Yeah, so the reason it doesn't do that conversion is because it will bite you.

Actually D already uses non-zero as true. Why do you need to cast it?


std.conv.to can't convert to bool?

2011-03-27 Thread Andrej Mitrovic
import std.stdio;
import std.conv : to;

void main()
{
uint state = 1;
writeln( to!bool(state) );
}

D:\DMD\dmd2\windows\bin\..\..\src\phobos\std\conv.d(99): Error: template 
std.conv.toImpl(T,S) if (!implicitlyConverts!(S,T)  isSomeString!(T)  
isInputRange!(Unqual!(S))  isSomeChar!(ElementType!(S))) does not match any 
function template declaration
D:\DMD\dmd2\windows\bin\..\..\src\phobos\std\conv.d(99): Error: template 
std.conv.toImpl(T,S) if (!implicitlyConverts!(S,T)  isSomeString!(T)  
isInputRange!(Unqual!(S))  isSomeChar!(ElementType!(S))) cannot deduce 
template function from argument types !(bool)(uint)
D:\DMD\dmd2\windows\bin\..\..\src\phobos\std\conv.d(99): Error: template 
instance errors instantiating template
boolConv.d(9): Error: template instance std.conv.to!(bool).to!(uint) error 
instantiating

What's the big problem with converting an int/uint to bool? I'm using a cast 
for now.


Re: std.conv.to can't convert to bool?

2011-03-27 Thread Andrej Mitrovic
Wow not a minute later and I get bitten by my own solution. A C
function returned 1 for a supported feature, and -1 otherwise. And of
course -1 got converted to true, so then I had a bug in my code.

Damn silly C functions which return -1 when they should return 0.

Or damn me for not RTFM'ing.