Sort alphabetically everything you can

Alexey Inkin
Flutter Senior
Published in
4 min readAug 10, 2022

Why

Say you have a class like this, and you add comment field:

Then someone else adds title field in another branch, and your merge looks like this:

It can’t go automatically, as the two branches modified the same lines. This is because when things are not sorted, everyone adds everything to the end.

If instead you added comment before description, then… I can’t even show you the dialog of an easy merge, because the editor did the merge without asking anything:

What Else to Sort

This goes for:

  • Class properties.
  • Named arguments when calling functions.
  • Named arguments at declaration. Required and non-required ones are sorted separately, required ones go first.
  • References to the named arguments in doc comments.
  • Enum constants at declaration and in switch.
  • Map entries.
  • Constants per group if you separate groups by blank lines.
  • Imports.
  • YAML, JSON and other map equivalents.
  • Calls to Object.hash.
  • Everything else if the order does not impact the semantics.

Exceptions

Understanding

Note that the list above is not sorted alphabetically. It goes from common to rare things as this is better for understanding. Same applies to:

  • Positional arguments.
    — Most important ones should go first.
    — Things like .range(start, end) should put start before end
    — Hinted arguments should follow the order like EdgeInsets.fromLTRB(…)
    If the order is not obvious, use named arguments.
  • Class methods. You usually sort them so that methods above invoke methods below, because this is better for the readers.
  • Local variables if you don’t have many.
  • Generic type parameters. You put the most important ones first.
  • Name, description, and version in pubspec.yaml, package.json and others (but not the dependency lists in them).

Special Items

  • ID field.
  • Widget key field.
  • none in enum, if you have one.

They stand out. They need to be first to assure they are there. They raise questions if they are not first.

If the Order Matters

You don’t sort like that:

  • Maps that are iterated in an expected order.
  • Columns in a table, as their order affects speed.
  • Variables initialized from one another.
  • Arrays that aim to have the most used items first for faster search.
  • Runtime imports like in PHP.
  • Tests of variables in && and || chains because you can benefit from short circuit evaluation.

A Natural Order

If things have a natural order, and so people will not add new items to the end, keep that order:

const xs = 10;
const s = 20;
const m = 30;
const l = 40;
const xl = 50;

Long Items

In Flutter, widget’s child and children properties are usually the longest ones because they may construct entire inline trees. So it’s recommended to put them last.

Lints to help

Many languages have lints to force some of the rules here. In Dart, you have:

Read this on how to set up lints in a Dart project so that GitHub tells you if you break a rule.

How to Add to an Unsorted List

Suppose you need to add keyed_collection_widgets package to the list:

dependencies:
flutter: { sdk: flutter }
flutter_svg: ^0.22.0
provider: ^6.0.0
code_text_field: ^1.0.0
url_launcher: ^6.0.12
expansion_widget: ^0.0.2

Maybe you cannot reorder the list right away because many people will suffer. Then you:

  1. Locate the first item out of order and consider the list sorted up till there:
dependencies:                    
flutter: { sdk: flutter } # sorted
flutter_svg: ^0.22.0 # sorted
provider: ^6.0.0 # sorted
code_text_field: ^1.0.0 # first violation, unsorted below
url_launcher: ^6.0.12
expansion_widget: ^0.0.2

2. Add to that sorted part:

dependencies:
flutter: { sdk: flutter }
flutter_svg: ^0.22.0
keyed_collection_widgets: ^0.3.2 # added
provider: ^6.0.0
code_text_field: ^1.0.0
url_launcher: ^6.0.12
expansion_widget: ^0.0.2

3. Give a hint for others to sort the rest as they change it. Depending on the syntax of the file, it can be a blank line, a blank line with TODO or something like that:

dependencies:
flutter: { sdk: flutter }
flutter_svg: ^0.22.0
keyed_collection_widgets: ^0.3.2
provider: ^6.0.0
# TODO(alexey.inkin): Sort alphabetically to the sorted part above
code_text_field: ^1.0.0
url_launcher: ^6.0.12
expansion_widget: ^0.0.2

--

--

Alexey Inkin
Flutter Senior

Google Developer Expert in Flutter. PHP, SQL, TS, Java, C++, professionally since 2003. Open for consulting & dev with my team. Telegram channel: @ainkin_com