Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How can I force calls to some constructors/functions to use named arguments?

I have some constructors and functions that I'd like to always be called with named arguments. Is there a way to require this?

I'd like to be able to do this for constructors and functions with many parameters and for those that read more clearly when named arguments are used, etc.

like image 768
mfulton26 Avatar asked May 23 '16 14:05

mfulton26


People also ask

How do you force keyword arguments in Python?

By adding a * in the function arguments, we force all succeeding arguments to be named. E.g. by having the first argument be * , we force all arguments to be named. This makes writing defensive Python easier!

How do you handle a named argument in a function?

When you mix named and unnamed arguments in a function call, the unnamed arguments must come before the named ones in the argument list. Thus, when writing a function, you should put required arguments to the function in the argument list before the ones that you consider optional.

How do you use named arguments in Python?

Requiring your arguments be named You can create a function that accepts any number of positional arguments as well as some keyword-only arguments by using the * operator to capture all the positional arguments and then specify optional keyword-only arguments after the * capture.

Does JavaScript support named arguments?

JavaScript, by default, does not support named parameters. However, you can do something similar using object literals and destructuring. You can avoid errors when calling the function without any arguments by assigning the object to the empty object, {} , even if you have default values set up.


1 Answers

In Kotlin 1.0 you can do this by using Nothing from the stdlib.

In Kotlin 1.1+ you will get "Forbidden vararg parameter type: Nothing" but you can replicate this pattern by defining your own empty class with a private constructor (like Nothing), and using that as the first varargs parameter.

/* requires passing all arguments by name */ fun f0(vararg nothings: Nothing, arg0: Int, arg1: Int, arg2: Int) {} f0(arg0 = 0, arg1 = 1, arg2 = 2)    // compiles with named arguments //f0(0, 1, 2)                       // doesn't compile without each required named argument  /* requires passing some arguments by name */ fun f1(arg0: Int, vararg nothings: Nothing, arg1: Int, arg2: Int) {} f1(arg0 = 0, arg1 = 1, arg2 = 2)    // compiles with named arguments f1(0, arg1 = 1, arg2 = 2)           // compiles without optional named argument //f1(0, 1, arg2 = 2)                // doesn't compile without each required named argument 

As Array<Nothing> is illegal in Kotlin, a value for vararg nothings: Nothing can't be created to be passed in (short of reflection I suppose). This seems a bit of a hack though and I suspect there is some overhead in the bytecode for the empty array of type Nothing but it appears to work.

This approach does not work for data class primary constructors which cannot use vararg but these can be marked as private and secondary constructors can be used with vararg nothings: Nothing.

like image 57
mfulton26 Avatar answered Sep 22 '22 12:09

mfulton26