[Prev][Next][Index][Thread]

Re: Does my ideal language exist?



In article <bruce-409501.17064326062000@news.akl.ihug.co.nz>, Bruce 
Hoult <bruce@hoult.org> wrote:

> define macro with-collect
>   { with-collect (?:name, ?more-names:*) ?:body end }
>     => {let vals = #();
>         local method ?name(item) vals := pair(item, vals) end;
>         let (#rest results) = with-collect (?more-names) ?body end;
>         apply(values, reverse!(vals), results);}
>   { with-collect () ?:body end } => { ?body; values() }
> end;
>
> define function dotest()
>   with-collect (c1, c2)
>     for (i from 0 below 10)
>       if (odd?(i)) c1(i) else c2(i) end;
>     end;
>   end;
> end dotest;


Actually, one thing confuses me here.

I can instead write the base case as...

   { with-collect () ?:body end } => { ?body }

... and it works just fine.  The downside is that (as you'd expect) you 
get a third, spurious result returned from dotest(), namely the result 
of the body which, being a for() with no explicit return value, is #f.

The confusing part is that this way generates quite a bit better code 
for the reverse!()'s and the multiple value return -- the two calls to 
values_sequence() and the call to make_rest_arg_FUN() are completely 
gone!

This remains true even if I add several more collectors to dotest():

define function dotest()
  with-collect (c1, c2, c3, c4)
    for (i from 0 below 10)
      if (odd?(i)) c1(i) else c2(i) end;
      c3(i + 7);
      c4(i * 10);
    end;
    123456;
  end;
end dotest;

The function epilog is now:

    L_arg1 = dylanZdylan_visceraZreverseD_METH
       (orig_sp, L_vals_4, dylanZliteral_67.heapptr);
    L_arg1_2 = dylanZdylan_visceraZreverseD_METH
       (orig_sp, L_vals_3, dylanZliteral_67.heapptr);
    L_arg1_3 = dylanZdylan_visceraZreverseD_METH
       (orig_sp, L_vals_2, dylanZliteral_67.heapptr);
    L_arg1_4 = dylanZdylan_visceraZreverseD_METH
       (orig_sp, L_vals, dylanZliteral_67.heapptr);
    L_temp_9.heapptr = L_arg1_4;
    L_temp_9.dataword.l = 0;
    orig_sp[0] = L_temp_9;
    L_temp_10.heapptr = L_arg1_3;
    L_temp_10.dataword.l = 0;
    orig_sp[1] = L_temp_10;
    L_temp_11.heapptr = L_arg1_2;
    L_temp_11.dataword.l = 0;
    orig_sp[2] = L_temp_11;
    L_temp_12.heapptr = L_arg1;
    L_temp_12.dataword.l = 0;
    orig_sp[3] = L_temp_12;
    L_temp_13.heapptr = collectZliteral.heapptr;
    L_temp_13.dataword.l = 123456;
    orig_sp[4] = L_temp_13;
    return orig_sp + 5;

Does anyone understand this?  Changing the original values() to read 
values(123456) or values("sex") also produces the good code above, but 
an empty values() causes really bad code.

What is it that the empty values() is doing?  Surely a bug?

-- Bruce



Follow-Ups: References: