Theory
The last stop before Flutter
One Dart topic remains, and it is the one Unit 3 will use in every single line: functions.
Half of it you already own from 3 languages: define, call, pass arguments, return. The other half is genuinely new equipment: a one-line arrow form, parameters callers address by name, and a scoping rule that lets a function carry its birthplace's variables around.
Why the urgency? Open any Flutter file and you will see named arguments filling the screen. This lesson is their passport.
Theory
Defining and calling (and one syllabus note)
The full form is Java with lighter shoes:
int seatsLeft(int total, int booked) {
return total - booked;
}
And when the body is a single expression, Dart offers the arrow form:
int seatsLeft(int total, int booked) => total - booked;
Same function, one line: => means "return this expression".
(Honest note: your syllabus line reads "deleting function": no such Dart concept exists; read it as defining a function, which the exam certainly means.)
Practical
Arrows, optionals, named parameters, and a closure
int seatsLeft(int total, int booked) => total - booked; // arrow body
// [optional positional] with a default:
String daySlot(String event, [int day = 1]) => '$event (day $day)';
// {named} parameters with defaults: Flutter's house style
String ticket(String name, {String event = 'Garba Night', int day = 1}) {
return '$name: $event, day $day';
}
void main() {
print(seatsLeft(350, 310)); // 40
print(daySlot('Rangoli')); // Rangoli (day 1)
print(daySlot('Rangoli', 2)); // Rangoli (day 2)
print(ticket('Riya')); // defaults fill in
print(ticket('Aman', day: 2, event: 'Robo Race'));// any order, by name
// Lexical scoping: register() sees counter, born beside it
var counter = 0;
void register() {
counter++;
}
register();
register();
print('Registrations: $counter'); // 2
}
Theory
Three ways to receive arguments
- Required positional:
ticket('Riya'): order carries meaning, as in every language so far - Optional positional, in square brackets with defaults:
daySlot('Rangoli', 2): may be omitted, still by position - Named, in braces with defaults: called as
ticket('Aman', day: 2, event: 'Robo Race'): any order, self-documenting at the call site
Why Flutter chose named: a widget takes 10 optional settings, and Text('Hi', style: ..., maxLines: 2) reads like configuration, not a puzzle of commas. Every Unit 3 constructor is this pattern.
Quiz
Given the listing's ticket function, what does print(ticket('Riya')); output?
- Riya: Garba Night, day 1: the named parameters' defaults fill in
- A compile error: event and day were not supplied
- Riya: null, null
- Riya: event, day: the parameter names print literally
Show the answer
Riya: Garba Night, day 1: the named parameters' defaults fill in
Named parameters declared with defaults are optional: omit them and the defaults ('Garba Night', 1) step in: that is precisely what makes 10-setting Flutter constructors callable with 2 arguments. Option B treats named parameters as required: possible in Dart, but only with an explicit required keyword, which this declaration does not use. Option C imagines defaults not existing; option D imagines string interpolation failing. Follow-up worth self-testing: ticket('Aman', day: 2) gives Aman: Garba Night, day 2: names go in any order, each independently optional.
Think first
The function that remembers its home
In the listing, register() modifies counter, a variable OUTSIDE itself. Two runs later main prints 2. State the rule that permits this, and recall where you met the same behaviour in BCA405-01, then tap.
Show the answer
Lexical scoping: a nested function sees (and may modify) the variables of the scope where it was DEFINED: register was born beside counter, so counter is within its reach for life. You met this in BCA405-01 without the name: every AJAX handler and Node callback that used variables from the function around it was lexical scoping at work (JavaScript shares the rule). It matters enormously in Flutter: every onPressed callback reaches out to the widget's surrounding state exactly this way. Function + remembered surroundings = a closure: the term worth writing in the margin.
Watch out
Function-writing slips
Arrow with braces: => takes an EXPRESSION: writing => { return x; } is wrong twice: braces mean a block body, no arrow needed.
Positional call for named parameters: ticket('Aman', 'Robo Race') does not compile: braces-declared parameters are addressed BY NAME only.
Bracket confusion: [optional positional] vs {named}: square keeps position, curly gains names: mixing the declaration styles up is the standard 1-mark ambush.
Theory
Unit 2 closes: you speak Dart
Inventory: why Dart exists (JIT/AOT), how it runs (3 doors), its syntax (accents noted) and now its functions with arrows, named parameters and closures: the exact toolkit Flutter code is written in. Read this line and see if it already parses: ElevatedButton(onPressed: register, child: Text('Book')): a constructor with 2 NAMED arguments, one a function, one a widget. It does parse. You are ready: Unit 3, Flutter itself.
Summary
Key takeaways
- Define/call as in Java; => returns a single expression (no braces, no return keyword).
- Required positional; [optional positional] with defaults; {named} with defaults, called any-order by name.
- Named parameters are Flutter's house style: constructors read as configuration.
- Defaults fill omitted parameters: ticket('Riya') = Riya: Garba Night, day 1; seatsLeft(350, 310) = 40.
- Lexical scoping: nested functions see and modify their birth scope's variables (closures): BCA405-01's callbacks, named at last.
- Syllabus's 'deleting function' reads as DEFINING: no delete-a-function exists.
- Memory hook: arrows return, braces name, functions remember home.