A woefully incomplete review of default argument evaluation in other languages. Updates and corrections are welcome.
Out of 22 languages apart from Python: - 3 use early binding (default is evaluated at compile or function definition time); - 12 use late binding (default is evaluated at call time); - 1 simulates late binding with a standard idiom; - and 6 do not support default arguments. Note that R's model for defaults in particularly interesting. Early binding ------------- PHP: function f($arg = const) {body} PHP default arguments must be constant expressions, not variables or function calls. I infer from this that they are evaluated at function definition time (compile time?). https://www.php.net/manual/en/functions.arguments.php#functions.arguments.default Dart: f({arg=const}) {body} Dart default values appear to be restricted to constants, by which I infer that they are evaluated at compile-time. Visual Basic: Sub F(Optional arg As Type = constant) body End Sub VB default values are restricted to constants, by which I infer that they are evaluated at compile time. https://docs.microsoft.com/en-us/dotnet/visual-basic/language-reference/modifiers/optional Late binding ------------ Javascript: function f(arg=expression) { body } ECMAScript 2015 (ES6) introduced default arguments to Javascript. Javascript default arguments are evaluated when the function is called (late binding). https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Functions/Default_parameters https://dev.to/kenbellows/javascript-vs-python-default-function-parameter-values-7dc CoffeeScript: f = (arg = expression) -> body which compiles to JavaScript: f = function(arg) { if (arg == null) { arg = expression; } body; }; CoffeeScript default arguments are evaluated when the function is called. https://stackoverflow.com/questions/23763825/coffeescript-default-arguments C++: void f(type arg = expression); {body} C++ default arguments are evaluated when the function is called (late binding). The rules for C++ default arguments are complicated, for example local variables *usually* cannot be used in the default expression. https://en.cppreference.com/w/cpp/language/default_arguments https://edux.pjwstk.edu.pl/mat/260/lec/PRG2CPP_files/node61.html Ruby: def f(arg = expression) body end Ruby default values are evaluated when the function is called. https://asquera.de/blog/2012-06-29/2-detect-default-argument-evaluation/ Kotlin: fun f(arg: Type = expression) {body} Kotlin default arguments are evaluated when the function is called. https://kotlinlang.org/spec/expressions.html#function-calls-and-property-access Elixir: def f(arg \\ expression) do body end Elixir default arguments are evaluated when the function is called. https://til.mirego.com/2021-07-14-elixir-and-default-argument-evaluation https://hexdocs.pm/elixir/Kernel.html#def/2-default-arguments Scala: def f(arg: Type = expression) : Type = {body} Scala default arguments are evaluated when the function is called. https://docs.scala-lang.org/sips/named-and-default-arguments.html#default-arguments D: void f(Type arg = value) {body} It is not entirely clear to me when D evaluates default arguments, but I think it is when the function is called. https://dlang.org/spec/function.html#function-default-args Julia: function f(arg::Type=expression) body end Julia default arguments are evaluated when the function is called. https://docs.julialang.org/en/v1/manual/functions/ Swift: func f(arg: Type = expression) {body} Swift default arguments are evaluated when the function is called. https://docs.swift.org/swift-book/ReferenceManual/Declarations.html#//apple_ref/doc/uid/TP40014097-CH34-ID472 https://stackoverflow.com/questions/38464715/when-are-swift-function-default-parameter-values-evaluated/38464716 Raku (Perl 6): sub f($arg = expression) {body} It is unclear to me when Raku evaluates default arguments, but I think it is when the function is called. https://raku.guide/#_default_and_optional_parameters https://perl6advent.wordpress.com/2009/12/09/day-9-having-beautiful-arguments-and-parameters/ R: f <- function(arg=expression) {body} Default arguments in R are evaluated at need, at call time (lazy late binding). Because they are not evaluated until the argument is needed, they can refer to local variables defined in the body of the function: g <- function(arg=x) {x = 1; arg+1} Calling g with no arguments will return 2. http://r.babo.ist/#/en/lang_4_3_3_argument_evaluation.html https://www.johndcook.com/blog/2008/10/16/default-arguments-and-lazy-evaluation-in-r/ Simulating late binding ----------------------- Lua: function f(arg) arg = arg or expression body end Lua does not have syntax for default values, but it has a standard idiom for setting a default at call-time. Calling f() with no arguments assigns the special value *nil* to arg, and the "or" operator evaluates to the given expression. https://www.lua.org/manual/5.1/manual.html No default arguments -------------------- Rust, Java, Go, Eiffel, Cobra, Perl: None of these languages support default arguments. Rust apparently has a RFC for function defaults, so it may support them in the future. In the case of Java, Go and Eiffel, it is apparently a deliberate design principle that they not support defaults. In the case of Perl, functions do not have declared arguments at all, the function manually unpacks whatever arguments it requires from the special global variable `@_`. -- Steve _______________________________________________ Python-ideas mailing list -- python-ideas@python.org To unsubscribe send an email to python-ideas-le...@python.org https://mail.python.org/mailman3/lists/python-ideas.python.org/ Message archived at https://mail.python.org/archives/list/python-ideas@python.org/message/P5JAIGZEI4PXR2TYS5ELB6TN4JVLUNL7/ Code of Conduct: http://python.org/psf/codeofconduct/