Thank you for doing this research, Steven.
The designers of 12 languages have chosen to provide late binding; those of 3 or 4 have provided early binding. I think this is at least tenuous evidence in favour of my belief that late binding is more useful than early binding.
Best wishes
Rob Cliffe

On 03/12/2021 21:05, Steven D'Aprano wrote:
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 `@_`.





_______________________________________________
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/LW6ETQEYPNKBK7XOKUB2KL3G4GSSLRJ4/
Code of Conduct: http://python.org/psf/codeofconduct/

Reply via email to