Re: Support implicit conversion between types

2013-09-04 Thread H. S. Teoh
On Wed, Sep 04, 2013 at 04:07:28PM -0700, H. S. Teoh wrote:
> On Thu, Sep 05, 2013 at 01:04:30AM +0200, Kapps wrote:
> > On Wednesday, 4 September 2013 at 23:00:07 UTC, H. S. Teoh wrote:
> > >On Wed, Sep 04, 2013 at 02:14:26PM -0700, Ali Çehreli wrote:
> > >>On 09/04/2013 01:46 PM, Adam D. Ruppe wrote:
> > >>
> > >>> D does not support implicit struct construction.
> > >>
> > >>That's what I knew.
> > >>
> > >>> Interestingly though, it *does* support it for functions taking
> > >>> classes:
> > >>>
> > >>> class Foo {
> > >>>  this(int i) {}
> > >>> }
> > >>>
> > >>> void foo(Foo f...) {}
> > >>>
> > >>> void main() {
> > >>>  foo(10);
> > >>> }
> > >>
> > >>WHAT? :) It even new's one?
> > >>
> > >>But it works only for the ellipsis.
> > >>
> > >>I wonder why the discrepancy...
> > >[...]
> > >
> > >Whoa. I never knew about this! It's ... I don't know what to say.  It
> > >seems to be a cool feature, but it's also ... so scary. Implicit
> > >new's just leaves a lump in my throat. Is this an actual, intentional
> > >feature??!
> > >
> > >
> > >T
> > 
> > It, in theory, doesn't allocate memory:
> > "An implementation may construct the object or array instance on the
> > stack. Therefore, it is an error to refer to that instance after the
> > variadic function has returned"
> 
> That's even more scary. So the object implicitly constructed in this way
> is put on the *stack* instead of the heap, and becomes invalid after the
> function returns? That's just a minefield of pitfalls waiting to
> happen...
[...]

Hmm.  I experimented with this "feature", and found some interesting
quirks:

void foo(Foo f...) {...}

can only be called with the same arguments as Foo's ctor, and 'f' inside
the function body refers to the *single* class instance implicitly
constructed.  The object is actually allocated on the heap, even though
the class reference is on the stack (perfectly normal). So this syntax
appears to be some kind of surrogate ctor syntax, in which foo() acts as
a surrogate ctor, getting the constructed object as a parameter and
possibly modifying it or returning something else in its place.

I can see where this might be useful, but I'm confused by the choice of
syntax. This isn't a true variadic function at all; it's a ctor wrapper?
Why was this syntax chosen?

I'm really puzzled now.


T

-- 
One disk to rule them all, One disk to find them. One disk to bring them all 
and in the darkness grind them. In the Land of Redmond where the shadows lie. 
-- The Silicon Valley Tarot


Re: Support implicit conversion between types

2013-09-04 Thread H. S. Teoh
On Thu, Sep 05, 2013 at 01:04:30AM +0200, Kapps wrote:
> On Wednesday, 4 September 2013 at 23:00:07 UTC, H. S. Teoh wrote:
> >On Wed, Sep 04, 2013 at 02:14:26PM -0700, Ali Çehreli wrote:
> >>On 09/04/2013 01:46 PM, Adam D. Ruppe wrote:
> >>
> >>> D does not support implicit struct construction.
> >>
> >>That's what I knew.
> >>
> >>> Interestingly though, it *does* support it for functions taking
> >>> classes:
> >>>
> >>> class Foo {
> >>>  this(int i) {}
> >>> }
> >>>
> >>> void foo(Foo f...) {}
> >>>
> >>> void main() {
> >>>  foo(10);
> >>> }
> >>
> >>WHAT? :) It even new's one?
> >>
> >>But it works only for the ellipsis.
> >>
> >>I wonder why the discrepancy...
> >[...]
> >
> >Whoa. I never knew about this! It's ... I don't know what to say.  It
> >seems to be a cool feature, but it's also ... so scary. Implicit
> >new's just leaves a lump in my throat. Is this an actual, intentional
> >feature??!
> >
> >
> >T
> 
> It, in theory, doesn't allocate memory:
> "An implementation may construct the object or array instance on the
> stack. Therefore, it is an error to refer to that instance after the
> variadic function has returned"

That's even more scary. So the object implicitly constructed in this way
is put on the *stack* instead of the heap, and becomes invalid after the
function returns? That's just a minefield of pitfalls waiting to
happen...


T

-- 
Curiosity kills the cat. Moral: don't be the cat.


Re: Support implicit conversion between types

2013-09-04 Thread Kapps

On Wednesday, 4 September 2013 at 23:00:07 UTC, H. S. Teoh wrote:

On Wed, Sep 04, 2013 at 02:14:26PM -0700, Ali Çehreli wrote:

On 09/04/2013 01:46 PM, Adam D. Ruppe wrote:

> D does not support implicit struct construction.

That's what I knew.

> Interestingly though, it *does* support it for functions 
> taking

> classes:
>
> class Foo {
>  this(int i) {}
> }
>
> void foo(Foo f...) {}
>
> void main() {
>  foo(10);
> }

WHAT? :) It even new's one?

But it works only for the ellipsis.

I wonder why the discrepancy...

[...]

