November 05, 2007
KlausO Wrote:

> Denton Cockburn schrieb:
> > On Fri, 02 Nov 2007 14:03:59 -0700, Walter Bright wrote:
> > 
> >> D 2.007 brings full closures to D. I was tired of D being denigrated for not having "real" closures.
> >>
> > 
> > Nicely Done.  Lisp is looking less special everyday.
> 
> Awesome. Seems it's time to update
> 
> http://www.prowiki.org/wiki4d/wiki.cgi?LanguagesVersusD
>
Someone with more a functional programming background may be able
to enlighten us but doesn't the existence of proper closures allow us to implement monads as a library now? Though I can't quite see in what situation we would want to use them.

> and the next big thing may be first class continuations which has an interesting application in GUI code, see
> 
> http://citeseer.ist.psu.edu/fuchs95escaping.html

Is this not possible via a library too, even without closures? Excuse me if I'm more than half asleep today.

November 05, 2007
Bruce Adams wrote:
> KlausO Wrote:
> Someone with more a functional programming background may be able to
> enlighten us but doesn't the existence of proper closures allow us to
> implement monads as a library now? Though I can't quite see in what
> situation we would want to use them.

Yup, IIRC the poor strictly functional guys needs them for I/O, but as
we're imperative anyway I don't see any applications for monads either.

Regards, Frank
November 05, 2007
KlausO wrote:
> Awesome. Seems it's time to update
> 
> http://www.prowiki.org/wiki4d/wiki.cgi?LanguagesVersusD

And it's time to distuinguish D1 vs. D2...

Regards, Frank
November 06, 2007
On Mon, 05 Nov 2007 22:48:20 +0100, 0ffh wrote:

> KlausO wrote:
>> Awesome. Seems it's time to update
>> 
>> http://www.prowiki.org/wiki4d/wiki.cgi?LanguagesVersusD
> 
> And it's time to distuinguish D1 vs. D2...
> 
> Regards, Frank

Is the goal to be able to many of these things as possible, leaving no one with a reason to use another language? :)

November 06, 2007
0ffh wrote:
> Bruce Adams wrote:
>> KlausO Wrote:
>> Someone with more a functional programming background may be able to
>> enlighten us but doesn't the existence of proper closures allow us to
>> implement monads as a library now? Though I can't quite see in what
>> situation we would want to use them.
> 
> Yup, IIRC the poor strictly functional guys needs them for I/O, but as
> we're imperative anyway I don't see any applications for monads either.

You might like to use monads in a "pure multithreading" environment where the threads are written in pure functional style and are thus safely lock-free.  A monad essentially allows you to defer any necessary locking to a convenient place and time.

Dave
November 06, 2007
>>  It's not an optimal solution because the "does the function escape"
>>  heuristic captures too many functions.
>
> You could let the programmer specify explicitly whether or not to make a function a closure or not, maybe with a key word or something.

A programming language called Vera uses the "shadow" keyword to acheive a somewhat related effect.

From http://www.asic-world.com/vera/concurrency_control1.html:

program shadow_variable {
  spawn_process() ;
  delay(100) ;
  spawn_process_with_shawdow();
  delay(100) ;
}

task print(integer i) {
  printf("   n = %0d\n", i);
}

task spawn_process () {
  integer n;
  printf("In spawn_process\n");
  for(n=0; n<3 ; n++) {
    fork
      print(n) ;
    join none
  }
}

task spawn_process_with_shawdow () {
  shadow integer n;
  printf("In spawn_process_with_shadow_variable\n");
  for(n=0; n<3 ; n++) {
    fork
      print(n) ;
    join none
  }
}

Executing this code gives:
 In spawn_process
    n = 3
    n = 3
    n = 3
 In spawn_process_with_shadow_variable
    n = 0
    n = 1
    n = 2

I am not a language expert, but this seemed related.

Martin
November 06, 2007
Martin d Anjou Wrote:

> >>  It's not an optimal solution because the "does the function escape"
> >>  heuristic captures too many functions.
> >
> > You could let the programmer specify explicitly whether or not to make a function a closure or not, maybe with a key word or something.
> 
> A programming language called Vera uses the "shadow" keyword to acheive a somewhat related effect.
> 
> From http://www.asic-world.com/vera/concurrency_control1.html:
> 
> program shadow_variable {
>    spawn_process() ;
>    delay(100) ;
>    spawn_process_with_shawdow();
>    delay(100) ;
> }
> 
> task print(integer i) {
>    printf("   n = %0d\n", i);
> }
> 
> task spawn_process () {
>    integer n;
>    printf("In spawn_process\n");
>    for(n=0; n<3 ; n++) {
>      fork
>        print(n) ;
>      join none
>    }
> }
> 
> task spawn_process_with_shawdow () {
>    shadow integer n;
>    printf("In spawn_process_with_shadow_variable\n");
>    for(n=0; n<3 ; n++) {
>      fork
>        print(n) ;
>      join none
>    }
> }
> 
> Executing this code gives:
>   In spawn_process
>      n = 3
>      n = 3
>      n = 3
>   In spawn_process_with_shadow_variable
>      n = 0
>      n = 1
>      n = 2
> 
> I am not a language expert, but this seemed related.
> 
> Martin

