The Problem.
Consider the Django Fieldclass . This class serves as a base class for several other classes, such as TextField, TimeField, BinaryField etc. To code examples like these cleanly, some type of language mechanism is needed which effectively achieves: "include all fields from the base class constructor (or other method from the base class) as also parameters to this class unless specifically declared in this class"
.
Python uses the *args,**kwargs system, which for several reasons is not an appropriate solution for Kotlin, but is at least a solution. There are some more elegant solutions possible for Kotlin, and can be just compiler syntactic sugar.
In Python the code for defining the BinaryField Class is as follows (not exact code for simplicity):
class BinaryField(Field):
def __init__(self, *args, **kwargs):
kwargs['editable'] = False
super().__init__(*args, **kwargs) // other init code goes here
while in Kotlin (slightly changed for name conventions and simplicity) the code becomes:
class BinaryField(
verboseName:String?=null, name:String?=null, primaryKey:Boolean=false,
maxLength:Int?=null, unique:Boolean=false, blank:Boolean=false, nulled:Boolean=false,
dbIndex:Boolean=false, rel:String?=null, default:Any?=null,
//editable:Boolean=true, - force 'false' for editable serialize:Boolean=true,
uniqueForYear:Int?=null, choices:String?=null, helpText:String="",
dbColumn:Int?=null, dbTablespace:Int?=null, autoCreated:Boolean=false,
validators:List?=null, errorMessages:String?=null
):Field(
verboseName=verboseName, name=name, primaryKey=primaryKey,
maxLength=maxLength, unique=unique, blank=blank, nulled=nulled,
dbIndex=dbIndex, rel=rel, default=default,
editable=false,
serialize=serialize, uniqueForYear=uniqueForYear, choices=choices,
helpText=helpText, dbColumn=dbColumn, dbTablespace=dbTablespace,
autoCreated=autoCreated, validators=validators, errorMessages=errorMessages
) { // class code here }
Clearly, the call to the base constructor will be much shorter if not using named parameters, which is a choice, but in a list this long I would use named parameters.
The code (or almost identical code) will be repeated TextField, TimeField and the over 12 other fields that inherit from Field. Any update to the parameter list for the base Field class is tedious to say the least.
This is a case where Kotlin requires boilerplate that is not required in python. What is needed is some way to say âaccept all parameters to the base default constructor not specifically named in the base call, and pass these parameters throughâ. Given this problem will not occur in Java libraries which have no default parameters, perhaps solving a problem of this nature is of less problem.
However, given pragmatic nature of the language in avoiding boilerplate, it would be great to have solution. I can think of ways that would be very workable, but I would imagine the Kotlin designers can do even better than I.
Does anyone else see this as something worth considering?