Iterable emulation in transcrypt

117 Views Asked by At

I've been trying to port a vector math library to transcrypt and I've bumped into an issue with emulating iterable types.

I've got a Vector class with an inner iterable. Here's a simplified version of the core:

class Vector:
    def __init__(self, *values):
        self.values = values

    def __iter__(self):
        for item in self.values:
            yield item

    def __add__(self, other):
        return Vector( *(x + y for x, y in zip(self, other)))

In pure python (Vector(1,2,3) + Vector(3,4,5)) returns Vector(4,6,8) as you'd expect. But after transcryption, the same code fails -- in Javascript it appears that zip() is expecting a Javascript map() function on its iterable objects.

I can work around it in this case by explicitly targeting the underlying storage, which -- since it's created with a *args -- seems to have the required method:

def __add__(self, other):
    pairwise = zip(self.values, other.values)
    return Vector( *(itertools.starmap(lambda a, b: a + b, pairwise)))

but coupling that to the inner container feels rickety to me and I assume theres overhead for creating the iterator and the starmap.

So -- what's the right way to work around this? Can I add a map() to the class? And if so, what's the right signature? The underlying JS seems to rely on JS scoping behavior... which scares me...

1

There are 1 best solutions below

0
On

The point is that zip has not yet been adapted for iterators. A simple workaround is converting the args of zip to lists. The following code works:

class Vector:
    def __init__(self, *values):
        self.values = values

    def __iter__(self):
        for item in self.values:
            yield item

    def __add__(self, other):
        return Vector( *(x + y for x, y in zip(list (self), list (other))))

    def __str__ (self):
        return self.values

#__pragma__ ('opov')

print (Vector(1,2,3) + Vector(3,4,5))

#__pragma__ ('noopov')

This will print:

4,6,8

Sorry for the late answer, have been a bit thinly spread the past few months. Adapting zip for iterators I found quite complicated, that's why it wasn't done yet.

Come to think of it, converting the params to lists could be done automagically. I will add that (issue #369), despite the (tiny) overhead by the runtime test, because it better matches expected behavior.

It is in release 3.6.44 and your code should now work correctly without alterations (using the -e 6 switch to activate iterators).