I see the analogy but this is actually about whether a variable should be shared between 2 threads / processes. I don't think there is a native D equivalent but "shared" has been proposed several times.
This would be more like "export".

November 07, 2007
Dnia Fri, 02 Nov 2007 14:03:59 -0700
Walter Bright <newshound1@digitalmars.com> napisał/a:

> D 2.007 brings full closures to D. I was tired of D being denigrated for not having "real" closures.
> 

Simpler curring?

// not tested
C delegate(B) curry(A, C, B...)(C delegate(A, B) dg_, A a_) {
        auto a = a_;
        auto dg = dg_;
        C add(B b) {
                return dg(a, b);
        }
        return &add;
}


instand of:

// Old code:  http://www.digitalmars.com/d/template.html

R delegate(U) Curry(R, A, U...)(R delegate(A, U) dg, A arg)
{
    struct Foo
    {
	typeof(dg) dg_m;
	typeof(arg) arg_m;

	R bar(U u)
	{
	    return dg_m(arg_m, u);
	}
    }

    Foo* f = new Foo;
    f.dg_m = dg;
    f.arg_m = arg;
    return &f.bar;
}



Also other functional stuff like infinite lazy lists or monads can be done much much simpler now :)

-- 
Witold Baryluk, aleph0
November 07, 2007
Maybe the two inner variables can be omitted  as :


C delegate(B) curry(A, C, B...)(C delegate(A, B) dg_, A a_) {
  C add(B b) {
    return dg_(a_, b);
  };
  return &add;
}


Witold Baryluk 写道:
> Dnia Fri, 02 Nov 2007 14:03:59 -0700
> Walter Bright <newshound1@digitalmars.com> napisał/a:
> 
>> D 2.007 brings full closures to D. I was tired of D being denigrated
>> for not having "real" closures.
>>
> 
> Simpler curring?
> 
> // not tested
> C delegate(B) curry(A, C, B...)(C delegate(A, B) dg_, A a_) {
>         auto a = a_;
>         auto dg = dg_;
>         C add(B b) {
>                 return dg(a, b);
>         }
>         return &add;
> }
> 
> 
> instand of:
> 
> // Old code:  http://www.digitalmars.com/d/template.html
> 
> R delegate(U) Curry(R, A, U...)(R delegate(A, U) dg, A arg)
> {
>     struct Foo
>     {
> 	typeof(dg) dg_m;
> 	typeof(arg) arg_m;
> 
> 	R bar(U u)
> 	{
> 	    return dg_m(arg_m, u);
> 	}
>     }
> 
>     Foo* f = new Foo;
>     f.dg_m = dg;
>     f.arg_m = arg;
>     return &f.bar;
> }
> 
> 
> 
> Also other functional stuff like infinite lazy lists or monads can be
> done much much simpler now :)
> 
November 07, 2007
Or even:

C delegate(B) curry(A, C, B...)(C delegate(A, B) dg_, A a_) {
  return delegate C(B b) { return dg_(a_, b); };
}

outersky wrote:
> Maybe the two inner variables can be omitted  as :
> 
> 
> C delegate(B) curry(A, C, B...)(C delegate(A, B) dg_, A a_) {
>   C add(B b) {
>     return dg_(a_, b);
>   };
>   return &add;
> }
> 
> 
> Witold Baryluk 写道:
>> Dnia Fri, 02 Nov 2007 14:03:59 -0700
>> Walter Bright <newshound1@digitalmars.com> napisał/a:
>>
>>> D 2.007 brings full closures to D. I was tired of D being denigrated
>>> for not having "real" closures.
>>>
>>
>> Simpler curring?
>>
>> // not tested
>> C delegate(B) curry(A, C, B...)(C delegate(A, B) dg_, A a_) {
>>         auto a = a_;
>>         auto dg = dg_;
>>         C add(B b) {
>>                 return dg(a, b);
>>         }
>>         return &add;
>> }
>>
>>
>> instand of:
>>
>> // Old code:  http://www.digitalmars.com/d/template.html
>>
>> R delegate(U) Curry(R, A, U...)(R delegate(A, U) dg, A arg)
>> {
>>     struct Foo
>>     {
>>     typeof(dg) dg_m;
>>     typeof(arg) arg_m;
>>
>>     R bar(U u)
>>     {
>>         return dg_m(arg_m, u);
>>     }
>>     }
>>
>>     Foo* f = new Foo;
>>     f.dg_m = dg;
>>     f.arg_m = arg;
>>     return &f.bar;
>> }
>>
>>
>>
>> Also other functional stuff like infinite lazy lists or monads can be
>> done much much simpler now :)
>>