Function pointers/delegates default args were stealth removed?

Manu turkeyman at gmail.com
Sun Aug 26 17:06:17 PDT 2012


On 27 August 2012 01:41, Walter Bright <newshound2 at 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 :/
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.puremagic.com/pipermail/digitalmars-d/attachments/20120827/29863175/attachment.html>


More information about the Digitalmars-d mailing list