Default parameters are a great convenience in most modern programming languages. Default parameters fix the ‘default’ parameter to a function, in case the parameter is not available. For example, a function greet_hello(name='david')
would give 'hello david
, but greet(name='davidos', greeting='Hola'
will give Hola davidos
. But that’s just the definition. The implementations could differ, and that is exactly the point of this port. This article is about default parameters handled differently in Python and JavaScript.
Python
Let’s say you have function foo
defined thus:
>>> def foo(str1=a, str2=b):
... return str1+str2
...
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
NameError: name 'a' is not defined
What happened? Well, the Python rules for function definition make sure that a
and b
are defined beforehand. In other words, the default parameters in Python are evaluated only once i.e. at the time of function declaration.
For instance, here’s a version that works as expected because a
and b
are already defined before foo
is.
>>> a = "Hello"
>>> b = "World"
>>> def foo(a=a, b=b):
... return a+b
...
>>> foo()
'HelloWorld
As a matter of fact, the default parameters have to be defined beforehand. Otherwise how could you even utilize __defaults__
of foo
?
>>> foo.__defaults__
('Hello', 'World')
JavaScript
Python being my first-language, JavaScript’s function assignment rules seemed ‘very dynamic’ at first, to say the least. For instance, JavaScript will happily accept the version that Python didn’t.
>> function foo(str1=a, str2=b){
return str1+str2;
}
>> undefined
If you call foo()
at this point, you’d get an error saying Uncaught ReferenceError: a is not defined
. However, unlike Python, foo
is, nonetheless, actually defined. At this or at any point later, if the JavaScript runtime environment can find a variable a
and b
defined in the runtime environment, it will make foo
run without any errors!
As a matter of fact, the default variables can be totally dynamic! Let’s assume that the function foo
is defined as above and then we run the following sequentially:
>> a = "Hello"
>> "Hello"
>> b = "World"
>> "World"
>> foo()
>> "HelloWorld"
>> // I will now redefine `a` and `b`
>> a = "Stop"
>> "Stop"
>> b = "War"
>> "War"
>> foo()
>> "StopWar"
Did you see that? foo
’s default parameters will always be pulled from the runtime scope.
Honestly, I don’t see many pragmatic use cases right away for this aspect, but I found it really dynamic (pun intended). And it could easily become a quirk to screw oneself over for multilingual programmers.
Home Work
What happens if you try to change the function signature of foo
to foo(a=a, b=b)
? Why?