View mode: basic / threaded / horizontal-split · Log in · Help
August 26, 2012
Function pointers/delegates default args were stealth removed?
I just updated to 2.60 and found errors throughout my code where function
pointers default args no longer work.
*Every single project* I've written in D, 5 projects, don't work anymore,
including my projects at work.

I found this discussion: http://d.puremagic.com/issues/show_bug.cgi?id=3866
It seems the change was just decided and implemented with basically no
discussion or argument at all :/

My use cases are dynamic linkage, and cross-language integration.
I can't manually interact with DLL's containing API's that expect to have
default arguments if function pointers no longer support them.
Also when receiving foreign language function pointers, they frequently
need to have default args too.

I also integrate with many C style API's (rendering engines and the like),
which involve registration of various callbacks, and lots of those have
default args too.

I find this particularly surprising, since I recently motivated
implementation of new traits which could parse default args from parameter
lists, and use that to generation function pointers in templates which
auto-magically clone functions parameter lists verbatim, specifically
including the default args...
August 26, 2012
Re: Function pointers/delegates default args were stealth removed?
I don't think there's any cases where the change can't be worked 
around relatively easily. Correct me if I'm wrong.

I was also surprised to see this removed without mention, but 
after reading the bug, it seems like the correct decision. I 
don't like the idea of adding default arguments to types.
August 26, 2012
Re: Function pointers/delegates default args were stealth removed?
On 8/26/2012 3:26 PM, Manu wrote:
> I just updated to 2.60 and found errors throughout my code where function
> pointers default args no longer work.
> _Every single project_ I've written in D, 5 projects, don't work anymore,
> including my projects at work.
>
> I found this discussion: http://d.puremagic.com/issues/show_bug.cgi?id=3866
> It seems the change was just decided and implemented with basically no
> discussion or argument at all :/
>
> My use cases are dynamic linkage, and cross-language integration.
> I can't manually interact with DLL's containing API's that expect to have
> default arguments if function pointers no longer support them.
> Also when receiving foreign language function pointers, they frequently need to
> have default args too.
>
> I also integrate with many C style API's (rendering engines and the like), which
> involve registration of various callbacks, and lots of those have default args too.
>
> I find this particularly surprising, since I recently motivated implementation
> of new traits which could parse default args from parameter lists, and use that
> to generation function pointers in templates which auto-magically clone
> functions parameter lists verbatim, specifically including the default args...

The trouble is that, as 3866 shows, there is no design anyone could come up with 
that worked in a consistent manner. The only consistent way out was to make 
default arguments a characteristic of the declaration, not of the type.

The trouble for function pointers, is that any default args would need to be 
part of the type, not the declaration.

I know it broke code (for many others, too), and I'm very sorry about that, but 
I don't see another way out.

(Many uses of default arguments can be replaced with overloaded functions.)
August 26, 2012
Re: Function pointers/delegates default args were stealth removed?
Walter Bright:

> The trouble is that, as 3866 shows, there is no design anyone 
> could come up with that worked in a consistent manner. The only 
> consistent way out was to make default arguments a 
> characteristic of the declaration, not of the type.

I think Ada is doing what D does now, it doesn't accept default 
arguments for things like function pointers/delegates.

Bye,
bearophile
August 26, 2012
Re: Function pointers/delegates default args were stealth removed?
On 08/27/2012 12:41 AM, Walter Bright wrote:
>
> The trouble for function pointers, is that any default args would need
> to be part of the type, not the declaration.
>

They could be made part of the variable declaration.
August 27, 2012
Re: Function pointers/delegates default args were stealth removed?
On 27 August 2012 01:41, Walter Bright <newshound2@digitalmars.com> wrote:

> On 8/26/2012 3:26 PM, Manu wrote:
>
>> I just updated to 2.60 and found errors throughout my code where function
>> pointers default args no longer work.
>> _Every single project_ I've written in D, 5 projects, don't work anymore,
>>
>> including my projects at work.
>>
>> I found this discussion: http://d.puremagic.com/issues/**
>> show_bug.cgi?id=3866 <http://d.puremagic.com/issues/show_bug.cgi?id=3866>
>> It seems the change was just decided and implemented with basically no
>> discussion or argument at all :/
>>
>> My use cases are dynamic linkage, and cross-language integration.
>> I can't manually interact with DLL's containing API's that expect to have
>> default arguments if function pointers no longer support them.
>> Also when receiving foreign language function pointers, they frequently
>> need to
>> have default args too.
>>
>> I also integrate with many C style API's (rendering engines and the
>> like), which
>> involve registration of various callbacks, and lots of those have default
>> args too.
>>
>> I find this particularly surprising, since I recently motivated
>> implementation
>> of new traits which could parse default args from parameter lists, and
>> use that
>> to generation function pointers in templates which auto-magically clone
>> functions parameter lists verbatim, specifically including the default
>> args...
>>
>
> The trouble is that, as 3866 shows, there is no design anyone could come
> up with that worked in a consistent manner. The only consistent way out was
> to make default arguments a characteristic of the declaration, not of the
> type.
>

To be fair, it's not a very lively discussion. Spans 1 day, and only 3
people comment :)
Is that really an exhaustive set of options? It seems the other possibility
(including the default arg in the equivalence test) wasn't really
considered.

The part that I don't understand is how the situation manifests in the
first place:

   auto foo = (int a = 1) { return a;};
   auto bar = (int a) { return a;};

   writeln(foo()); // writes '1'
   writeln(bar()); // writes '1' also!

These are 2 distinct assignments. I would expect foo and bar *would* each
take a type that is technically equivalent, but foo's type would have the
bonus default arg in its type record, just as a function pointer that were
declared explicitly.
At what point does the compiler become confused? They never interact... The
expected behaviour seems obvious to me, foo and bar should effectively be:
  int function(int a = 1) foo = ..;
  int function(int a) bar = ...;

I presume if I typed that code, there would be no problem?

The discussion is obviously regarding implementation details...?


The trouble for function pointers, is that any default args would need to
> be part of the type, not the declaration.
>

I thought they were part of the type already? I would have thought that's
where they should be. Why is their new home more 'proper'?


I know it broke code (for many others, too), and I'm very sorry about that,
> but I don't see another way out.
>

It's a rather major breakage. I've seen you reject far more important
changes solely on the grounds that they are a breaking change before...


(Many uses of default arguments can be replaced with overloaded functions.)
>

Can you suggest how? I can't think of a feasible approach.

You can't overload function pointers (multiple instances of variables with
the same name). And by definition of a function *pointer*, I don't own the
target function to overload it.
I can't reasonably produce static wrappers either, unless the wrapper
receives the function pointer I intend to call as an arg, which is super
nasty.

I can probably address the global/static ones via wrappers, but I don't
love redundant function calls, it reduces debug build performance (see: all
my rants about __forceinline), but that would only address the problem in a
few situations.
This also undoes all that good work recently with the parameter list traits
>_<


As I see it, calling a function is possibly the single most important thing
a programming language does. Flexibility in this regard is
valuable. Default args in function pointers was a HUGE selling point of D
to me, I've made extremely liberal use of this feature to great benefit
throughout all my projects.
But perhaps most importantly, this change has a huge impact on my code at
work... I don't really want to imagine telling my boss that I need to
rewrite the engine bindings and integration code. I'll look like the
biggest dick this side of the Baltic :/
August 27, 2012
Re: Function pointers/delegates default args were stealth removed?
On 8/26/2012 4:50 PM, Timon Gehr wrote:
> On 08/27/2012 12:41 AM, Walter Bright wrote:
>>
>> The trouble for function pointers, is that any default args would need
>> to be part of the type, not the declaration.
>>
>
> They could be made part of the variable declaration.

You mean part of the function pointer variable?

Consider what you do with a function pointer - you pass it to someone else. That 
someone else gets it as a type, not a declaration. I.e. you lose the default 
argument information, since that is not attached to the type.
August 27, 2012
Re: Function pointers/delegates default args were stealth removed?
On 8/26/2012 5:06 PM, Manu wrote:
> To be fair, it's not a very lively discussion. Spans 1 day, and only 3 people
> comment :)

If you want a lively discussion, start one up about what to name a keyword :-)


> Is that really an exhaustive set of options? It seems the other possibility
> (including the default arg in the equivalence test) wasn't really considered.
>
> The part that I don't understand is how the situation manifests in the first place:
>
>      auto foo = (int a = 1) { return a;};
>      auto bar = (int a) { return a;};
>
>      writeln(foo()); // writes '1'
>      writeln(bar()); // writes '1' also!
>
> These are 2 distinct assignments. I would expect foo and bar /would/ each take a
> type that is technically equivalent, but foo's type would have the bonus default
> arg in its type record, just as a function pointer that were declared explicitly.

That's the way it used to work. The problem is, what are those types? Are they 
the same types or not? You're saying sometimes they are the same type, sometimes 
they are not. It's a mess.

> At what point does the compiler become confused? They never interact... The
> expected behaviour seems obvious to me, foo and bar should effectively be:
>     int function(int a = 1) foo = ..;
>     int function(int a) bar = ...;

It seems obvious only in the trivial case. What if you passed foo to a function? 
Now what type is it? What is the mangling for the type?

