6 ms·
I understand the "capturing i in a closure by reference" part, since that error is also common in other languages which capture variables by reference, and don'
by Matthias247 10y ago
I understand the "capturing i in a closure by reference" part, since that error is also common in other languages which capture variables by reference, and don't create a new reference per loop iteration.
However the default parameter issue looks like a python specific issue which is really strangely designed. I would normally say [] is a literal for an empty list which creates a new instance of an empty list every time it's used. So when it's used as a default parameter a fresh empty list should be created all times.
Is [] is global reference to a single mutable list which is only initially empty? That would make it pretty useless, since everyone could mutate it. If it's a single reference then that should at least be an immutable list which throws some exception when someone messes around with it.
- zaptheimpaler 10y ago>Is [] is global reference to a single mutable list which is only initially empty? No, the problem is default arguments to methods are evaluated once, when the method is created and that value is used for all calls. I don't know why that is, its definitely strange - any other language would evaluate the default args each time a function is called just like the regular args.
- jVint 10y agoThen you would have the problem that something like mydefault=3, def f(default=mydefault):... would change it's evaluation if anyone ever defined mydefault=4. That would leave users unable to define any variable thats ever mentioned in default values of any function in any library they are using without causing very unexpected behaviors. What languages are you thinking of where default values set to a references are set to a copy of that reference as it was at definition time at every evaluation?
- zaptheimpaler 10y agoNot sure if i completely understand, but the example you mentioned would work in Scala. If a mutable variable is referenced in default args, its value at define-time is used. Example: scala> var x = 5 x: Int = 5 scala> def func(arg1: Int = (x+1)) = { println(arg1)} func: (arg1: Int)Unit scala> func() 6 scala> var x = 7 x: Int = 7 scala> func() 6 //unchanged For reference vars the closure captures a local copy: scala> var list = List(1,2,3) list: List[Int] = List(1, 2, 3) scala> def printList(arg1: List[Int] = lis) = { println(arg1) } printList: (arg1: List[Int])Unit scala> printList() List(1, 2, 3) scala> var list = List(4,5,6) list: List[Int] = List(4, 5, 6) scala> printList() List(1, 2, 3)