August 31, 2013
On 2013-08-31 14:03, Andrej Mitrovic wrote:

> How will you pass a pointer to a constructor?

No, you invoke the constructor via a pointer.

https://github.com/D-Programming-Language/phobos/blob/master/std/conv.d#L4391

Replace that line with:

auto dg = &result.__ctor;
dg(args);

The static-if needs to be adjusted as well.

-- 
/Jacob Carlborg
August 31, 2013
On 8/31/13, Andrei Alexandrescu <SeeWebsiteForEmail@erdani.org> wrote:
> Library issues are a lot easier to deal with than core language issues.

Not when you have Kenji around!
August 31, 2013
On 8/31/13, Jacob Carlborg <doob@me.com> wrote:
> Replace that line with:
>
> auto dg = &result.__ctor;
> dg(args);

Hmm... I hope this can actually work when there are multiple ctors, how would the compiler know which of the ctors dg should be assigned to?
August 31, 2013
On 2013-08-31 20:28, Andrej Mitrovic wrote:

> Hmm... I hope this can actually work when there are multiple ctors,
> how would the compiler know which of the ctors dg should be assigned
> to?

Apparently you cannot use "auto" when having an overloaded symbol, so just use an explicit type:

T delegate (Args) dg = &result.__ctor;
dg(args);

-- 
/Jacob Carlborg
August 31, 2013
On 8/31/13, Jacob Carlborg <doob@me.com> wrote:
> T delegate (Args) dg = &result.__ctor;
> dg(args);

Ah, pretty cool workaround.
August 31, 2013
On 31.08.2013 21:52, Andrej Mitrovic wrote:
> On 8/31/13, Jacob Carlborg <doob@me.com> wrote:
>> T delegate (Args) dg = &result.__ctor;
>> dg(args);
>
> Ah, pretty cool workaround.

Then, why not close that old bug?
August 31, 2013
On 8/31/13, Piotr Szturmaj <bncrbme@jadamspam.pl> wrote:
> On 31.08.2013 21:52, Andrej Mitrovic wrote:
>> On 8/31/13, Jacob Carlborg <doob@me.com> wrote:
>>> T delegate (Args) dg = &result.__ctor;
>>> dg(args);
>>
>> Ah, pretty cool workaround.
>
> Then, why not close that old bug?
>

It needs to be fixed first.
August 31, 2013
On Friday, 30 August 2013 at 21:11:32 UTC, Andrei Alexandrescu wrote:
> * scope: cute and dangerous in equal proportions - great for a movie character, terrible for language design.

I'll argue for it and others can then destroy.

IME, a lot of the value of functional programming (by which I mean, programming with higher order functions) can be had with downward funargs, as found in Pascal (and more recently, Ada), which don't require garbage collection.

The D language expresses closures and higher order functions as delegates, and uses the heap to manage these. I had assumed that we could use 'scope' on the delegate being passed to prevent it's heap allocation, as discussed here:

  http://stackoverflow.com/questions/4711309/meaning-of-scope-in-d-for-a-parameter

I wrote a small test case to try this out, in which I construct a 2-D integration function from a 1-D one, and I use Adam Ruppe's nogc code to seg fault when the GC is hit. Without using a 'scope' on a local variable, I'm forced to pile up the anonymous function calls to get the behavior I want.

import std.stdio, std.math;

// int delegate(int) adder(int a) { return (int b) { return a + b;}; }

float integrate(scope float delegate(float x) f, float lo, float hi, size_t n) {
  float result = 0.0;
  float dx = (hi - lo) / n;
  for (size_t i = 0; i < n; i++) {
    result += f(lo + i * dx) * dx;
  }
  return result;
}

float integrate(scope float delegate(float, float) f,
                 float x0, float x1,
                 float y0, float y1,
                 size_t nX, size_t nY) {
  scope auto f_y = delegate float(float y) =>
    integrate(delegate(float x) => f(x,y), x0, x1, nX);

  return integrate(f_y, y0, y1, nY);

  // I'll have to write it like this to avoid heap allocation without
  // local variable scope
  // return integrate((y) => integrate((x) =>f(x,y), x0, x1, nX), y0, y1, nY);
}