> I presume if I typed that code, there would be no problem?
>
> The discussion is obviously regarding implementation details...?

No.

>
>
>     The trouble for function pointers, is that any default args would need to be
>     part of the type, not the declaration.
>
>
> I thought they were part of the type already? I would have thought that's where
> they should be. Why is their new home more 'proper'?

Because are the types the same or not?

>
>
>     I know it broke code (for many others, too), and I'm very sorry about that,
>     but I don't see another way out.
>
>
> It's a rather major breakage. I've seen you reject far more important changes
> solely on the grounds that they are a breaking change before...

Unfortunately, it was already broken, as the bug report showed. It's a matter of 
where the crack shows up.



>     (Many uses of default arguments can be replaced with overloaded functions.)
>
>
> Can you suggest how? I can't think of a feasible approach.

I'd have to see what you were trying to do.


> You can't overload function pointers (multiple instances of variables with the
> same name). And by definition of a function /pointer/, I don't own the target
> function to overload it.
> I can't reasonably produce static wrappers either, unless the wrapper receives
> the function pointer I intend to call as an arg, which is super nasty.
>
> I can probably address the global/static ones via wrappers, but I don't love
> redundant function calls, it reduces debug build performance (see: all my rants
> about __forceinline), but that would only address the problem in a few situations.
> This also undoes all that good work recently with the parameter list traits >_<
>
>
> As I see it, calling a function is possibly the single most important thing a
> programming language does. Flexibility in this regard is valuable. Default args
> in function pointers was a HUGE selling point of D to me, I've made extremely
> liberal use of this feature to great benefit throughout all my projects.
> But perhaps most importantly, this change has a huge impact on my code at
> work... I don't really want to imagine telling my boss that I need to rewrite
> the engine bindings and integration code. I'll look like the biggest dick this
> side of the Baltic :/

If you can show me a generic example of what you are trying to do, perhaps we 
can suggest a reasonable alternative.
August 27, 2012
Re: Function pointers/delegates default args were stealth removed?
On 08/27/2012 02:44 AM, Walter Bright wrote:
> On 8/26/2012 4:50 PM, Timon Gehr wrote:
>> On 08/27/2012 12:41 AM, Walter Bright wrote:
>>>
>>> The trouble for function pointers, is that any default args would need
>>> to be part of the type, not the declaration.
>>>
>>
>> They could be made part of the variable declaration.
>
> You mean part of the function pointer variable?
>

Yes.

> Consider what you do with a function pointer - you pass it to someone
> else. That someone else gets it as a type, not a declaration.

If it is a template function, yes. But then you may as well pass the
function pointer variable per alias, which is common.

Otherwise someone else gets nothing but a parameter declaration.

> I.e. you lose the default argument information, since that is not attached to the
> type.
>

I think most valid existing use cases would still be supported:

int execFunctionPointer(int function(int = 2) fun){
    return fun();
}

auto dg = (int x, int y=2){ return x+y; }
writeln(range.map!dg());

int function(int=3)[] funs;
funs[0]();

It is up to you if it is worth the effort, of course.
August 27, 2012
Re: Function pointers/delegates default args were stealth removed?
On 8/26/2012 6:55 PM, Timon Gehr wrote:
> On 08/27/2012 02:44 AM, Walter Bright wrote:
>> On 8/26/2012 4:50 PM, Timon Gehr wrote:
>>> On 08/27/2012 12:41 AM, Walter Bright wrote:
>>>>
>>>> The trouble for function pointers, is that any default args would need
>>>> to be part of the type, not the declaration.
>>>>
>>>
>>> They could be made part of the variable declaration.
>>
>> You mean part of the function pointer variable?
>>
>
> Yes.
>
>> Consider what you do with a function pointer - you pass it to someone
>> else. That someone else gets it as a type, not a declaration.
>
> If it is a template function, yes. But then you may as well pass the
> function pointer variable per alias, which is common.

You pass the function declaration by alias, not the function pointer 
declaration. In which case you will get the default arguments.

>
> Otherwise someone else gets nothing but a parameter declaration.
>
>> I.e. you lose the default argument information, since that is not attached to the
>> type.
>>
>
> I think most valid existing use cases would still be supported:
>
> int execFunctionPointer(int function(int = 2) fun){
>      return fun();
> }
>
> auto dg = (int x, int y=2){ return x+y; }
> writeln(range.map!dg());
>
> int function(int=3)[] funs;
> funs[0]();
>
> It is up to you if it is worth the effort, of course.

and it falls apart immediately once you try to transfer that function pointer 
anywhere.
« First   ‹ Prev
1 2 3 4 5
Top | Discussion index | About this forum | D home