View mode: basic / threaded / horizontal-split · Log in · Help
September 02, 2011
Conversion of delegate with default arguments to delegate with less arguments?
Code:

void main()
{
   auto foo = (int x = 10){ /* */ };
   void delegate() bar = foo;
}

Since foo takes an argument that already has a default it can be used
as a simple `void delegate()`, so maybe it makes sense for `foo` to be
able to implicitly convert to such a type.

Unfortunately doing a cast doesn't work properly:

import std.stdio;

void main()
{
   auto foo = (int x = 10){ writeln(x); };
   void delegate() bar;
   bar = cast(typeof(bar))foo;

   bar();  // prints garbage
}

So maybe this type of conversion is impossible in the first place due
to how arguments are passed? I don't know all the technical tidbits,
but from a user's point of view an implicit conversion kind of makes
sense (if it's possible).
September 02, 2011
Re: Conversion of delegate with default arguments to delegate with less arguments?
On Fri, 02 Sep 2011 22:11:50 +0300, Andrej Mitrovic  
<andrej.mitrovich@gmail.com> wrote:

> So maybe this type of conversion is impossible in the first place due
> to how arguments are passed?

Yes. The default value is pushed on the stack at the call site.

>  I don't know all the technical tidbits,
> but from a user's point of view an implicit conversion kind of makes
> sense (if it's possible).

The compiler would need to generate a function to do the conversion. I  
think the same could be achieved with a template.

-- 
Best regards,
 Vladimir                            mailto:vladimir@thecybershadow.net
September 02, 2011
Re: Conversion of delegate with default arguments to delegate with less arguments?
On 9/2/11, Vladimir Panteleev <vladimir@thecybershadow.net> wrote:
> On Fri, 02 Sep 2011 22:11:50 +0300, Andrej Mitrovic
> <andrej.mitrovich@gmail.com> wrote:
>
>> So maybe this type of conversion is impossible in the first place due
>> to how arguments are passed?
>
> Yes. The default value is pushed on the stack at the call site.

Yeah, I should have thought more before I posted. The default value is
not "tied" to the function, the values are inserted by the compiler at
the call site, doh. :)
September 02, 2011
Re: Conversion of delegate with default arguments to delegate with less arguments?
On 09/02/2011 11:49 PM, Andrej Mitrovic wrote:
> On 9/2/11, Vladimir Panteleev<vladimir@thecybershadow.net>  wrote:
>> On Fri, 02 Sep 2011 22:11:50 +0300, Andrej Mitrovic
>> <andrej.mitrovich@gmail.com>  wrote:
>>
>>> So maybe this type of conversion is impossible in the first place due
>>> to how arguments are passed?
>>
>> Yes. The default value is pushed on the stack at the call site.
>
> Yeah, I should have thought more before I posted. The default value is
> not "tied" to the function, the values are inserted by the compiler at
> the call site, doh. :)

The solution is this:

void main()
{
    auto foo = (int x = 10){ /* */ }
    void delegate() bar = { return foo(); }
}

the compiler could in theory just automatically insert a thunk like this.

Related: I think that function pointers should implicitly decay to 
delegates. This would allow the compiler to optimize some delegate 
literals to function pointers if they don't access the outer scope, 
without breaking any code that wants to use such a function literal as a 
delegate.
September 03, 2011
Re: Conversion of delegate with default arguments to delegate with less arguments?
On 9/3/11, Timon Gehr <timon.gehr@gmx.ch> wrote:
> Related: I think that function pointers should implicitly decay to
> delegates. This would allow the compiler to optimize some delegate
> literals to function pointers if they don't access the outer scope,
> without breaking any code that wants to use such a function literal as a
> delegate.
>

