Re: Add support implicit conversion between types

2013-09-08 Thread Simen Kjaeraas

On 2013-09-07, 15:19, ilya-stromberg wrote:


On Saturday, 7 September 2013 at 13:02:39 UTC, Simen Kjaeraas wrote:

It's a bit weird in D though, as operators are instance methods, and
opImplicitRightCast (or opImplicitCastFrom, which is the name used in
discussions before, see WalterAndrei.pdf from back when dinosaurs  
roamed the

earth) should definitely not be an instance method but a static one.

That said, I belive opImplicitCastFrom is The Right Solution™. It's  
explicit,

it's a bit ugly, but not so much it hurts.


Yes, opImplicitCastFrom looks better. I didn't know about  
WalterAndrei.pdf file. Can you give me a link to the file? It's  
intresting to read.


http://s3.amazonaws.com/dconf2007/WalterAndrei.pdf

It's from the D conference back in 2007, as the URL indicates.

opImplicitCastFrom is mentioned on page 22. It's kinda interesting
to see what was happening back then and how things have progressed.


--
  Simen


Re: Add support implicit conversion between types

2013-09-07 Thread Simen Kjaeraas

On 2013-09-06, 19:12, Dmitry Olshansky wrote:


06-Sep-2013 21:05, H. S. Teoh пишет:

On Fri, Sep 06, 2013 at 05:14:48PM +0200, ilya-stromberg wrote:

On Friday, 6 September 2013 at 14:26:17 UTC, H. S. Teoh wrote:

I thought the usual D idiom was to write factorial(5) and
factorial(BigInt(5)) and let the compiler figure out which template
instance you wanted?


Yes, but it isn't always possible.


It can be critical for more complex cases, when you call one generic
function from another one, like this:

