Which kinds of parameters can an external function/method have?
Thanks to @sgrekhov for bringing up this question.
How does an external function or method handle optional parameters?
I'd think there is no such thing, but we never specified that it is an error to have something like this:
external int foo([int i = 42]);
The reason why my first reaction was that this is simply an error is that I wouldn't expect foreign functions to have a notion of optional parameters whose semantics is similar to that of Dart optional parameters. A similar situation might exist with named parameters.
One known use case is js_interop constructors using named arguments to specify desired instance variables and their initial value. Look for 'object literal constructors' here.
Can we say that the semantics is implementation specific, and then it's up to each team who provides support for any given kind of external functions to define the semantics as they wish?
@dart-lang/language-team, WDYT? @dcharkes, WDYT, do those concepts have a meaningful interpretation with ffi code?
An external function is an abstract function signature with a marker saying that it's not actually abstract. It should be able to write anything that an abstract function signature can, no more and no less.
Dart function signatures can have optional parameters. So can external functions. It's up to the code that creates the implementation to ensure that the implementation actually handles all valid calls when it gets invoked with an argument list (in whatever ABI it used for that).
How does an external function or method handle optional parameters?
That's between the implementation and the compiler.
Default values are part of the implementation of a function, not its signature, and the entirety of the functions implementation is external. Writing a default value has, at best, no effect. I wouldn't allow it. Or we can allow it, but it's only for documentation purposes. But then, so are positional parameter names if you write those.
(Nothing prevents external void foo(int _, String _);.
If the code creating the implementation chooses to use those names and default values, that's somewhat bad style,
but nothing we can stop them from doing. As long as they provide an implementation that is compatible with the signature, they've done their part.
Can we say that the semantics is implementation specific, and then it's up to each team who provides support for any given kind of external functions to define the semantics as they wish?
That's how it works today. You write a function signature. You say it's external. It's up to the code that provides the implementation to figure out what that means. Nothing prevents optional parameters from the language's side. If the implementation provider cannot handle optional parameters, it's up to it to refuse the signature. (It definitely does not mean that any default value, if we allow it, must mean anything at all.)