The code to test demonstrates the issue better, as I'm forced to use inline anonymous functions everywhere to avoid the GC calls (unitCircle and unitSphere omitted for brevity)


void main() {
  scope auto funcX_1 = delegate float(float x) => unitCircle(x);
  float result1 = integrate(funcX_1 /* (x) => unitCircle(x) */, -1.0, 1.0, 500);
  writefln("integrate(func1, -1.0, 1.0, 500) = %g", result1);

  scope auto funcXY_1 = delegate float(float x, float y) => unitSphere(x,y);
  result1 = integrate(funcXY_1 /* (x,y) => unitSphere(x,y) */, -1.0, 1.0,  -1.0, 1.0, 100, 100);
  writefln("integrate(funcXY_1, -1.0, 1.0,  -1.0, 1.0, 100, 100) = %g", result1);
}

Yes, it's a toy example, but I do program with higher order functions a lot in OCaml and I'd probably use them quite a bit in D, especially if I could avoid impacting the GC.

If scope on local variables is going away, it would be nice if the compiler could figure out when I'm using delegate args in a 'downward, non escaping' way and not heap allocate. My tests with DMD indicate that without those 'scope' on the local variable the GC does in fact get hit, and with them it does not.

-- Brian

PS: I don't really use classes much, so I have little to say about scope on objects

PPS: If my missive made little sense,

https://en.wikipedia.org/wiki/Funarg_problem
http://stackoverflow.com/questions/581182/what-are-downward-funargs







August 31, 2013
On 8/31/13 1:34 PM, Brian Rogoff wrote:
> On Friday, 30 August 2013 at 21:11:32 UTC, Andrei Alexandrescu wrote:
>> * scope: cute and dangerous in equal proportions - great for a movie
>> character, terrible for language design.
>
> I'll argue for it and others can then destroy.
>
> IME, a lot of the value of functional programming (by which I mean,
> programming with higher order functions) can be had with downward
> funargs, as found in Pascal (and more recently, Ada), which don't
> require garbage collection.
>
> The D language expresses closures and higher order functions as
> delegates, and uses the heap to manage these. I had assumed that we
> could use 'scope' on the delegate being passed to prevent it's heap
> allocation, as discussed here:
>
> http://stackoverflow.com/questions/4711309/meaning-of-scope-in-d-for-a-parameter

That use will stay and is useful and uncontested.

Andrei

August 31, 2013
On Saturday, 31 August 2013 at 21:30:40 UTC, Andrei Alexandrescu wrote:

>> http://stackoverflow.com/questions/4711309/meaning-of-scope-in-d-for-a-parameter
>
> That use will stay and is useful and uncontested.
>
> Andrei

Sure, but my complaint is that that useful style is cramped by the inability to have scope on *local variables*. I understand that scope on function parameters will stay. If you're saying that scope on local variables for delegates will stay, then disregard all I've written here, I'm happy! :-).

If you look at the code I posted, try removing scope from the 2-D integrate and from the local variable declarations in the main() function, and the program hits the GC, with the scopes, they don't. The problem occurs when I create the local variables to name an anonymous function. I tested this with Adam Ruppe's code which halts when the GC is called.

As I said, I'm not arguing for scope on objects, but for contrivances which allow me to program easily with downward funargs and not hit the GC. D goes further than most languages in this and it would be a shame if this capability is removed with no substitute.

For those who want to test on their systems, here are the trivial unitCircle and unitSphere I omitted.


float unitCircle(float x) {
  float x2 = x * x;
  if (x2 < 1.0) {
    return sqrt(1.0 - x2);
  } else {
    return 0.0;
  }
}

float unitSphere(float x, float y) {
  float sum = x*x + y*y;
  if (sum <= 1.0) {
    return sqrt(1.0 - sum);
  } else {
    return 0.0;
  }
}


-- Brian