Skip to content

Error in evaluation of function default arguments #649

Open

Description

@faerot
x = []

for i in range(5):
    x.append(lambda i=i: print(i))

for c in x:
    c()

python output:

0
1
2
3
4

javascript output:

undefined
undefined
undefined
undefined
undefined

The problem is transcrypt postpones evaluation of default arguments to inside function:

export var x = [];
for (var i = 0; i < 5; i++) {
    x.append ((function __lambda__ (i) {
        if (typeof i == 'undefined' || (i != null && i.hasOwnProperty ("__kwargtrans__"))) {;
            var i = i;
        };
        return print (i);
    }));
}
for (var c of x) {
    c ();
}

To fix it we need to wrap function declaration in another closure and have default values locked inside that function call like this:

export var x = [];
for (var i = 0; i < 5; i++) {
    x.append (
    (function() {
        var default_i = i;
        return (function __lambda__ (i) {
            if (typeof i == 'undefined' || (i != null && i.hasOwnProperty ("__kwargtrans__"))) {
                var i = default_i;
            };
            return print (i);
        });
    })()
    
    );
}
for (var c of x) {
    c ();
}

Activity

  1. faerot commented on Jul 3, 2019

    @faerot
    Author

    Ok, looks like it was already reviewed 3 years ago here:
    #36
    and it was suggested to consider it a transcrypt "limitation", but what about my suggested solution above? This requires minimal overhead but should provide correct behavior with python.

  2. self-assigned this
    on Aug 14, 2019
  3. JdeH commented on Aug 14, 2019

    @JdeH
    Collaborator

    I find the current limitation very annoying and will take a good look at your solution!

  4. trenta3 commented on Jul 16, 2021

    @trenta3

    Is there any update on this issue?
    This basically prevents using partially evaluated functions to pass around as values.
    In my usage this is pretty worrysome!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

Type

No type

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions