DMD 0.170 release

Tom S h3r3tic at remove.mat.uni.torun.pl
Tue Oct 17 19:51:41 PDT 2006


Bill Baxter wrote:
> Tom S wrote:
>> Bill Baxter wrote:
>>> Bill Baxter wrote:
>>>> Is there any reason for not allowing a function to be used too?
>>>> Then you could also use a closure as the thing that does the iteration:
>>>
>>> Ok, I just realized that "delegate" can also be pointer to a 
>>> non-static nested function...  Duh.  So my question should have been 
>>> -- why doesn't this work?
>>>
>>> int delegate(int delegate(inout ElemT))
>>> reversed(AggregateT,ElemT)(AggregateT array)
>>> {
>>>     int _innerFunc(int delegate(inout ElemT) loopBody)
>>>     {
>>>         int done = 0;
>>>         for (int i = array.length-1; i >=0; i--)
>>>         {
>>>             done = loopBody(array[i]);
>>>             if (done)
>>>                 break;
>>>         }
>>>         return done;
>>>     }
>>>     return &_innerFunc;
>>> }
>>>   ...
>>> foreach(real r; reversed!(real[],real)(areal))
>>> {...}
>>>
>>> Compiles but gives:
>>> "Error: Access Violation"
>>>
>>> I'm not totally clear on how pointers/objects are handled in D.  It 
>>> looks the call to reversed() is maybe creating a copy of the data?  
>>> If I put in printfs the pointer value is different from that of the 
>>> original int[].
>>
>> Basically, when you leave 'reversed', any stack data defined within 
>> that function becomes invalid, as D doesn't support real closures. 
>> What you're aiming for can be achieved without the new feature anyway, 
>> e.g. through:
>>
>> ----
>> import std.stdio;
>>
>>
>> struct reverse__(AggregType) {
>>     alias typeof(AggregType[0]) ElemType;
>>     AggregType arr;
>>     int opApply(int delegate(inout ElemType) dg) {
>>         int ret = 0;
>>         for (int i = arr.length -1; i >= 0; --i){
>>             ret = dg(arr[i]);
>>             if (ret) break;
>>         }
>>         return ret;
>>     }
>> }
>>
>> reverse__!(T) reverse(T)(T x) {
>>     reverse__!(T) res;
>>     res.arr = x;
>>     return res;
>> }
>>
>>
>> void main() {
>>     char[] foo = "foo bar";
>>     foreach (c; foo.reverse) {
>>         writefln(c);
>>     }
>> }
> 
> Did you mean
>    foreach (c; reverse(foo)) ??
> I guess so.  it does seem to compile that way.

Actually I meant foo.reverse. It compiles and runs fine on .169


> I think this falls into Walter's "dummy classes and hackish stuff" 
> category though.

It's not that bad. There's just one small dummy struct that resides on 
the stack. The rest is a function that returns it and a generic 
implementation of 'reverse' that will work on any array type.


> Is there no way to make something similar work with a nested function? 
> If my reversed function above could just get the pointer to the actual 
> array then it seems like it should work.  Is there some way to declare 
> the AggregateT array parameter so that that happens?


Not without dummy classes and hackish stuff <g>


--
Tomasz Stachowiak



More information about the Digitalmars-d-announce mailing list