Using '_' to pass default value for function parameters


#1

Hi guys,

what do you think about the following syntax for parameters with default value:

fun foo(a: Int = 1, b: Int = 2, c: Int = 3) {}
...
foo(_, _, 33)

Today to use default parameter values I must move these parameters to the end of the list.

If Kotlin would support this syntax there will be no problem with parameters ordering just because of default values anymore.


#2

Why not call it as:

foo(c=33) 

And there will also not be any issues with parameter ordering anymore - even less issues with parameter ordering, since named arguments are safe against reordering or inserting of new parameters, whereas your suggestion is not.


#3

This syntax forces you to name all parameters you want to pass value for. This is OK for short function signatures and short parameter names.

But if function signature has 7-10+ parameters (it may be considered normal for enum constructors) and/or long parameter names this style will make code even longer than repeating default values.


#4

Readability is much more important than shortness. Concise parameter naming is important thing. line syntax does not suite you, you can always start each argument from new line which is very convenient for easy reading and comments.
And I don’t know about javascript community, but in java 7-10+ parameters usually means that you are doing something wrong. Some of parameters groups probably could be replaced by data classes.


#5

Actually in my own code I also have some functions with a lot of parameters, and some constructors for database-entities also have a lot of parameters.

In the case of functions with a lot of parameters, mostly these are builder-type functions to build test data instances where most values are defaulted and a typical invocation will specify only 2 or 3 non-default values.

And the OP’s case about Enum constructors with a lot of arguments, I do recognise that situation and data classes are probably not going to help.

I agree that readability is more important than brevity. Therefore I would prefer the named argument syntax myself in my own code for such situations, for readability, because the more parameters a function has, the harder it becomes to quickly see what each parameter is. Especially when various parameters are skipped to apply defaults.

When I see a call like:

foo(_, _, true, _, 42, _, _, _, _, "Bar")

Really - what would ‘true’, ‘42’, or ‘Bar’ really mean to that function? I’d prefer to see:

foo(isWorkflowTerminatingStatus = true,
    pricingSurchargeForResolution = 42,
    requiredUserRoleForAction = "Bar")

Then at least I’d know what I’m talking about when I pass in 42!

Well I guess it’s a matter of preference but I’ve seen enough code over the years to know what I find easier to understand!


#6

This is really good example when there are a lot of parameters in a method. Now consider that the enum has 100+ (the one I worked with today has about 500) members and to pass params for a single element you have to use multiple lines… A file becomes really huge.

But we can consider the same problem from a different perspective: why parameters with default values must always be at the end? I remember a lot of pain in API design in C/C++ (these languages support default parameters) when I had a dilema: either do not have a default value for a parameter at all or move it to the end of parameters list.

And the next logical question: what if I decided to add a default value later? Changing order of parameters may be considered unsafe and prevent adding default value for the parameter at all.


#7

Personally I don’t care if a file becomes large because of that. I do hate working with enums with that many values - but looking at that file for maintenance becomes even worse for me personally, when arguments are all position-based and I have to guess at the meaning of all of them.

Your point about reordering when adding new parameters for me reinforces the case for using named arguments, because this is safe against reordering or inserting new parameters in the middle.

I guess this partially boils down to personal preference, but I feel that the case with ‘_’ underscore for positional parameters where you want to apply the default value, however elegant it appears at first blush, very quickly leads to very unreadable code.