Parameters Design

Domains: Dart


DO use inclusive start and exclusive end parameters to accept a range.

If you are defining a method or function that lets a user select a range of elements or items from some integer-indexed sequence, take a start index, which refers to the first item and a (likely optional) end index which is one greater than the index of the last item.

This is consistent with core libraries that do the same thing.

[0, 1, 2, 3].sublist(1, 3) // [1, 2]
'abcd'.substring(1, 3) // 'bc'

It’s particularly important to be consistent here because these parameters are usually unnamed. If your API takes a length instead of an end point, the difference won’t be visible at all at the callsite.


AVOID positional boolean parameters.

Unlike other types, booleans are usually used in literal form. Things like numbers are usually wrapped in named constants, but we usually just pass around true and false directly. That can make callsites unreadable if it isn’t clear what the boolean represents:

new Task(true);
new Task(false);
new ListBox(false, true, true);
new Button(false);

Instead, consider using named arguments, named constructors, or named constants to clarify what the call is doing.

ListBox(scroll: true, showScrollbars: true);

Note that this doesn’t apply to setters, where the name makes it clear what the value represents:

listBox.canScroll = true;
button.isEnabled = false;

AVOID optional positional parameters if the user may want to omit earlier parameters.

Optional positional parameters should have a logical progression such that earlier parameters are passed more often than later ones. Users should almost never need to explicitly pass a “hole” to omit an earlier positional argument to pass later one. You’re better off using named arguments for that.

String.fromCharCodes(Iterable<int> charCodes, [int start = 0, int end]);

DateTime(int year,
    [int month = 1,
    int day = 1,
    int hour = 0,
    int minute = 0,
    int second = 0,
    int millisecond = 0,
    int microsecond = 0]);

    {int days = 0,
    int hours = 0,
    int minutes = 0,
    int seconds = 0,
    int milliseconds = 0,
    int microseconds = 0});

AVOID mandatory parameters that accept a special “no argument” value.

If the user is logically omitting a parameter, prefer letting them actually omit it by making the parameter optional instead of forcing them to pass null, an empty string, or some other special value that means “did not pass”.

Omitting the parameter is more terse and helps prevent bugs where a sentinel value like null is accidentally passed when the user thought they were providing a real value.

var rest = string.substring(start);
var rest = string.substring(start, null);

Similar pages

Page structure





Positional parameters





Named constructor