Hacker News new | ask | show | jobs
by mikeash 3822 days ago
Yes, that's true, but note that you only need to specify the external names on the parameters that depart from the default. A function with external names on every parameter looks like:

    func whatever(a a: Int, b: Int, c: Int)
A function with no external names on any parameter looks like:

    func whatever(a: Int, _ b: Int, _ c: Int)
I'm not sure if you understood that or thought they all had to be specified if any were, but in any case that's how it looks.

As for "that could trivially be done," that applies to a lot of language features in a lot of languages. Virtually all language features are redundant in that fashion, yet they can still be useful by adding brevity and clarity.

1 comments

The question is why is the first argument special? Also, it's weird that you have to explicitly mark the label as "_" to get positional parameters.

I find Scala's handling of named arguments much saner.

I think it's because the first argument tends to be named by the function itself. For example:

    button.setTitle("Ham and Cheese", color: red)
Note that named parameters are still positional, they just have names too. Using _ doesn't get you positional parameters, you already had that, it just removes the name. (Exception: named parameters with default values can be reordered with other adjacent named parameters with default values. Why? I don't know.)

It is mildly annoying that you have to add an extra symbol to remove the name for parameters after the first one, but that's the language pushing its preferred style.

How does Scala handle all this?

> Exception: named parameters with default values can be reordered with other adjacent named parameters with default values. Why? I don't know.

That's actually nice to know.

> How does Scala handle all this?

No idea about Scala. In Python 3, there are 4 "classes" of parameters:

* "positional-and-named", the basic parameter can be passed either by name or by position, though passing parameter 1 by name parameter 2 by position won't work: when actually calling the function, the interpreter first fills positional parameters left-to-right then applies named parameters, so it'll raise an error noting that one parameter got two values[0]. Can be either required or with a default value. Parameters passed by names can be passed in any order

    def foo(a, b, c=5): pass
    foo(1, c=42, b=3)
* positional varargs ("args"), can only be passed positionally, can follow any number of positional parameters, will be collected as an array

    def foo(*args): pass
    foo(1, 2, 3, 4)
* named-only ("keyword parameters"), follows either positional varargs or a special placeholder. These were not possible in Python 2 in pure Python, they're similar to 1 but can only be passed by name, they can be either required or with a default value. Like 1 but more so, named-only parameters can be passed in any relative order

    def foo(*, a, b, c=5): pass
    foo(b=6, a=2)
* keyword varargs ("kwargs"), may follow named-only parameters and will collect any parameter passed by name which didn't match any formal parameter, will be collected as a key:value map

    def foo(**kwargs): pass
    foo(bar=5, baz=42, qux=1)
The C API also allows creating true positional parameters (completely unnamed), as far as I know that's not possible in pure Python.

[0] the reverse won't work either, at callsite Python doesn't allow named parameters to be provided before positional ones

For Swift, a lot of the designs were due to the ability to automatically transform Objective-C apis into swift APIs. The big issue from what i can tell is in extracting the first parameters name from the method name automatically.
That doesn't really explain the defaults, though. Translation could override the defaults if that fit better. This already happens when translating C functions, as none of the parameters get external names.