Skip to content

Parameter Groups  #2245

Open
Open
@apps-transround

Description

@apps-transround

Problem

Handling long parameter lists either at declaration or at call/instantiation may require a lot of repeating and hard to read code. Flutter widgets are good examples where the actual parameters often just replace the default values for each instantiation:

return Column(
  mainAxisSize: MainAxisSize.min,
  crossAxisAlignment: CrossAxisAlignment.start,
  mainAxisAlignment: MainAxisAlignment.start,
  children: []
)
// or 
return Row(
  mainAxisSize: MainAxisSize.min,
  crossAxisAlignment: CrossAxisAlignment.start,
  mainAxisAlignment: MainAxisAlignment.start,
  children: []
)

Simplifying this can be done by
• adding specific named constructors with proper defaults, but that's an endless effort
• creating subclasses just to override defaults, but it seems to be an overkill resulting in non-shallow inheritance chains.

Proposal

As a new solution this proposal aims to create a new language feature called Parameter Group to make parameter lists shorter, easier to read and more reusable. For example, minStart is a Parameter Group:

const minStart = Flex.params(
    mainAxisSize: MainAxisSize.min,
    crossAxisAlignment: CrossAxisAlignment.start,
    mainAxisAlignment: MainAxisAlignment.start);

return Column(
  ...minStart,
  children: []
)
// or
return Row(
  ...minStart,
  children: []
)

A Parameter Group is a list of parameters including type, name and (default) value.
Parameter Groups are used inside parameter lists via the … (spread) operator, which expands all members of the group into the list.
Expansion is done virtually for the IDE wizards, autofill and documentation.
Parameter Groups can be

  • Implicit: each constructor, method and function parameter list creates an implicit parameter group that can be accessed via the name.params expression.
  • Explicit: variables defined as parameter groups like minStart in the example above. Parameter Groups of a certain type are created with the type.params(parameterList) expression.

Parameter groups can be placed into

  • instantiation / call: members of the group become the actual parameters if have value, such as in the example above
  • Declaration: see Using constructor and function parameter lists as implicit parameter groups for more details
    Example: because all Column constructor parameters are just passed to its superclass Flex we can simplify the Column() declaration using the implicit parameter group of the Flex constructor:
class Column extends Flex {
  Column({…Flex.params}) {
  }
}

Advantages

General:

  • Shorter, more reusable and more readable code
  • Transparency: changes in parameters can be transparent via Parameter Groups
  • Parameter Groups create brand new type of coding experience and may catalyze a whole wave of new features.
  • Independent from the existing solutions; does not increase structural complexity; easy introduction.

In declarations:

  • No change on the caller side
  • Only the specific parts are needed in the constructors.
  • Easy to see and understand overrides/differences.
  • Transparent changes, no need to modify all passing constructors

In calls:

  • Reusable, self-explaining code
  • May decrease Flutter widget hell pains: although the structure remains the same, less lines are used
  • Error proof predefined parameter groups for certain use cases

Considerations

  • Conflict resolution: Members of a parameter group may be in conflict with already defined parameters in the list. Although this can be treated as an error, probably a clear resolution priority chain is more developer friendly. Conflict between two parameter groups may still result in compile time error.
  • Value or default value: parameters in the declaration can have default values (int parameter1 = 6) and values in the calls (parameter1: 6). To have a reusable solution these two notations may mean the same for groups.
  • Declaration vs runtime evaluation scopes require further study.
  • Additional parameter group operations: Parameter groups are similar to Dart lists and this proposal uses the spread (…) operator. Other list methods and further operators (for example collection for, collection if) may be implemented if strong use cases are found.

Related topics

  • Parameter groups have the common goal with mixins to improve code reuse but target only parameter lists.
  • Dependency injection targets parameter passing but with a different goal.
  • Widget extensions roll up children with parameters to reduce tree depth
  • Super parameters

Metadata

Metadata

Assignees

No one assigned

    Labels

    featureProposed language feature that solves one or more problems

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions