Thread overview
workaround for closure problem needed
Dec 26, 2007
mandel
Dec 27, 2007
BCS
Dec 27, 2007
Jérôme M. Berger
Dec 27, 2007
Bill Baxter
Dec 27, 2007
Jérôme M. Berger
Dec 27, 2007
BCS
Dec 27, 2007
mandel
December 26, 2007
Hi,

I have a problem with closures and D 1.024.
D2 does have full closure support, but I have to stick with D1
for now.

Problem: variable "state" changes silently when the anonymous
function goes out of the scope of function filter.
Therefore the program does print out "item" only once.

My question is if there is a workaround ("static state" wouldn't be thread safe)?

import tango.io.Stdout;
import tango.util.collection.iterator.FilteringIterator;
import tango.util.collection.iterator.ArrayIterator;
import tango.util.collection.model.Iterator;

class A
{
        uint getState() { return 0; }
}

Iterator!(A) filter(Iterator!(A) iter)
{
        uint state = 0;
        return new FilteringIterator!(A)( iter, (A item) {
                return (item.getState == state); //should always return true
        });
}

void main(char[][] args)
{
        A[] aa = new A[10];
        foreach(inout a; aa) a = new A;

        auto array_iter = new ArrayIterator!(A)(aa);
        auto iter = filter(array_iter);

        foreach(a; iter)
        {
                Stdout("item").newline;
        }
}
December 27, 2007
Reply to Mandel,

> Hi,
> 
> I have a problem with closures and D 1.024.
> D2 does have full closure support, but I have to stick with D1
> for now.
> Problem: variable "state" changes silently when the anonymous
> function goes out of the scope of function filter.
> Therefore the program does print out "item" only once.
> My question is if there is a workaround ("static state" wouldn't be
> thread safe)?
> 

wrap the stuff (state + the local function) in a local struct, new off an instance at the top of the outer function, convert the outer function's access to "state" into "inst.state" and then replace the anon delegate with "&inst.fn". Crude and a bit ugly but it works.

OTOH (WARNING: TOTAL HACK) if you want to go one step cheaper; state is 32bits, the same as a void*.

struct Wrap
{
 bool func(A item)
 {
   Cast c;
   c.pt = this;    return (item.getState == c.ui); //should always return true
 }
}

union Cast {Wrap* pt; uint ui;}

//to get dg;

Cast c;
c.ui = state;
&c.pt.func;

this works only if state is the only thing used and if it is not changed.


December 27, 2007
BCS wrote:
> OTOH (WARNING: TOTAL HACK) if you want to go one step cheaper; state is
> 32bits, the same as a void*.
> 
	Doesn't work on 64 bits platforms!

		Jerome
- --
+------------------------- Jerome M. BERGER ---------------------+
|    mailto:jeberger@free.fr      | ICQ:    238062172            |
|    http://jeberger.free.fr/     | Jabber: jeberger@jabber.fr   |
+---------------------------------+------------------------------+
December 27, 2007
Jérôme M. Berger wrote:
> -----BEGIN PGP SIGNED MESSAGE-----
> Hash: SHA1
> 
> BCS wrote:
>> OTOH (WARNING: TOTAL HACK) if you want to go one step cheaper; state is
>> 32bits, the same as a void*.
>>
> 	Doesn't work on 64 bits platforms!

Neither does DMD!

;-)

--bb
December 27, 2007
Bill Baxter wrote:
> Jérôme M. Berger wrote:
>> -----BEGIN PGP SIGNED MESSAGE-----
>> Hash: SHA1
>>
>> BCS wrote:
>>> OTOH (WARNING: TOTAL HACK) if you want to go one step cheaper; state is
>>> 32bits, the same as a void*.
>>>
>>     Doesn't work on 64 bits platforms!
> 
> Neither does DMD!
> 
> ;-)
> 
	True, but gdc works fine ;)

		Jerome
- --
+------------------------- Jerome M. BERGER ---------------------+
|    mailto:jeberger@free.fr      | ICQ:    238062172            |
|    http://jeberger.free.fr/     | Jabber: jeberger@jabber.fr   |
+---------------------------------+------------------------------+
December 27, 2007
ok,

I was able to relax the contrains and solved the issue now by introducing a helper class to bind the value to the function.

I can drop the helper classes when my code can move over to D2.0 and make use of full closure support.
December 27, 2007
Reply to Jérôme,

> -----BEGIN PGP SIGNED MESSAGE-----
> Hash: SHA1
> 
> BCS wrote:
> 
>> OTOH (WARNING: TOTAL HACK) if you want to go one step cheaper; state
>> is 32bits, the same as a void*.
>> 
> Doesn't work on 64 bits platforms!
> 

Actually it should work. You Just get 32bits of junk passed around that is ignored. The reverse is the one that wont work (ulong+64bit works but ulong+32bit fails)

To be on the safe side the union should have:

static assert((void*).sizeof >= Union.sizeof);

and the other struct should have:

static assert(0 == Struct.sizeof);

> Jerome
> - --
> +------------------------- Jerome M. BERGER ---------------------+
> |    mailto:jeberger@free.fr      | ICQ:    238062172            |
> |    http://jeberger.free.fr/     | Jabber: jeberger@jabber.fr   |
> +---------------------------------+------------------------------+
> -----BEGIN PGP SIGNATURE-----
>> Version: GnuPG v1.4.7 (GNU/Linux)
>> 
>> iD8DBQFHc1led0kWM4JG3k8RAsc9AJ43BIXYijvUF18cIBOVIZA1vvdO8QCeJb04
>> /12efoBUeayhetlzXHSfkTY=
>> =1kBl
> -----END PGP SIGNATURE-----