View mode: basic / threaded / horizontal-split · Log in · Help
August 28, 2012
Re: Function pointers/delegates default args were stealth removed?
On 2012-08-27 22:53, Walter Bright wrote:

> The language design requires a 1:1 mapping of mangling to types. Hence
> the compiler design to use the mangling as a hashmap key of types. The
> failure of that approach in this case points to a problem in the
> language design, not a bug in the compiler.

How does this then work when the body of the anonymous functions are 
different? How will they be identified?

-- 
/Jacob Carlborg
August 28, 2012
Re: Function pointers/delegates default args were stealth removed?
On 8/27/2012 11:53 PM, Jacob Carlborg wrote:
> How does this then work when the body of the anonymous functions are different?
> How will they be identified?

I don't know what you mean.
August 28, 2012
Re: Function pointers/delegates default args were stealth removed?
On 2012-08-28 09:16, Walter Bright wrote:

> I don't know what you mean.

The original problem in the bug report looked like this:

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

    writeln(foo());
    writeln(bar());
}

If I change one of the bodies of the anonymous functions to look like this:

void main ()
{
    auto foo = (int a = 1) { return a; writeln("foo"); };
    auto bar = (int a) { return a; };

    writeln(foo());
    writeln(bar());
}

It behaves correctly and won't compile any more.

-- 
/Jacob Carlborg
August 28, 2012
Re: Function pointers/delegates default args were stealth removed?
On 2012-08-27 23:28, Jonathan M Davis wrote:

> Except that the change which is causing Manu problems _isn't_ a new feature.
> It's a bug fix. So, better versioning wouldn't necessarily have helped him any
> at all. At best, if we had a more complex versioning scheme, it could be
> decided that the bug fix was potentially disruptive enough that it should only
> be fixed in a more major release, but _every_ bug fix risks breaking code,
> especially when code could be relying on the buggy behavior.

The fix for this particular bug was to remove a language feature. I 
don't think it would be wise to put that change in a minor release. It 
doesn't matter why the feature was removed. If a feature is remove from 
the language it should only be put in a major release, period.

-- 
/Jacob Carlborg
August 28, 2012
Re: Function pointers/delegates default args were stealth removed?
On 2012-08-27 23:29, Manu wrote:

> Are you suggesting using DLL's is asking for trouble? Dynamic linkage is
> a fundamental part of software.

Yes, they don't properly work in D.

-- 
/Jacob Carlborg
August 28, 2012
Re: Function pointers/delegates default args were stealth removed?
On 27/08/12 16:16, Steven Schveighoffer wrote:
> On Sun, 26 Aug 2012 18:26:40 -0400, Manu <turkeyman@gmail.com> 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.
>
> OK, I've read all the posts on this, and this is what I think would
> solve the problem:
>
> 1. default parameters are part of the function pointer type, because a
> function pointer has a type.
> 2. The mangled name of the function that is assigned to that function
> pointer does *not* have default parameters mangled in.  Only the
> function pointer type has them.
> 3. Since the default parameters are part of the type, but not defined by
> the function it points to, you can use interchangeably functions of the
> same type which define default parameters or not (or define different
> ones).  The default parameters follow the function pointer variable.

This sounds like sloppy thinking.
I _think_ what you are saying is that there should be implicit 
conversions from one function pointer type, to any other that has the 
same basic declaration, but different default arguments.

But then you get problems with IFTI.
void foo( void function(int x), double) {}
void foo( void function(int x), int) {}

void function(int x = 10) bar;

foo(bar, 5); // fails -- ambiguous. Both overloads match with implicit 
conversions.


But really, it seems to me that this whole feature is just syntax sugar 
for one special case of currying.
August 28, 2012
Re: Function pointers/delegates default args were stealth removed?
On Monday, 27 August 2012 at 21:29:06 UTC, Jonathan M Davis wrote:
> On Monday, August 27, 2012 23:22:39 foobar wrote:
>> All true, except one crucial fact: DMD gets critical bug fixes
>> incorporated with new features in the same release. This 
>> leaves a
>> poor choice to the programmer, either he sticks with older
>> compiler version and can't get any critical bug fixes, or he
>> updates the compiler to latest version with all the bug fixes 
>> but
>> risks breakage of code due to new features (which is _exactly_
>> what happened to manu).
>
> Except that the change which is causing Manu problems _isn't_ a 
> new feature.
> It's a bug fix. So, better versioning wouldn't necessarily have 
> helped him any
> at all. At best, if we had a more complex versioning scheme, it 
> could be
> decided that the bug fix was potentially disruptive enough that 
> it should only
> be fixed in a more major release, but _every_ bug fix risks 
> breaking code,
> especially when code could be relying on the buggy behavior.
>
> - Jonathan M Davis

I guess your definition of stable is different than mine.
"Accepts invalid" bugs should never be fixed on the current 
stable branch as they introduce a breaking change unless it's a 
matter of a security problem.

All compilers have a list of accepts invalid bugs and no one 
"fixes" them on the stable/release branch exactly because it will 
break existing code as evidently shown by manu's posts.
Python introduced version 3 to handle this and Ruby had version 
1.9, all the while both the stable and the next-version branches 
got bug-fixes.

D was moved to Git long ago which trivially allows such branching 
schemes so there really no excuse to stick with the current 
flawed system except inertia.
August 28, 2012
Re: Function pointers/delegates default args were stealth removed?
"Jonathan M Davis" <jmdavisProg@gmx.com> wrote in message 
news:mailman.1446.1346070222.31962.digitalmars-d@puremagic.com...
>
> Default arguments just do not make sense with function pointers, because 
> they
> don't follow the function pointer, because it's a _pointer_ and has no
> knowledge of what it's pointing to. It's only at the declaration point of 
> the
> function that the default argument exists, and that has _nothing_ to do 
> with
> the function pointer. You might as well ask a reference of type Object 
> what
> the arguments used to construct the derived class that it actually refers 
> to
> were as expect a function pointer to have any clue about default arguments 
> to
> the function that it points to.
>
> - Jonathan M Davis

Yes, this.  I looked into fixing issue 3866 earlier this year, and Kenji's 
list sounds very familiar.

It comes down to - function pointers are not function declarations and 
therefore can't do everything function declarations do, such as overloading 
and default arguments.  This is the price of being able to reassign them.

Yes it is possible to make them work the way Manu has been using them, but 
the solution is messy and I seriously doubt it's worth it.  I agree with 
everything Andrei has said about this.

I don't consider putting default arguments back in the type a valid approach 
because of the reason above, so that leaves giving function pointer 
variables the ability to have default arguments.  This seems to me like a 
really dumb corner case with the same problems.
August 28, 2012
Re: Function pointers/delegates default args were stealth removed?
On 28 August 2012 16:50, Daniel Murphy <yebblies@nospamgmail.com> wrote:

> "Jonathan M Davis" <jmdavisProg@gmx.com> wrote in message
> news:mailman.1446.1346070222.31962.digitalmars-d@puremagic.com...
> >
> > Default arguments just do not make sense with function pointers, because
> > they
> > don't follow the function pointer, because it's a _pointer_ and has no
> > knowledge of what it's pointing to. It's only at the declaration point of
> > the
> > function that the default argument exists, and that has _nothing_ to do
> > with
> > the function pointer. You might as well ask a reference of type Object
> > what
> > the arguments used to construct the derived class that it actually refers
> > to
> > were as expect a function pointer to have any clue about default
> arguments
> > to
> > the function that it points to.
> >
> > - Jonathan M Davis
>
> Yes, this.  I looked into fixing issue 3866 earlier this year, and Kenji's
> list sounds very familiar.
>
> It comes down to - function pointers are not function declarations and
> therefore can't do everything function declarations do, such as overloading
> and default arguments.  This is the price of being able to reassign them.
>
> Yes it is possible to make them work the way Manu has been using them, but
> the solution is messy and I seriously doubt it's worth it.  I agree with
> everything Andrei has said about this.
>
> I don't consider putting default arguments back in the type a valid
> approach
> because of the reason above, so that leaves giving function pointer
> variables the ability to have default arguments.  This seems to me like a
> really dumb corner case with the same problems.
>

Well that's painful for a number of reasons.
Other than the fact that I need to rewrite a bunch of code, I can't
actually produce a solution that works as well in lieu of some feature
requests.

A language feature should be deprecated for some time before it is
surprise-removed like that... that would allow some time to discuss and
possibly implement support for work-arounds.

Since I'll need to create wrapper functions and stubs for *everything*, I
really need __forceinline, or debug builds will really suffer. (That said,
I need it anyway for heaps of other stuff (SIMD in particular), but this
really seals the deal.)
Without it, all function calls require call-through stubs, all my API calls
become double-calls, and debugging becomes really tedious (stepping into
and out of stubs generated by magic that don't really exist every time you
press F11 >_<).

Also, in my case, I really need to be able to forward declare a function in
the same file as it is defined.
The user needs to write the prototypes, and then magic can scan for the
prototypes and generate the stub its self, but they can't currently appear
in the same file like in C/C++.

Without both of those things, my new solutions will be worse. More verbose,
difficult to read&maintain, slower, and really annoying to debug.


Why are you so against default arguments associating with a declaration?
Why is the solution messy?
Default arguments simplify code. If a default is used frequently, it's
better to define it in one place, that is easy to change, and appears with
the definition. It's self-documenting, and very convenient.
August 28, 2012
Re: Function pointers/delegates default args were stealth removed?
On Monday, 27 August 2012 at 12:14:30 UTC, Manu wrote:
> On 27 August 2012 14:08, Carl Sturtivant <sturtivant@gmail.com> 
> wrote:
>
>>
>>> extern(C) void function( ref const(Vector2) v0, ref 
>>> const(Vector2) v1,
>>> ref const(Vector2) v2, ref const(Color) color = Color.white, 
>>> BlendMode
>>> blendMode = BlendMode.Disabled ) fillTriangle2D;
>>>
>>
>> If function pointers could be called with fewer than the 
>> prototypical
>> number of arguments, and the remaining arguments be always 
>> initialized to
>> their .init defaults, you could perhaps make this sort of 
>> thing work
>> without the default argument values by using struct defaults.
>>
>> How would that be deficient?
>>
>
> ... no.
> Color does not .init == Color.white. You're suggesting I define 
> a new type,
> obscuring the API, every time I want a non-.init default arg?
> Also, I think it's correct that functions shouldn't be callable 
> without
> explicit parameters. Default args are carefully selected, and 
> they are
> always opt-in.
> 'v2' in this case shouldn't be allowed to default to [ NaN, NaN 
> ] if I omit
> it.

More specifically, you can get the default initialization of e.g. 
double to be different as follows.

import std.stdio;

struct dbl(double init) {
    double d = init;
    alias d this;
}

void main() {
	dbl!3.142 x;
	dbl!2.0 y;
	writeln(x*y);
}

In the case of an external(C) struct, the D definition can fix up 
its own default initialization without a new type name even. 
Color for example could be fixed up to initialize to Color.white 
by default.

And, having the compiler fix up omitted trailing arguments with 
.init default values could be confined to "opt-in" parameters by 
a small change to the type system for function pointers as 
follows.

The type of a function pointer could now include the number of 
trailing parameters that may be defaulted. This does not explode 
the size of a mangled name much. A syntactic mechanism to 
indicate which trailing parameters may be defaulted in a function 
prototype could be added to D. The default would be none with 
functions declared without that mechanism. This mechanism needs 
to be a part of the prototype so that it can be used on 
external(C) functions etcetera.

Now only trailing parameters that you intend to be defaulted 
would would get defaulted with the .init treatment. Others would 
be compilation errors.

Now what's wrong with this if there are no trailing argument 
defaults except for the .init defaults?
6 7 8 9 10 11 12
Top | Discussion index | About this forum | D home