Functions and Parameters
Sprout builds the same kind of message over and over: "Fern: water every 3 days". A function wraps that logic once. Dart's parameter system then lets each call read almost like a sentence, if you choose between positional and named parameters well.
The rule
Positional by place, named by name;
requiredmakes a name mandatory.
String reminder(String plant, {int days = 7, bool outdoors = false}) {
final where = outdoors ? 'outside' : 'inside';
return '$plant ($where): every $days days';
}
reminder('Fern', days: 3); // 'Fern (inside): every 3 days'- Positional parameters, like
plant, are matched by their order in the call. - Named parameters sit inside
{ }and are passed asname: value, in any order. They are optional, so each needs a default, a nullable type, or the wordrequired. - Optional positional parameters sit inside
[ ]:void log(String msg, [String? tag]).
A function whose body is one expression can use the arrow:
bool isDue(int daysSince, int every) => daysSince >= every;=> expr is short for { return expr; }. Functions are values too, so you can pass one to another: plants.where((p) => p.outdoors).
The shortcut
Design a signature by asking, for each input, "Would a reader know what this value means without its name?"
The plant name
reminder('Fern')is obvious. Keep it positional.
The trap is a named, non-nullable parameter with neither a default nor required. Dart rejects it, because an optional int would have nothing to hold when omitted.
Drills
Answer fast — trust the rule.
With the reminder above, what does reminder('Cactus', days: 14) return?
Why is void water({int litres}) {} rejected?
What does int twice(int n) => n * 2; return for twice(4)?
Which syntax declares an optional positional parameter?
Remember
- Positional by place, named by name;
requiredmakes a name mandatory. - If a bare value would puzzle a reader, make it named.
- Trap: a named non-nullable parameter needs a default or
required.