Well in TDPL it says that function literals are function literals by
default unless the compiler determines they must be delegates. But
currently all function literals are delegates unless explicitly marked
with 'function'.
September 03, 2011
Re: Conversion of delegate with default arguments to delegate with less arguments?
On 2011-09-02 21:11, Andrej Mitrovic wrote:
> Code:
>
> void main()
> {
>      auto foo = (int x = 10){ /* */ };
>      void delegate() bar = foo;
> }
>
> Since foo takes an argument that already has a default it can be used
> as a simple `void delegate()`, so maybe it makes sense for `foo` to be
> able to implicitly convert to such a type.
>
> Unfortunately doing a cast doesn't work properly:
>
> import std.stdio;
>
> void main()
> {
>      auto foo = (int x = 10){ writeln(x); };
>      void delegate() bar;
>      bar = cast(typeof(bar))foo;
>
>      bar();  // prints garbage
> }
>
> So maybe this type of conversion is impossible in the first place due
> to how arguments are passed? I don't know all the technical tidbits,
> but from a user's point of view an implicit conversion kind of makes
> sense (if it's possible).

I think it would be usable. I also think that a delegate/function that 
returns a value could be implicitly converted to a delegate/function of 
the same signature but returns void instead. I would be the same as 
calling the delegate that returns a value and not assign the returned 
value to a variable.

-- 
/Jacob Carlborg
September 03, 2011
Re: Conversion of delegate with default arguments to delegate with less arguments?
> void main()
> {
>      auto foo = (int x = 10){ /* */ }
>      void delegate() bar = { return foo(); }
> }
> 
> the compiler could in theory just automatically insert a thunk like 
> this.

That sounds reasonable.
September 03, 2011
Re: Conversion of delegate with default arguments to delegate with less arguments?
On Sat, 03 Sep 2011 11:50:25 +0200, Christophe  
<travert@phare.normalesup.org> wrote:

>> void main()
>> {
>>      auto foo = (int x = 10){ /* */ }
>>       void delegate() bar = { return foo(); }
>> }
>>
>> the compiler could in theory just automatically insert a thunk like
>>  this.
>
> That sounds reasonable.

This look like a library solution would be best.
I suppose you want to store a homogeneous list of delegates.
Actually std.bind should do exactly this, but the module is broken and  
needs a rewrite.

You should also be able to use std.functional's curry but it turns out  
it's implementation
can't handle anything but two parameter functions.
I'll make a pull request for this one though. Then you should be able to  
do 'alias curry!(foo, 10) bar'

martin
September 03, 2011
Re: Conversion of delegate with default arguments to delegate with less arguments?
On 9/2/11 9:52 PM, Andrej Mitrovic wrote:
> On 9/3/11, Timon Gehr<timon.gehr@gmx.ch>  wrote:
>> Related: I think that function pointers should implicitly decay to
>> delegates. This would allow the compiler to optimize some delegate
>> literals to function pointers if they don't access the outer scope,
>> without breaking any code that wants to use such a function literal as a
>> delegate.
>>
>
> Well in TDPL it says that function literals are function literals by
> default unless the compiler determines they must be delegates. But
> currently all function literals are delegates unless explicitly marked
> with 'function'.

Yah, Walter explicitly approved that paragraph but didn't get around to 
implementing it.

Andrei
September 03, 2011
Re: Conversion of delegate with default arguments to delegate with less arguments?
On 09/03/2011 03:12 PM, Martin Nowak wrote:
> On Sat, 03 Sep 2011 11:50:25 +0200, Christophe
> <travert@phare.normalesup.org> wrote:
>
>>> void main()
>>> {
>>> auto foo = (int x = 10){ /* */ }
>>> void delegate() bar = { return foo(); }
>>> }
>>>
>>> the compiler could in theory just automatically insert a thunk like
>>> this.
>>
>> That sounds reasonable.
>
> This look like a library solution would be best.
> I suppose you want to store a homogeneous list of delegates.
> Actually std.bind should do exactly this, but the module is broken and
> needs a rewrite.
>
> You should also be able to use std.functional's curry but it turns out
> it's implementation
> can't handle anything but two parameter functions.
> I'll make a pull request for this one though. Then you should be able to
> do 'alias curry!(foo, 10) bar'
>

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

Make sure to call the new implementation 'partial' or similar.
« First   ‹ Prev
1 2
Top | Discussion index | About this forum | D home