On 27 August 2012 01:41, Walter Bright <newshou...@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 :/