May 09, 2015 Re: Lambda functions in D | ||||
---|---|---|---|---|
| ||||
Posted in reply to Russel Winder | On 05/09/2015 10:45 AM, Russel Winder via Digitalmars-d-learn wrote:
> On Sat, 2015-05-09 at 09:49 -0700, Ali Çehreli via Digitalmars-d-learn wrote:
>>
> […]
>> BigInt factorial(size_t n)
>> {
>> return bigInts(1).take(n).reduce!((a, b) => a *= b);
>> }
>
> I wonder if that should be a * b rather than a *= b?
Yes. :) Luckily, the difference is an unused side-effect to parameter 'a' in my wrong version.
Ali
|
May 09, 2015 Re: Lambda functions in D | ||||
---|---|---|---|---|
| ||||
Posted in reply to Dennis Ritchie | On 05/09/2015 05:52 PM, Dennis Ritchie wrote: > On Saturday, 9 May 2015 at 14:15:21 UTC, Ali Çehreli wrote: >> On 05/09/2015 04:59 AM, Dennis Ritchie wrote: >>> On Saturday, 9 May 2015 at 11:49:48 UTC, Timon Gehr wrote: >>>> assert((function int(int >>>> x)=>x?x*__traits(parent,{})(x-1):1)(10)==3628800); >>> >>> Thanks. Yes, it is similar to what I wanted :) >> >> Also interesting: >> >> http://rosettacode.org/wiki/Y_combinator#D >> >> I think that code was improved by Timon Gehr as well. >> >> Ali > > Yes, it's much better. Well, it is much slower due to all the allocated closures, owed to the fact that the implementations of 'fix' on that page are expected to mirror a particular famous implementation in untyped lambda calculus. In case you have a use for 'fix', a more efficient implementation might be: auto fix(S,T...)(S delegate(T) delegate (S delegate(T)) f){ S delegate(T) g=(T a){ assert(0,"f is too eager."); }; return g=f((T a)=>g(a)); } (In particular, this will only allocate two closures for the plumbing instead of a number of them linear in the number of recursive invocations.) > Even something like Common Lisp. (Be aware that Common Lisp implementations typically have better garbage collectors than what is available for D.) |
May 09, 2015 Re: Lambda functions in D | ||||
---|---|---|---|---|
| ||||
Posted in reply to Timon Gehr | On Saturday, 9 May 2015 at 21:48:05 UTC, Timon Gehr wrote:
> Well, it is much slower due to all the allocated closures, owed to the fact that the implementations of 'fix' on that page are expected to mirror a particular famous implementation in untyped lambda calculus.
>
> In case you have a use for 'fix', a more efficient implementation might be:
>
> auto fix(S,T...)(S delegate(T) delegate (S delegate(T)) f){
> S delegate(T) g=(T a){ assert(0,"f is too eager."); };
> return g=f((T a)=>g(a));
> }
>
> (In particular, this will only allocate two closures for the plumbing instead of a number of them linear in the number of recursive invocations.)
>
>
>> Even something like Common Lisp.
>
> (Be aware that Common Lisp implementations typically have better garbage collectors than what is available for D.)
Maybe in the future, that D will be added to optimize tail recursion delegates?
And why garbage collectors in Lisp is better?
|
Copyright © 1999-2021 by the D Language Foundation