unittest
{
   alias TypeTuple!(byte, ubyte, short, ushort, int, uint, long,
ulong, BigInt) IntegralTypeList;

   foreach(T; IntegralTypeList)
   {
  assert(factorial!T(3) == 6);//Error: factorial (BigInt
number)
is not callable using argument types (int)


You could just write factorial(T(3)) ?


No, I have the error:
Error: function expected before (), not byte of type byte
Error: function expected before (), not ubyte of type ubyte
Error: function expected before (), not short of type short
Error: function expected before (), not ushort of type ushort
Error: function expected before (), not int of type int
Error: function expected before (), not uint of type uint
Error: function expected before (), not long of type long
Error: function expected before (), not ulong of type ulong

As monarch_dodra pointed above, we haven't got uniform
construction support.


Hmm, I see. This is an unfortunate limitation. In C++, writing int(123)
actually works. Looks like D is lacking in this area. :-(


I swear I've seen a pull request that enables it.


This one?

https://github.com/D-Programming-Language/dmd/pull/1356

It seems to be on its way.

--
  Simen


Re: Add support implicit conversion between types

2013-09-07 Thread Simen Kjaeraas

On 2013-09-06, 15:57, ilya-stromberg wrote:


On Friday, 6 September 2013 at 13:39:20 UTC, deadalnix wrote:
You don't want a keyword for that. Something obscure and ugly is  
required.


C# have operator overloading for this.

We can use, for example, opImplicitRightCast

struct Foo
{
Foo opImplicitRightCast(T)(T from);
}


It's a bit weird in D though, as operators are instance methods, and
opImplicitRightCast (or opImplicitCastFrom, which is the name used in
discussions before, see WalterAndrei.pdf from back when dinosaurs roamed  
the

earth) should definitely not be an instance method but a static one.

That said, I belive opImplicitCastFrom is The Right Solution™. It's  
explicit,

it's a bit ugly, but not so much it hurts.

--
  Simen


Re: Add support implicit conversion between types

2013-09-07 Thread ilya-stromberg
On Saturday, 7 September 2013 at 13:02:39 UTC, Simen Kjaeraas 
wrote:
It's a bit weird in D though, as operators are instance 
methods, and
opImplicitRightCast (or opImplicitCastFrom, which is the name 
used in
discussions before, see WalterAndrei.pdf from back when 
dinosaurs roamed the
earth) should definitely not be an instance method but a static 
one.


That said, I belive opImplicitCastFrom is The Right Solution™. 
It's explicit,

it's a bit ugly, but not so much it hurts.


Yes, opImplicitCastFrom looks better. I didn't know about 
WalterAndrei.pdf file. Can you give me a link to the file? It's 
intresting to read.


In C# this operator is static:

class Foo {
   public Foo(int temp)
   {
   }

   public static implicit operator Foo(int temp) {
  return new Foo(temp);
   }
}

So, I agree, the opImplicitCastFrom should be also static.


Re: Add support implicit conversion between types

2013-09-07 Thread Peter Alexander

On Friday, 6 September 2013 at 13:15:21 UTC, Benjamin Thaut wrote:

Am 06.09.2013 15:01, schrieb Dicebot:
Probably. But what is the gain? `foo(Foo(5))` looks better 
than `foo(5)`

to me in every possible way.

For example, use case that justifies operator overloading 
(despite the
danger) in my eyes is ability to replace built-in types with 
custom

ones. What is the similar rationale for implicit conversion?


Try implementing a custom string class in D that does not 
depend on the GC and you will know. Your code will be littered 
with explict constructions of strings, which makes it look 
totally ugly.


Could you not just implement a .str property that does the 
conversion? Surely littering code with .str isn't too ugly?


I understand the desire for it, but implicit coercions truly are 
evil.


Re: Add support implicit conversion between types

2013-09-07 Thread Maxim Fomin

On Friday, 6 September 2013 at 10:33:07 UTC, ilya-stromberg wrote:
Do you have any plans to support implicit conversion between 
types?


I have some code like this:

struct Foo
{
this(int i)
{
//do something useful
}
}

void bar(Foo f)
{
//do something else
}

void main()
{
Foo f = 5;//works

bar(f);//works

bar(Foo(5));//works

bar(5);//Error: function app.bar (Foo f) is not callable using
argument types (int)
}



Actually D has this feature for classes:

class A
{
this(int) {}
}

void foo(A a ...) {}

void main()
{
foo(5);
}

This compiles and runs as expected. By the way, the code was 
fixed recently - before 2.063 this was allocating class on stack 
(so in D there were some kind of scoped stack classes), now this 
allocates on heap as usual. I don't see the rationale behind not 
working with structs.




Re: Add support implicit conversion between types

2013-09-07 Thread monarch_dodra

On Saturday, 7 September 2013 at 19:37:28 UTC, Maxim Fomin wrote:

Actually D has this feature for classes:

class A
{
this(int) {}
}

void foo(A a ...) {}

void main()
{
foo(5);
}

This compiles and runs as expected. By the way, the code was 
fixed recently - before 2.063 this was allocating class on 
stack (so in D there were some kind of scoped stack classes), 
now this allocates on heap as usual. I don't see the rationale 
behind not working with structs.


I don't see the rationale for it working for classes at all!


Re: Add support implicit conversion between types

2013-09-07 Thread Ramon
I understand and support Kenjis request (linked in this thread) 
in the no casting, though version.


And I find C++ or C# or Foo2k has this! a very troublesome 
approach and measure.
Whatever feature is introducing inconsistencies is almost never 
worth it.


We do have explicit conversion. If anyone feels that to look ugly 
he should ask what's worse, language inconsistencies or looks.


A+ -R


Add support implicit conversion between types

2013-09-06 Thread ilya-stromberg
Do you have any plans to support implicit conversion between 
types?


I have some code like this:

struct Foo
{
this(int i)
{
//do something useful
}
}

void bar(Foo f)
{
//do something else
}

void main()
{
Foo f = 5;//works

bar(f);//works

bar(Foo(5));//works

bar(5);//Error: function app.bar (Foo f) is not callable using
argument types (int)
}

So, D can't use constructor to convert int to Foo implicitly.
Can we add implicit keyword to allow do this:

struct Foo
{
implicit this(int i)
{
//do something useful
}
}

C++ allows this, but have explicit keyword.
C# doesn't allow this, but have operator overloading for both 
implicit and explicit cases.


Re: Add support implicit conversion between types

2013-09-06 Thread Benjamin Thaut

Am 06.09.2013 12:33, schrieb ilya-stromberg:

Do you have any plans to support implicit conversion between types?

I have some code like this:

struct Foo
{
 this(int i)
 {
 //do something useful
 }
}

void bar(Foo f)
{
 //do something else
}

void main()
{
 Foo f = 5;//works

 bar(f);//works

 bar(Foo(5));//works

 bar(5);//Error: function app.bar (Foo f) is not callable using
argument types (int)
}

So, D can't use constructor to convert int to Foo implicitly.
Can we add implicit keyword to allow do this:

struct Foo
{
 implicit this(int i)
 {
 //do something useful
 }
}

C++ allows this, but have explicit keyword.
C# doesn't allow this, but have operator overloading for both implicit
and explicit cases.


I also made almost the same suggestion some time ago. I would support a 
feature like this.


--
Kind Regards
Benjamin Thaut


Re: Add support implicit conversion between types

2013-09-06 Thread Peter Alexander

On Friday, 6 September 2013 at 10:33:07 UTC, ilya-stromberg wrote:
Do you have any plans to support implicit conversion between 
types?


Implicit conversions open up a whole can of worms for the sake of 
a small amount of convenience.


I'm not sure it's a fair trade.


Re: Add support implicit conversion between types

2013-09-06 Thread Dicebot
On Friday, 6 September 2013 at 11:04:31 UTC, Peter Alexander 
wrote:
Implicit conversions open up a whole can of worms for the sake 
of a small amount of convenience.


I'm not sure it's a fair trade.


Agreed. It was quite common source of troubles in my C++ days and 
have never offered much convenience.


Re: Add support implicit conversion between types

2013-09-06 Thread Benjamin Thaut

Am 06.09.2013 13:27, schrieb Dicebot:

On Friday, 6 September 2013 at 11:04:31 UTC, Peter Alexander wrote:

Implicit conversions open up a whole can of worms for the sake of a
small amount of convenience.

I'm not sure it's a fair trade.


Agreed. It was quite common source of troubles in my C++ days and have
never offered much convenience.


Its only a source of troubles in C++ because it is the default behavior. 
But if you design a library it can make the usage of your api easier and 
also you have a few more options to stay backwards compatible with your 
old api.


Re: Add support implicit conversion between types

2013-09-06 Thread deadalnix
On Friday, 6 September 2013 at 11:04:31 UTC, Peter Alexander 
wrote:
On Friday, 6 September 2013 at 10:33:07 UTC, ilya-stromberg 
wrote:
Do you have any plans to support implicit conversion between 
types?


Implicit conversions open up a whole can of worms for the sake 
of a small amount of convenience.


I'm not sure it's a fair trade.


I think we should be able to do it, but in unconvenient ways.

Like alias this + a property.


Re: Add support implicit conversion between types

2013-09-06 Thread Benjamin Thaut

Am 06.09.2013 13:44, schrieb deadalnix:

On Friday, 6 September 2013 at 11:04:31 UTC, Peter Alexander wrote:

On Friday, 6 September 2013 at 10:33:07 UTC, ilya-stromberg wrote:

Do you have any plans to support implicit conversion between types?


Implicit conversions open up a whole can of worms for the sake of a
small amount of convenience.

I'm not sure it's a fair trade.


I think we should be able to do it, but in unconvenient ways.

Like alias this + a property.


But that doesn't work for construction. Also its not possible to do it 
for primitive types (especially string comes to mind)


Re: Add support implicit conversion between types

2013-09-06 Thread ilya-stromberg

On Friday, 6 September 2013 at 11:32:11 UTC, Benjamin Thaut wrote:

Am 06.09.2013 13:27, schrieb Dicebot:
On Friday, 6 September 2013 at 11:04:31 UTC, Peter Alexander 
wrote:
Implicit conversions open up a whole can of worms for the 
sake of a

small amount of convenience.

I'm not sure it's a fair trade.


Agreed. It was quite common source of troubles in my C++ days 
and have

never offered much convenience.


Its only a source of troubles in C++ because it is the default 
behavior. But if you design a library it can make the usage of 
your api easier and also you have a few more options to stay 
backwards compatible with your old api.


Totally agree. The default implicit conversion in C++ is a 
mistake.


The conversion must be explicit by default (like in D now).
The programmer should use implicit conversion ONLY IF IT SAFE 
(like ftom int to long). For any other cases programmer 
should use explicit conversion (default).


Actually, this simple rule comes from C#: it have explicit 
conversions by default and ability to explicitly add implicit 
conversion. And I never had problems with it.


Re: Add support implicit conversion between types

2013-09-06 Thread Peter Alexander

On Friday, 6 September 2013 at 11:32:11 UTC, Benjamin Thaut wrote:
Its only a source of troubles in C++ because it is the default 
behavior. But if you design a library it can make the usage of 
your api easier and also you have a few more options to stay 
backwards compatible with your old api.


It's not just that single arg constructors are by default 
implicit. Implicit conversions complicate things, like template 
argument deduction and overload resolution.


Re: Add support implicit conversion between types

2013-09-06 Thread Dicebot

On Friday, 6 September 2013 at 11:32:11 UTC, Benjamin Thaut wrote:
Its only a source of troubles in C++ because it is the default 
behavior. But if you design a library it can make the usage of 
your api easier and also you have a few more options to stay 
backwards compatible with your old api.


Probably. But what is the gain? `foo(Foo(5))` looks better than 
`foo(5)` to me in every possible way.


For example, use case that justifies operator overloading 
(despite the danger) in my eyes is ability to replace built-in 
types with custom ones. What is the similar rationale for 
implicit conversion?


Re: Add support implicit conversion between types

2013-09-06 Thread Benjamin Thaut

Am 06.09.2013 15:01, schrieb Dicebot:

On Friday, 6 September 2013 at 11:32:11 UTC, Benjamin Thaut wrote:

Its only a source of troubles in C++ because it is the default
behavior. But if you design a library it can make the usage of your
api easier and also you have a few more options to stay backwards
compatible with your old api.


Probably. But what is the gain? `foo(Foo(5))` looks better than `foo(5)`
to me in every possible way.

For example, use case that justifies operator overloading (despite the
danger) in my eyes is ability to replace built-in types with custom
ones. What is the similar rationale for implicit conversion?


Try implementing a custom string class in D that does not depend on the 
GC and you will know. Your code will be littered with explict 
constructions of strings, which makes it look totally ugly.


Re: Add support implicit conversion between types

2013-09-06 Thread ilya-stromberg

On Friday, 6 September 2013 at 13:01:14 UTC, Dicebot wrote:
For example, use case that justifies operator overloading 
(despite the danger) in my eyes is ability to replace built-in 
types with custom ones. What is the similar rationale for 
implicit conversion?


For exaple, for generic code:

T factorial(T)(T number)
{
   return number = 1 ? 1 : number * factorial!T(number - 1);
}

void main()
{
   //works:
   factorial!int(5);

   //doesn't work:
   factorial!BigInt(5);
}

It can be critical for more complex cases, when you call one 
generic function from another one, like this:


unittest
{
   alias TypeTuple!(byte, ubyte, short, ushort, int, uint, long, 
ulong, BigInt) IntegralTypeList;


   foreach(T; IntegralTypeList)
   {
  assert(factorial!T(3) == 6);//Error: factorial (BigInt 
number) is not callable using argument types (int)

   }
}


Re: Add support implicit conversion between types

2013-09-06 Thread Flamaros

On Friday, 6 September 2013 at 10:33:07 UTC, ilya-stromberg wrote:
Do you have any plans to support implicit conversion between 
types?


I have some code like this:

struct Foo
{
this(int i)
{
//do something useful
}
}

void bar(Foo f)
{
//do something else
}

void main()
{
Foo f = 5;//works

bar(f);//works

bar(Foo(5));//works


I think that the good way, to do


bar(5);//Error: function app.bar (Foo f) is not callable using
argument types (int)
}

So, D can't use constructor to convert int to Foo 
implicitly.

Can we add implicit keyword to allow do this:

struct Foo
{
implicit this(int i)
{
//do something useful
}
}

C++ allows this, but have explicit keyword.
C# doesn't allow this, but have operator overloading for both 
implicit and explicit cases.



It's difficult to never forget the explicit keyword in c++, and 
this little mistake can make you loose a lot of time.


I prefer to only have explicit conversions with cast or 
constructors calls, that all make the code easier to understand.


Re: Add support implicit conversion between types

2013-09-06 Thread ilya-stromberg

On Friday, 6 September 2013 at 13:25:37 UTC, Flamaros wrote:
It's difficult to never forget the explicit keyword in c++, 
and this little mistake can make you loose a lot of time.


I prefer to only have explicit conversions with cast or 
constructors calls, that all make the code easier to understand.


Yes. I sugest keep current D bechavior by default, but add 
implicit keyword.

It allows to add implicit cast only if it SAFE.


Re: Add support implicit conversion between types

2013-09-06 Thread Dicebot

On Friday, 6 September 2013 at 13:21:44 UTC, ilya-stromberg wrote:

On Friday, 6 September 2013 at 13:01:14 UTC, Dicebot wrote:
For example, use case that justifies operator overloading 
(despite the danger) in my eyes is ability to replace built-in 
types with custom ones. What is the similar rationale for 
implicit conversion?


For exaple, for generic code:
...


So, what essentially is needed, is ability to implicitly convert 
literals of built-in types to user types, not any possible 
implicit conversion?


I think allowing it with such restrictions can be reasonably 
clean.


Re: Add support implicit conversion between types

2013-09-06 Thread deadalnix

On Friday, 6 September 2013 at 13:31:41 UTC, ilya-stromberg wrote:

On Friday, 6 September 2013 at 13:25:37 UTC, Flamaros wrote:
It's difficult to never forget the explicit keyword in c++, 
and this little mistake can make you loose a lot of time.


I prefer to only have explicit conversions with cast or 
constructors calls, that all make the code easier to 
understand.


Yes. I sugest keep current D bechavior by default, but add 
implicit keyword.

It allows to add implicit cast only if it SAFE.


You don't want a keyword for that. Something obscure and ugly is 
required.


Re: Add support implicit conversion between types

2013-09-06 Thread deadalnix

On Friday, 6 September 2013 at 13:01:14 UTC, Dicebot wrote:
On Friday, 6 September 2013 at 11:32:11 UTC, Benjamin Thaut 
wrote:
Its only a source of troubles in C++ because it is the default 
behavior. But if you design a library it can make the usage of 
your api easier and also you have a few more options to stay 
backwards compatible with your old api.


Probably. But what is the gain? `foo(Foo(5))` looks better than 
`foo(5)` to me in every possible way.




This is very convenient when dealing with unknown types. Think 
JSON manipulation for instance.


Re: Add support implicit conversion between types

2013-09-06 Thread ilya-stromberg

On Friday, 6 September 2013 at 13:30:26 UTC, Dicebot wrote:
So, what essentially is needed, is ability to implicitly 
convert literals of built-in types to user types, not any 
possible implicit conversion?


I think allowing it with such restrictions can be reasonably 
clean.


Yes, the ability to implicitly convert literals of built-in types 
to user types is REALLY needed.

The 2-nd error from factorial example

import std.bigint;

void main()
{
   assert(factorial!BigInt(BigInt(3)) == 6); //Error: 
incompatible types for ((1) : 
(number.opBinary(factorial(number.opBinary(1): 'int' and 
'BigInt'

}


The correct factorial implementation is:

T factorial(T)(T number)
{
   enum T one = 1;
   return number = one ? one : number * factorial!T(number - 
one);

}

It's complicated, how do you think?



not any possible implicit conversion?
I didn't think about yet. May be you are right, but I think it 
can be also useful. For example, if you can't change user-defined 
type.


Re: Add support implicit conversion between types

2013-09-06 Thread ilya-stromberg

On Friday, 6 September 2013 at 13:39:20 UTC, deadalnix wrote:
You don't want a keyword for that. Something obscure and ugly 
is required.


C# have operator overloading for this.

We can use, for example, opImplicitRightCast

struct Foo
{
   Foo opImplicitRightCast(T)(T from);
}


Re: Add support implicit conversion between types

2013-09-06 Thread H. S. Teoh
On Fri, Sep 06, 2013 at 03:21:42PM +0200, ilya-stromberg wrote:
 On Friday, 6 September 2013 at 13:01:14 UTC, Dicebot wrote:
 For example, use case that justifies operator overloading (despite
 the danger) in my eyes is ability to replace built-in types with
 custom ones. What is the similar rationale for implicit
 conversion?
 
 For exaple, for generic code:
 
 T factorial(T)(T number)
 {
return number = 1 ? 1 : number * factorial!T(number - 1);
 }
 
 void main()
 {
//works:
factorial!int(5);
 
//doesn't work:
factorial!BigInt(5);
 }

I thought the usual D idiom was to write factorial(5) and
factorial(BigInt(5)) and let the compiler figure out which template
instance you wanted?


 It can be critical for more complex cases, when you call one generic
 function from another one, like this:
 
 unittest
 {
alias TypeTuple!(byte, ubyte, short, ushort, int, uint, long,
 ulong, BigInt) IntegralTypeList;
 
foreach(T; IntegralTypeList)
{
   assert(factorial!T(3) == 6);//Error: factorial (BigInt number)
 is not callable using argument types (int)

You could just write factorial(T(3)) ?


T

-- 
Prosperity breeds contempt, and poverty breeds consent. -- Suck.com


Re: Add support implicit conversion between types

2013-09-06 Thread monarch_dodra

On Friday, 6 September 2013 at 13:50:25 UTC, ilya-stromberg wrote:

On Friday, 6 September 2013 at 13:30:26 UTC, Dicebot wrote:
So, what essentially is needed, is ability to implicitly 
convert literals of built-in types to user types, not any 
possible implicit conversion?


I think allowing it with such restrictions can be reasonably 
clean.


Yes, the ability to implicitly convert literals of built-in 
types to user types is REALLY needed.

The 2-nd error from factorial example

import std.bigint;

void main()
{
   assert(factorial!BigInt(BigInt(3)) == 6); //Error: 
incompatible types for ((1) : 
(number.opBinary(factorial(number.opBinary(1): 'int' and 
'BigInt'

}


The correct factorial implementation is:

T factorial(T)(T number)
{
   enum T one = 1;
   return number = one ? one : number * factorial!T(number - 
one);

}


Or just:

//
import std.bigint;

T factorial(T)(T number)
{
return number = 1 ?
T(1) :
number * factorial!T(number - 1);
}
//

The problem though is that this requires uniform construction, 
which we don't have yet:

http://d.puremagic.com/issues/show_bug.cgi?id=9112


Re: Add support implicit conversion between types

2013-09-06 Thread ilya-stromberg

On Friday, 6 September 2013 at 14:26:17 UTC, H. S. Teoh wrote:

I thought the usual D idiom was to write factorial(5) and
factorial(BigInt(5)) and let the compiler figure out which 
template

instance you wanted?


Yes, but it isn't always possible.

It can be critical for more complex cases, when you call one 
generic

function from another one, like this:

unittest
{
   alias TypeTuple!(byte, ubyte, short, ushort, int, uint, 
long,

ulong, BigInt) IntegralTypeList;

   foreach(T; IntegralTypeList)
   {
  assert(factorial!T(3) == 6);//Error: factorial (BigInt 
number)

is not callable using argument types (int)


You could just write factorial(T(3)) ?


No, I have the error:
Error: function expected before (), not byte of type byte
Error: function expected before (), not ubyte of type ubyte
Error: function expected before (), not short of type short
Error: function expected before (), not ushort of type ushort
Error: function expected before (), not int of type int
Error: function expected before (), not uint of type uint
Error: function expected before (), not long of type long
Error: function expected before (), not ulong of type ulong

As monarch_dodra pointed above, we haven't got uniform 
construction support.


Re: Add support implicit conversion between types

2013-09-06 Thread Dicebot

On Friday, 6 September 2013 at 15:14:50 UTC, ilya-stromberg wrote:

No, I have the error:
Error: function expected before (), not byte of type byte
Error: function expected before (), not ubyte of type ubyte
Error: function expected before (), not short of type short
Error: function expected before (), not ushort of type ushort
Error: function expected before (), not int of type int
Error: function expected before (), not uint of type uint
Error: function expected before (), not long of type long
Error: function expected before (), not ulong of type ulong

As monarch_dodra pointed above, we haven't got uniform 
construction support.


Yeah, this one, contrary, seems to be really crucial feature 
lacking.


Re: Add support implicit conversion between types

2013-09-06 Thread ilya-stromberg

On Friday, 6 September 2013 at 17:15:03 UTC, H. S. Teoh wrote:

Hmm, could this be a possible (though somewhat ugly) workaround?

foreach (T; IntegralTypeList)
{
assert(factorial(to!T(3) == 6));
}

AFAIK, if T==int, then std.conv.to should simply alias itself 
away. And
it *should* be able to handle ctors that take the requisite 
type, I

think.


I use:

foreach (T; IntegralTypeList)
{
assert(factorial(cast(T)3) == 6));
}

I works, but looks a little strange.
I belive that compiler should optimise this (do nothing), but I 
am not sure.


Re: Add support implicit conversion between types

2013-09-06 Thread H. S. Teoh
On Fri, Sep 06, 2013 at 10:05:47AM -0700, H. S. Teoh wrote:
 On Fri, Sep 06, 2013 at 05:14:48PM +0200, ilya-stromberg wrote:
  On Friday, 6 September 2013 at 14:26:17 UTC, H. S. Teoh wrote:
  I thought the usual D idiom was to write factorial(5) and
  factorial(BigInt(5)) and let the compiler figure out which template
  instance you wanted?
  
  Yes, but it isn't always possible.
  
  It can be critical for more complex cases, when you call one generic
  function from another one, like this:
  
  unittest
  {
 alias TypeTuple!(byte, ubyte, short, ushort, int, uint, long,
  ulong, BigInt) IntegralTypeList;
  
 foreach(T; IntegralTypeList)
 {
assert(factorial!T(3) == 6);//Error: factorial (BigInt
  number)
  is not callable using argument types (int)
  
  You could just write factorial(T(3)) ?
  
  No, I have the error:
  Error: function expected before (), not byte of type byte
  Error: function expected before (), not ubyte of type ubyte
  Error: function expected before (), not short of type short
  Error: function expected before (), not ushort of type ushort
  Error: function expected before (), not int of type int
  Error: function expected before (), not uint of type uint
  Error: function expected before (), not long of type long
  Error: function expected before (), not ulong of type ulong
  
  As monarch_dodra pointed above, we haven't got uniform
  construction support.
 
 Hmm, I see. This is an unfortunate limitation. In C++, writing int(123)
 actually works. Looks like D is lacking in this area. :-(
[...]

Hmm, could this be a possible (though somewhat ugly) workaround?

foreach (T; IntegralTypeList)
{
assert(factorial(to!T(3) == 6));
}

AFAIK, if T==int, then std.conv.to should simply alias itself away. And
it *should* be able to handle ctors that take the requisite type, I
think.


T

-- 
The number you have dialed is imaginary. Please rotate your phone 90 degrees 
and try again.


Re: Add support implicit conversion between types

2013-09-06 Thread H. S. Teoh
On Fri, Sep 06, 2013 at 05:14:48PM +0200, ilya-stromberg wrote:
 On Friday, 6 September 2013 at 14:26:17 UTC, H. S. Teoh wrote:
 I thought the usual D idiom was to write factorial(5) and
 factorial(BigInt(5)) and let the compiler figure out which template
 instance you wanted?
 
 Yes, but it isn't always possible.
 
 It can be critical for more complex cases, when you call one generic
 function from another one, like this:
 
 unittest
 {
alias TypeTuple!(byte, ubyte, short, ushort, int, uint, long,
 ulong, BigInt) IntegralTypeList;
 
foreach(T; IntegralTypeList)
{
   assert(factorial!T(3) == 6);//Error: factorial (BigInt
 number)
 is not callable using argument types (int)
 
 You could just write factorial(T(3)) ?
 
 No, I have the error:
 Error: function expected before (), not byte of type byte
 Error: function expected before (), not ubyte of type ubyte
 Error: function expected before (), not short of type short
 Error: function expected before (), not ushort of type ushort
 Error: function expected before (), not int of type int
 Error: function expected before (), not uint of type uint
 Error: function expected before (), not long of type long
 Error: function expected before (), not ulong of type ulong
 
 As monarch_dodra pointed above, we haven't got uniform
 construction support.

Hmm, I see. This is an unfortunate limitation. In C++, writing int(123)
actually works. Looks like D is lacking in this area. :-(


T

-- 
Answer: Because it breaks the logical sequence of discussion.
Question: Why is top posting bad?


Re: Add support implicit conversion between types

2013-09-06 Thread ilya-stromberg

On Friday, 6 September 2013 at 15:47:27 UTC, Dicebot wrote:
On Friday, 6 September 2013 at 15:14:50 UTC, ilya-stromberg 
wrote:
As monarch_dodra pointed above, we haven't got uniform 
construction support.


Yeah, this one, contrary, seems to be really crucial feature 
lacking.


Yes, I agree. It solves problem of the difference between 
built-in and user-defined types for explicit cast.


Re: Add support implicit conversion between types

2013-09-06 Thread Dmitry Olshansky

06-Sep-2013 21:05, H. S. Teoh пишет:

On Fri, Sep 06, 2013 at 05:14:48PM +0200, ilya-stromberg wrote:

On Friday, 6 September 2013 at 14:26:17 UTC, H. S. Teoh wrote:

I thought the usual D idiom was to write factorial(5) and
factorial(BigInt(5)) and let the compiler figure out which template
instance you wanted?


Yes, but it isn't always possible.


It can be critical for more complex cases, when you call one generic
function from another one, like this:

unittest
{
   alias TypeTuple!(byte, ubyte, short, ushort, int, uint, long,
ulong, BigInt) IntegralTypeList;

   foreach(T; IntegralTypeList)
   {
  assert(factorial!T(3) == 6);//Error: factorial (BigInt
number)
is not callable using argument types (int)


You could just write factorial(T(3)) ?


No, I have the error:
Error: function expected before (), not byte of type byte
Error: function expected before (), not ubyte of type ubyte
Error: function expected before (), not short of type short
Error: function expected before (), not ushort of type ushort
Error: function expected before (), not int of type int
Error: function expected before (), not uint of type uint
Error: function expected before (), not long of type long
Error: function expected before (), not ulong of type ulong

As monarch_dodra pointed above, we haven't got uniform
construction support.


Hmm, I see. This is an unfortunate limitation. In C++, writing int(123)
actually works. Looks like D is lacking in this area. :-(


I swear I've seen a pull request that enables it.


--
Dmitry Olshansky


Re: Add support implicit conversion between types

2013-09-06 Thread monarch_dodra
On Friday, 6 September 2013 at 17:49:04 UTC, Jonathan M Davis 
wrote:
Personally, I think that this is opening a whole can of worms 
that should
never be opened. alias this already causes enough trouble for 
stuff like
templates (primarily because it becomes far too easy to pass a 
template
constraint and yet fail to work in the actual code). It's 
ultimately way
cleaner and far less bug-prone to disallow this sort of 
implicit conversion,

especially when so much D code is generic code.

- Jonathan M Davis


The problem with alias this is that it was designed to emulate 
inheritance, but was *diverted*, specifically, to emulate 
implicit casting instead.


I think the results speak for themselves how well that worked...

As a matter of fact, there are more than a few classes where I 
wish we could deprecate the static alias, and re-force explicit 
cast.


Re: Add support implicit conversion between types

2013-09-06 Thread ilya-stromberg

On Friday, 6 September 2013 at 13:01:14 UTC, Dicebot wrote:
On Friday, 6 September 2013 at 11:32:11 UTC, Benjamin Thaut 
wrote:
Its only a source of troubles in C++ because it is the default 
behavior. But if you design a library it can make the usage of 
your api easier and also you have a few more options to stay 
backwards compatible with your old api.


Probably. But what is the gain? `foo(Foo(5))` looks better than 
`foo(5)` to me in every possible way.


For example, use case that justifies operator overloading 
(despite the danger) in my eyes is ability to replace built-in 
types with custom ones. What is the similar rationale for 
implicit conversion?


In a few cases it's really useful.

Assume that you have user-defined type, for example BigInt.
You must implement A LOT OF foo functions which works only 
whith BigInt, like RSA, DSA and etc. For example, 100-500 
different functions.
Do you still want to write every time `foo(BigInt(5))`? 
(Remember: you have to use only BigInt).


So, the short answer is the same as for operator overloading: in 
my eyes is ability to replace built-in types with custom ones. 
Yes, it can be dangerous, and we must to provide explicit cast by 
default. But in many cases it can simplify a life and a code.


Re: Add support implicit conversion between types

2013-09-06 Thread Jonathan M Davis
On Friday, September 06, 2013 12:33:05 ilya-stromberg wrote:
 Do you have any plans to support implicit conversion between
 types?
 
 I have some code like this:
 
 struct Foo
 {
 this(int i)
 {
 //do something useful
 }
 }
 
 void bar(Foo f)
 {
 //do something else
 }
 
 void main()
 {
 Foo f = 5;//works
 
 bar(f);//works
 
 bar(Foo(5));//works
 
 bar(5);//Error: function app.bar (Foo f) is not callable using
 argument types (int)
 }
 
 So, D can't use constructor to convert int to Foo implicitly.
 Can we add implicit keyword to allow do this:
 
 struct Foo
 {
 implicit this(int i)
 {
 //do something useful
 }
 }
 
 C++ allows this, but have explicit keyword.
 C# doesn't allow this, but have operator overloading for both
 implicit and explicit cases.

Personally, I think that this is opening a whole can of worms that should 
never be opened. alias this already causes enough trouble for stuff like 
templates (primarily because it becomes far too easy to pass a template 
constraint and yet fail to work in the actual code). It's ultimately way 
cleaner and far less bug-prone to disallow this sort of implicit conversion, 
especially when so much D code is generic code.

- Jonathan M Davis


Re: Add support implicit conversion between types

2013-09-06 Thread H. S. Teoh
On Fri, Sep 06, 2013 at 07:25:21PM +0200, ilya-stromberg wrote:
 On Friday, 6 September 2013 at 17:15:03 UTC, H. S. Teoh wrote:
 Hmm, could this be a possible (though somewhat ugly) workaround?
 
  foreach (T; IntegralTypeList)
  {
  assert(factorial(to!T(3) == 6));
  }
 
 AFAIK, if T==int, then std.conv.to should simply alias itself away.
 And it *should* be able to handle ctors that take the requisite type,
 I think.
 
 I use:
 
   foreach (T; IntegralTypeList)
   {
   assert(factorial(cast(T)3) == 6));
   }
 
 I works, but looks a little strange.
 I belive that compiler should optimise this (do nothing), but I am
 not sure.

I checked the disassembly for cast(T)5 for T==int and T==BigInt. Seems
the compiler is doing the right thing in both cases. For T==int, the
compiler just loads 5 directly into the register; for T==BigInt, it
calls the BigInt ctor with 5 as parameter to construct an instance of
BigInt.

So, this seems to work, even though it looks ugly.


T

-- 
A linguistics professor was lecturing to his class one day. In
English, he said, A double negative forms a positive. In some
languages, though, such as Russian, a double negative is still a
negative. However, there is no language wherein a double positive can
form a negative. A voice from the back of the room piped up, Yeah,
yeah.