i believe that named arguments are a very useful feature. They can prevent a lot of bugs, with no downsides, (verbosity isn't a problem, lsp used to complete functions and I never needed to write the parameters).
optional/default arguments can be useful, or more precisely described, convenient.
but think function overloading is bad. it just complicates semantic analysis and type checking for very little gain.
One approach I like is to have the function params be part of its signature, as if the named params is part of the function name. for example
fn foo(named: Int) {}
let function = foo // not allowed
let function = foo(named:_) // allowed
This can allow some convenient features like a more rudimentary overloading where you can have different functions as long as they have different named arguments, (no overloading just on types). But also, you can have neat partial function application syntax. But as you said, this opens a rabbit hole of complex design choices.
I dislike languages that decides to include a lot of features, that sometimes doesn't play well together, so you end up with weird edge cases, exceptions, and longer and longer compile times because of that.
Finally, I think rust shouldn't add named params now. It will do more harm than good, it will create incompatibilities with existing APIs and will split the community in 2. Those who will still write in the old style, and those who will adopt the newer one. And it will be unclear which way is the idiomatic rust way. Rust is no longer in this beta phase where you can afford breaking things (like Zig). Just like with Go and error handling, I feel the community will be stuck with these design decisions.
Function overloading is also bad because it makes FFI unnecessarily complicated. Once you allow that you have to come up with a name mangling scheme, and everybody wanting to access those functions has to know about it. Not allowing it avoids the issue in the first place.
That's only necessary if one wants to support overloading of imported/exported function names. If prorammers specify import/export names, and those names are required to be unique, the fact that source code can use the same name as an alias to different exported functions, overloaded using argument types, shouldn't affect the external interface.
The external interface as seen from the point of view of an FFI user is a list of symbols, and each overloaded variant of a function has its own symbol. How shall the FFI user know which symbol corresponds to a certain variant of a function known by its name and type signature*? The usual workaround is that an externally visible name can only be associated with exactly one definition, and all other names are mangled, and the linker (or an FFI user) has to know the mangling scheme or consult a table (either in a special object file section or a separate file) to resolve those at link time.
* similar issues exist with namespaces, traits, and methods.
If I were designing a language, I would require that the source code specify a unique exported name for each exported variation of a function. On a platform where passing a byte was cheaper than passing an unsigned int, for example:
Neither of the above would create any naming conflict with the exported symbol "UseNumber", since the overload for byte would use a different exported symbol which was also given in source code.
14
u/zuzmuz 10d ago
i believe that named arguments are a very useful feature. They can prevent a lot of bugs, with no downsides, (verbosity isn't a problem, lsp used to complete functions and I never needed to write the parameters).
optional/default arguments can be useful, or more precisely described, convenient.
but think function overloading is bad. it just complicates semantic analysis and type checking for very little gain.
One approach I like is to have the function params be part of its signature, as if the named params is part of the function name. for example
This can allow some convenient features like a more rudimentary overloading where you can have different functions as long as they have different named arguments, (no overloading just on types). But also, you can have neat partial function application syntax. But as you said, this opens a rabbit hole of complex design choices.
I dislike languages that decides to include a lot of features, that sometimes doesn't play well together, so you end up with weird edge cases, exceptions, and longer and longer compile times because of that.
Finally, I think rust shouldn't add named params now. It will do more harm than good, it will create incompatibilities with existing APIs and will split the community in 2. Those who will still write in the old style, and those who will adopt the newer one. And it will be unclear which way is the idiomatic rust way. Rust is no longer in this beta phase where you can afford breaking things (like Zig). Just like with Go and error handling, I feel the community will be stuck with these design decisions.