October 29, 2007

BCS wrote:
> Reply to Benjamin,
> ...
>> how the heck is that parsing?? Is the /map/ actualy this:
>>
>> (A / B) / C; ??
>>
> 
> BTW if that is what you are doing, I may be force to do something totally EVIL to reclaim some ground in the "does nasty things with D" ranking. I have a few ideas though....  }:-)  (BBBBWWWWAAAA HAA Haa haaa.....)

IIRC, map is basically defined like this:

struct map
{
  static map_ opDiv_r(T)(some_array_type!(T));
}

struct map_
{
  some_array_type!(T) opDiv(T)(some_delegate_type!(T));
}

Or something similar.

	-- Daniel
October 29, 2007
Daniel Keep wrote:
> 
> BCS wrote:
>> Reply to Benjamin,
>> ...
>>> how the heck is that parsing?? Is the /map/ actualy this:
>>>
>>> (A / B) / C; ??
>>>
>> BTW if that is what you are doing, I may be force to do something totally EVIL to reclaim some ground in the "does nasty things with D" ranking. I have a few ideas though....  }:-)  (BBBBWWWWAAAA HAA Haa haaa.....)

Looking forward to it! :)
The world needs more weird and disturbing things. Shake it up.

> 
> IIRC, map is basically defined like this:
> 
> struct map
> {
>   static map_ opDiv_r(T)(some_array_type!(T));
> }
> 
> struct map_
> {
>   some_array_type!(T) opDiv(T)(some_delegate_type!(T));
> }
> 
> Or something similar.
> 
> 	-- Daniel

Yes exactly; though I have all the ugliness packed around in a template.


Quote from the respective file:
>
> mixin(Operator!("map", "
>   static if (is(ReturnType!(RHS)==void)) {
>     foreach (ref entry; lhs) rhs(mixin(Value!(ElemType!(LHS), RHS,
"~Quote!("entry")~")));
>   } else {
>     auto res=new ReturnType!(RHS)[lhs.length];
>     foreach (id, ref entry; res)
entry=rhs(mixin(Value!(ElemType!(LHS), RHS, "~Quote!("lhs[id]")~")));
>     return res;
>   }
> "));
>
October 29, 2007
downs wrote:
> Daniel Keep wrote:
>> BCS wrote:
>>> Reply to Benjamin,
>>> ...
>>>> how the heck is that parsing?? Is the /map/ actualy this:
>>>>
>>>> (A / B) / C; ??
>>>>
>>> BTW if that is what you are doing, I may be force to do something
>>> totally EVIL to reclaim some ground in the "does nasty things with D"
>>> ranking. I have a few ideas though....  }:-)  (BBBBWWWWAAAA HAA Haa
>>> haaa.....)
> 
> Looking forward to it! :)
> The world needs more weird and disturbing things. Shake it up.
> 
>> IIRC, map is basically defined like this:
>>
>> struct map
>> {
>>   static map_ opDiv_r(T)(some_array_type!(T));
>> }
>>
>> struct map_
>> {
>>   some_array_type!(T) opDiv(T)(some_delegate_type!(T));
>> }
>>
>> Or something similar.
>>
>> 	-- Daniel
> 
> Yes exactly; though I have all the ugliness packed around in a template.

Does it compile down to the same code as just a plain call to a map() function?  (Or is there some other benefit that justifies the extra runtime cost and loss of readability?)

--bb
October 29, 2007
downs Wrote:
> > ["Load ", "Prefetch ", "Prefetch "] /zip/ ([0, 1, 2] /map/ (&info
> /rfix/ currentComic /fix/ (&subtract!(int) /fix/ currentStrip))) /map/
> &concat!(string) /zip/ [&update, &prefetch /fix/ (currentStrip-1),
> &prefetch /fix/ (currentStrip-2)] /map/ &Pool.addTask;

I too have developed a large functional-style lib for D, but I think D needs a bit more built-in support for it (the first class functions, allowing a better syntax, etc) and you need to program in a more tidy way :-)

bearophile
October 29, 2007
Bill Baxter wrote:
> 
> Does it compile down to the same code as just a plain call to a map()
> function?  (Or is there some other benefit that justifies the extra
> runtime cost and loss of readability?)
> 
> --bb

Loss of readability is debatable. Personally I like it better, or else I
wouldn't use it. :)
The runtime cost might not be as high as you expect. Let us do a test.

>
> module test12;
> import std.stdio;
> import tools.base, tools.functional, tools.log;
>
> int add(int a, int b) { return a+b; }
>
> mixin(Operator!("add3", "return lhs+rhs;"));
>
> void main() {
>   const long count=1_000_000_000;
>   long test;
>   int delegate(int, int) add1=(int a, int b) { return add(a, b); };
>   int function(int, int) add2=&add;
>   logln("Function: ", time({ for (int i=0; i<count; ++i) test+=add(0,
1); }), " -test ", test);
>   logln("Delegate function: ", time({ for (int i=0; i<count; ++i)
test+=add1(0, 1); }), " -test ", test);
>   logln("Function ... function: ", time({ for (int i=0; i<count; ++i)
test+=add2(0, 1); }), " -test ", test);
>   logln("Infix function: ", time({ for (int i=0; i<count; ++i) test+=0
/add3/ 1; }), " -test ", test);
> }
>

The results:

> gentoo-pc ~/d $ gdc test12.d -o test12 -O3 -frelease -Itools
tools/tools/*.d && ./test12
> /--[ Main Thread ]------
> | Function: 0 -test 1000000000
> | Delegate function: 7234 -test 2000000000
> | Function ... function: 6415 -test -1294967296
> | Infix function: 1501 -test -294967296
> \-----------------------------
>

Hm ... interesting.
I had expected the infix function to be inlined as well as the straight
function. Ah well. Four times the speed of an un-inlined function is
good enough for me. :)
1 2
Next ›   Last »