Hacker Newsnew | past | comments | ask | show | jobs | submitlogin

It's incredibly confusing if you naively use a list as a default argument, e.g.

    def foo(some_list=[]):
        ...
        some_list.append(3)
        ...
Since the default is constructed when the function is evaluated, it's the same list, but only when the default is used.

Or the n00b's attempt to use lambdas:

    def list_of_lambdas(x):
        result = []
        for n in range(x):
            result.append(lambda m: n + m)
        return result

    for func in list_of_lambdas(3):
        print(func(3))

    5
    5
    5
(All the closures share the same "cell", meaning the same "n", which is 2 at the end of that loop. Worse, if you 'yield lambda ...', that example would look like it worked. So, yes, Python absolutely has references.)


Yes indeed, that's a bug-prone misfeature of Python.

Perl and JavaScript both get default arguments right: They make a new array on each call.

Perl and JavaScript also get the for-loop closures right as well. In Perl, "for (my $n = ...)" and in JavaScript "for (let n = ...)" will both create a new "cell" each time around the loop, so closures work as expected.

(However, MSIE's version of "let" doesn't create a new "cell" each time, and this can be a source of difficult to see event callback bugs; best transpiled out.)


Perl has default arguments (outside of Devel::Declare trickery)?


Yes, built-in since Perl 5.20, released mid 2014.

  use experimental qw(signatures);

  sub plus_one($x = 100) {
      return $x + 1;
  }

  # Says 6.
  say plus_one(5);

  # Says 101.
  say plus_one();
(The subroutine signatures feature is still marked experimental, which is a shame. I use it in virtually all my code, unless I want pre-5.20 compatibility.)


Neat, thanks! I can't use it unfortunately (the little Perl I still write targets 5.8 on ancient CentOS, but that's not the language's fault).

Good to see it still evolving!




Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: