To the first part, it seems like that's rather difficult to say given we don't have either in stable at present. I can say that I'd very much like to have named arguments in particular (type ascription is fine, though I don't want it as much as I want named arguments).
To the second, that certainly hasn't been my experience in Python; it's natural to refactor to a class
or dict
there if your argument lists start getting long. This does raise an important ergonomics point when comparing to Swift, on which see below.
I strongly agree with the underlying sentiment here from a user (rather than implementor) perspective. The various alternative options proposed above to work around the type ascription problem are, as even those who proposed them noted, ugly. The internal and external parameter names in Swift (and ObjC, thanks to common Smalltalk heritage) took me a while to get used to, but I also like them. (_ x
is indeed the correct shorthand for them.)
But the type ascription syntax also seems like an even more natural fit with the overall language designāwhile param_name: value
is initially attractive, I do think param_name: type
for ascription is even more so (even as someone who's far likelier so far to want a named parameter than type ascription).
To the ergonomics point I mentioned above: Swift's approach to named parameters (unlike Python's) is such that once you have keyword/named arguments, you have to supply them in most cases; otherwise the API developer has to explicitly do func foo(_ bar: Int, _ baz: String)
there.
That specific approach would (fairly obviously) not be backwards compatible here, and it's also annoying. It makes calling functions incredibly long and verboseāfar more so than similar APIs in Rust, which is a fairly unusual outcome on comparing the two for brevity.
From a usability perspective (again, I have no idea how feasible this is from the implementation side), what I'd prefer to see is:
fn increment(initial: i32, by amount: i32) -> i32 {
initial + amount
}
increment(32, by 10); // 42
With a case where you had type ascription, that'd look something like:
let amount = 10i32;
increment(32, by amount: i32)
Is it possible to evaluate that call signature unambiguously in the grammar?
(Again, I know almost nothing on the implementation side, this is all just an enormous for me coupled with what I would like as a user.)
Then I'd assume it would play out something like this:
-
named parameters must follow any non-named parameters (both Python and Swift enforce this)
-
named parameters may be supplied without the name (a la Python; Swift doesn't allow this, but I think that's both problematic in Swift and a problem for Rust backwards compatibility)
-
named parameters are defined simply by including the external parameter name. If there is only one name, it's a positional parameter; if there are two names, the first is the named parameter name.
(Maybe there's a way to avoid repetition if you want them both to be the same so you don't end up with fn foo(bar bar: i32)
in that case, but I can't come up with anything immediately.)