Whoa. I never knew about this! It's ... I don't know what to 
say. It
seems to be a cool feature, but it's also ... so scary. 
Implicit new's

just leaves a lump in my throat. Is this an actual, intentional
feature??!


T


It, in theory, doesn't allocate memory:
"An implementation may construct the object or array instance on 
the stack. Therefore, it is an error to refer to that instance 
after the variadic function has returned"




Re: Support implicit conversion between types

2013-09-04 Thread H. S. Teoh
On Wed, Sep 04, 2013 at 02:14:26PM -0700, Ali Çehreli wrote:
> On 09/04/2013 01:46 PM, Adam D. Ruppe wrote:
> 
> > D does not support implicit struct construction.
> 
> That's what I knew.
> 
> > Interestingly though, it *does* support it for functions taking
> > classes:
> >
> > class Foo {
> >  this(int i) {}
> > }
> >
> > void foo(Foo f...) {}
> >
> > void main() {
> >  foo(10);
> > }
> 
> WHAT? :) It even new's one?
> 
> But it works only for the ellipsis.
> 
> I wonder why the discrepancy...
[...]

Whoa. I never knew about this! It's ... I don't know what to say. It
seems to be a cool feature, but it's also ... so scary. Implicit new's
just leaves a lump in my throat. Is this an actual, intentional
feature??!


T

-- 
If you want to solve a problem, you need to address its root cause, not just 
its symptoms. Otherwise it's like treating cancer with Tylenol...


Re: Support implicit conversion between types

2013-09-04 Thread Kapps

On Wednesday, 4 September 2013 at 21:14:26 UTC, Ali Çehreli wrote:

On 09/04/2013 01:46 PM, Adam D. Ruppe wrote:

> D does not support implicit struct construction.

That's what I knew.

> Interestingly though, it *does* support it for functions
taking classes:
>
> class Foo {
>  this(int i) {}
> }
>
> void foo(Foo f...) {}
>
> void main() {
>  foo(10);
> }

WHAT? :) It even new's one?

But it works only for the ellipsis.

I wonder why the discrepancy...

Ali


http://dlang.org/function.html Under Typesafe Variadic Functions 
-> For class objects.


Re: Support implicit conversion between types

2013-09-04 Thread Ali Çehreli

On 09/04/2013 01:46 PM, Adam D. Ruppe wrote:

> D does not support implicit struct construction.

That's what I knew.

> Interestingly though, it *does* support it for functions taking classes:
>
> class Foo {
>  this(int i) {}
> }
>
> void foo(Foo f...) {}
>
> void main() {
>  foo(10);
> }

WHAT? :) It even new's one?

But it works only for the ellipsis.

I wonder why the discrepancy...

Ali



Re: Support implicit conversion between types

2013-09-04 Thread Adam D. Ruppe
On Wednesday, 4 September 2013 at 20:25:28 UTC, ilya-stromberg 
wrote:
So, the question is: what should I add to "Foo" struct to allow 
implicit conversions from "int" to "Foo"?


D does not support implicit struct construction.

Interestingly though, it *does* support it for functions taking 
classes:


class Foo {
this(int i) {}
}

void foo(Foo f...) {}

void main() {
foo(10);
}


But there's nothing like it for structs.


Re: Support implicit conversion between types

2013-09-04 Thread ilya-stromberg

On Wednesday, 4 September 2013 at 20:14:06 UTC, Kozzi wrote:

So you can use templates, something like this:


I know, it will work. But I really have **a lot of** different 
"bar" functions, so that way will be painful.


So, the question is: what should I add to "Foo" struct to allow 
implicit conversions from "int" to "Foo"?


Re: Support implicit conversion between types

2013-09-04 Thread Kozzi

So you can use templates, something like this:


bool isConvertableToFoo(T)
{
T i = void;
return is(typeof(Foo(i)) == Foo);
}

void bar(T)(T i) if (is(T : Foo))
{
//some code
}

void bar(T)(T i) if (!is(T : Foo) && isConvertableToFoo!T)
{
bar(Foo(i));
}


I do not test it so it is maybe not completly correct :).
On Wednesday, 4 September 2013 at 19:54:44 UTC, ilya-stromberg 
wrote:

On Wednesday, 4 September 2013 at 19:44:17 UTC, Namespace wrote:


What's about:

void bar(int i) {
   bar(Foo(i));
}

?


No, I wrote very simple example. I have 10 "from" types and a 
lot of different "bar" functions. Your way will be more painful 
then explicit conversion.


Re: Support implicit conversion between types

2013-09-04 Thread Namespace
On Wednesday, 4 September 2013 at 19:36:08 UTC, ilya-stromberg 
wrote:

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)

}


D can't implicitly convert type "int" to type "Foo", but 
constructor "Foo(int)" exists. Explicit conversion works fine.

What should I do to support this convertion implicitly?


What's about:

void bar(int i) {
bar(Foo(i));
}

?


Re: Support implicit conversion between types

2013-09-04 Thread ilya-stromberg

On Wednesday, 4 September 2013 at 19:44:17 UTC, Namespace wrote:


What's about:

void bar(int i) {
bar(Foo(i));
}

?


No, I wrote very simple example. I have 10 "from" types and a lot 
of different "bar" functions. Your way will be more painful then 
explicit conversion.