Watch the video (10 min)
On this page22 sections
  1. Prerequisites
  2. Connection With Previous Lectures
  3. Learning Objectives
  4. 1. The Problem With Long Positional Calls
  5. 2. Declaring Named Parameters
  6. 3. Named Parameters Are Optional
  7. 4. Nullable Named Parameters
  8. 5. required Named Parameters
  9. 6. Named Arguments in Any Order
  10. 7. Mixing Positional and Named Parameters
  11. 8. Named Arguments Can Go Anywhere in the Call
  12. 9. [ ] and { } Cannot Be Combined
  13. 10. A Real-World Example
  14. Code Examples
  15. Common Beginner Mistakes
  16. Best Practices
  17. Mini Challenge
  18. Practice Questions
  19. Practice Answers
  20. Quick Revision
  21. Key Takeaways
  22. What's Next?

Lecture 33 — Named Parameters

Category6 — Functions
Lecture033 of 140
Estimated video length10 min
TargetDart 3.12.2
LevelBeginner

A call like openAccount('Ali', 500, true, false) compiles, but nobody can tell what true and false mean. Named parameters put a label on every argument, so the call explains itself.

Contents

Prerequisites · Connection · Objectives · Lesson · Code Examples · Common Mistakes · Best Practices · Mini Challenge · Practice Questions · Answers · Takeaways

Every error message in this lecture is real. Each one was produced by running the code shown on Dart 3.12.2, so you will recognize it when you meet it yourself.


Prerequisites

Students should already understand, from Lectures 001–032:

  • nullable types (String?) and the ?? operator (Lectures 013–014)
  • functions with typed parameters and return values (Lecture 031)
  • optional positional parameters in [ ] and default values (Lecture 032)

Connection With Previous Lectures

In Lecture 032 we made parameters optional with [ ] and gave them default values. That works well for one or two values, but positional parameters still have two weaknesses. First, the call shows only values, not their meaning: in order('Pen', 3, true), what is true? Second, to set the third optional value you must also pass the second, even if you are happy with its default. This lecture removes both problems by letting the caller pass each argument by name.


Learning Objectives

By the end of this lecture you will be able to:

  • Declare named parameters with curly braces { }
  • Call a function using name: value arguments
  • Give named parameters default values
  • Use nullable named parameters for values that may be missing
  • Make a named parameter mandatory with required
  • Pass named arguments in any order
  • Combine positional and named parameters in one function
  • Read the errors Dart gives when named parameters are used incorrectly

1. The Problem With Long Positional Calls

Here is a function with four positional parameters:

dart
void openAccount(String owner, int deposit, bool isSavings, bool sendSms) {
  print('$owner | $deposit | savings: $isSavings | sms: $sendSms');
}

void main() {
  openAccount('Ali', 500, true, false);
}
output
Ali | 500 | savings: true | sms: false

It runs, but the call openAccount('Ali', 500, true, false) hides its meaning. Swap the two bool values by mistake and Dart cannot warn you — both are bool.


2. Declaring Named Parameters

Wrap parameters in curly braces { } to make them named. The caller then writes the parameter's name, a colon, and the value.

Analogy — positional arguments are like boxes in a row: you must remember which box is which. Named arguments are boxes with labels stuck on them.

dart
void greet({String name = 'friend'}) {
  print('Hello, $name!');
}

void main() {
  greet(name: 'Sara');
}
output
Hello, Sara!

name: 'Sara' is a named argument. The = 'friend' part is a default value — Step 3 explains why it is needed.


3. Named Parameters Are Optional

Unlike the positional parameters of Lecture 031, a named parameter is optional by default: the caller may leave it out. So Dart needs to know what value to use when it is missing. The simplest answer is a default value, written with = exactly as in Lecture 032.

dart
void greet({String name = 'friend'}) {
  print('Hello, $name!');
}

void main() {
  greet(name: 'Zayan');
  greet();
}
output
Hello, Zayan!
Hello, friend!

Without a default, a missing String would have to be null — and String does not allow null:

dart
void greet({String name}) {
  print('Hello, $name!');
}

void main() {
  greet(name: 'Ali');
}
output
Error: The parameter 'name' can't have a value of 'null' because of its type 'String', but the implicit default value is 'null'.
Try adding either an explicit non-'null' default value or the 'required' modifier.
void greet({String name}) {
                   ^^^^

The error suggests the two fixes: a default value (this step), or required (Step 5).


4. Nullable Named Parameters

Sometimes there is no sensible default — the value is simply "there or not there". Make the type nullable with ?. A missing argument then becomes null.

dart
void sendGift(String to, {String? message}) {
  print('Gift for $to');
  print('Message: ${message ?? '(none)'}');
}

void main() {
  sendGift('Sara', message: 'Happy birthday!');
  sendGift('Zayan');
}
output
Gift for Sara
Message: Happy birthday!
Gift for Zayan
Message: (none)

Inside the function, message is a String?, so all the null-safety rules from Lectures 012–016 apply. Here ?? supplies the fallback text.


5. required Named Parameters

Some values must always be given, but you still want the label at the call. Put the keyword required before the type.

dart
void transfer({required String from, required String to, required int amount}) {
  print('$from sends $amount to $to');
}

void main() {
  transfer(from: 'Ali', to: 'Sara', amount: 300);
}
output
Ali sends 300 to Sara

Leave one out and the program does not compile:

dart
void transfer({required String from, required String to, required int amount}) {
  print('$from sends $amount to $to');
}

void main() {
  transfer(from: 'Ali', amount: 300);
}
output
Error: Required named parameter 'to' must be provided.
  transfer(from: 'Ali', amount: 300);
          ^

A required parameter needs no default — the caller always supplies the value.


6. Named Arguments in Any Order

Because every argument carries its name, the order no longer matters. Dart matches by name, not by position.

dart
void transfer({required String from, required String to, required int amount}) {
  print('$from sends $amount to $to');
}

void main() {
  transfer(amount: 50, to: 'Zayan', from: 'Sara');
  transfer(to: 'Ali', from: 'Zayan', amount: 75);
}
output
Sara sends 50 to Zayan
Zayan sends 75 to Ali

This also solves the second problem from the Connection: you can set any one optional named value and skip the rest.


7. Mixing Positional and Named Parameters

A function can have ordinary positional parameters and named ones. In the definition, the positional parameters come first and the { } block comes last.

dart
void showStudent(String name, int marks, {String grade = '-', bool passed = true}) {
  print('$name: $marks ($grade) passed: $passed');
}

void main() {
  showStudent('Ali', 85, grade: 'A');
  showStudent('Zayan', 40, passed: false, grade: 'F');
  showStudent('Sara', 70);
}
output
Ali: 85 (A) passed: true
Zayan: 40 (F) passed: false
Sara: 70 (-) passed: true

Use positional parameters for the obvious main values (name, marks) and named ones for the extras.


8. Named Arguments Can Go Anywhere in the Call

In the definition, { } must come last. In the call, Dart is more relaxed: a named argument can appear before, between, or after the positional ones. The positional arguments still keep their order among themselves.

dart
void showStudent(String name, int marks, {String grade = '-'}) {
  print('$name: $marks ($grade)');
}

void main() {
  showStudent('Ali', 85, grade: 'A');
  showStudent('Sara', grade: 'B', 70);
  showStudent(grade: 'C', 'Zayan', 55);
}
output
Ali: 85 (A)
Sara: 70 (B)
Zayan: 55 (C)

All three calls are legal, but the first form — positional first, named last — is the easiest to read. Stick to it unless a long named argument reads better earlier.


9. [ ] and { } Cannot Be Combined

A single function can have optional positional parameters ([ ], Lecture 032) or named parameters ({ }) — not both.

dart
void order(String item, [int quantity = 1], {bool gift = false}) {
  print(item);
}

void main() {
  order('Pen');
}
output
Error: Expected ')' before this.
void order(String item, [int quantity = 1], {bool gift = false}) {
                                          ^

When a function needs several optional values, choose named parameters.


10. A Real-World Example

dart
double checkout({
  required String customer,
  required double subtotal,
  double discountPercent = 0,
  bool express = false,
  String? coupon,
}) {
  double total = subtotal - subtotal * discountPercent / 100;
  if (express) {
    total = total + 150;
  }
  print('Customer: $customer');
  print('Coupon: ${coupon ?? 'none'}');
  print('Total: $total');
  return total;
}

void main() {
  checkout(
    customer: 'Sara',
    subtotal: 2000,
    discountPercent: 10,
    coupon: 'SAVE10',
  );
  checkout(customer: 'Ali', express: true, subtotal: 800);
}
output
Customer: Sara
Coupon: SAVE10
Total: 1800.0
Customer: Ali
Coupon: none
Total: 950.0

customer and subtotal are required; discountPercent and express have defaults; coupon is nullable. Each call passes only what it needs, in any order, and still reads like a sentence. When a parameter list or a call is too long for one line, dart format puts each item on its own line with a trailing comma, as here.


Code Examples

Example 1 — One Named Parameter With a Default

dart
void welcome({String name = 'guest'}) {
  print('Welcome, $name!');
}

void main() {
  welcome(name: 'Ali');
  welcome();
}
output
Welcome, Ali!
Welcome, guest!

Example 2 — Two Defaults, Set Either One

dart
void pizza({String size = 'medium', bool extraCheese = false}) {
  print('$size pizza, extra cheese: $extraCheese');
}

void main() {
  pizza();
  pizza(extraCheese: true);
  pizza(size: 'large');
}
output
medium pizza, extra cheese: false
medium pizza, extra cheese: true
large pizza, extra cheese: false

pizza(extraCheese: true) sets the second value without touching the first — impossible with [ ].

Example 3 — A Nullable Named Parameter

dart
void profile(String name, {int? age}) {
  if (age == null) {
    print('$name (age unknown)');
  } else {
    print('$name, $age years old');
  }
}

void main() {
  profile('Sara', age: 22);
  profile('Zayan');
}
output
Sara, 22 years old
Zayan (age unknown)

Example 4 — required Parameters

dart
int rectangleArea({required int width, required int height}) {
  return width * height;
}

void main() {
  print(rectangleArea(width: 12, height: 5));
  print(rectangleArea(height: 3, width: 4));
}
output
60
12

Example 5 — Returning a Value

dart
String fullName({
  required String first,
  required String last,
  String title = '',
}) {
  if (title.isEmpty) {
    return '$first $last';
  }
  return '$title $first $last';
}

void main() {
  print(fullName(first: 'Sara', last: 'Khan'));
  print(fullName(title: 'Dr.', first: 'Ali', last: 'Raza'));
}
output
Sara Khan
Dr. Ali Raza

Example 6 — Positional Plus Named

dart
void log(String message, {String level = 'INFO', bool loud = false}) {
  String text = '[$level] $message';
  print(loud ? text.toUpperCase() : text);
}

void main() {
  log('App started');
  log('Low balance', level: 'WARN');
  log('Payment failed', level: 'ERROR', loud: true);
}
output
[INFO] App started
[WARN] Low balance
[ERROR] PAYMENT FAILED

Example 7 — Student Marks

dart
void report(String name, {required int marks, int passMark = 50}) {
  String result = marks >= passMark ? 'Pass' : 'Fail';
  print('$name: $marks → $result');
}

void main() {
  report('Ali', marks: 72);
  report('Zayan', marks: 45);
  report('Sara', marks: 55, passMark: 60);
}
output
Ali: 72 → Pass
Zayan: 45 → Fail
Sara: 55 → Fail

The pass mark is usually 50, so it has a default; one course raises it by name.

Example 8 — Shopping Total

dart
double lineTotal({required double price, int quantity = 1, double tax = 0}) {
  return price * quantity * (1 + tax / 100);
}

void main() {
  print(lineTotal(price: 250, quantity: 3));
  print(lineTotal(price: 1000));
  print(lineTotal(price: 200, tax: 5));
}
output
750.0
1000.0
210.0

Example 9 — Bank Balance

dart
int withdraw(int balance, {required int amount, int fee = 0}) {
  int cost = amount + fee;
  if (cost > balance) {
    print('Declined: need $cost, have $balance');
    return balance;
  }
  return balance - cost;
}

void main() {
  int balance = 1000;
  balance = withdraw(balance, amount: 300);
  balance = withdraw(balance, amount: 500, fee: 20);
  balance = withdraw(balance, fee: 20, amount: 400);
  print('Balance: $balance');
}
output
Declined: need 420, have 180
Balance: 180

Example 10 — Temperature Conversion

dart
double convert(double value, {bool toFahrenheit = true}) {
  if (toFahrenheit) {
    return value * 9 / 5 + 32;
  }
  return (value - 32) * 5 / 9;
}

void main() {
  print(convert(25));
  print(convert(212, toFahrenheit: false));
}
output
77.0
100.0

Common Beginner Mistakes

1. A non-nullable named parameter with no default and no required

dart
// void greet({String name}) { ... }
output
Error: The parameter 'name' can't have a value of 'null' because of its type 'String', but the implicit default value is 'null'.

Add a default, add required, or make the type String?.

2. Forgetting the name in the call

dart
// void greet({String name = 'friend'}) { ... }
// greet('Ali');
output
Error: Too many positional arguments: 0 allowed, but 1 found.
Try removing the extra positional arguments.

The function has no positional parameters. Write greet(name: 'Ali').

3. Using a name on a positional parameter

dart
// void greet(String name) { ... }
// greet(name: 'Ali');
output
Error: Too few positional arguments: 1 required, 0 given.

Only parameters inside { } can be passed by name.

4. Misspelling the name

dart
// void greet({String name = 'friend'}) { ... }
// greet(nam: 'Ali');
output
Error: No named parameter with the name 'nam'.

5. Giving a required parameter a default

dart
// void greet({required String name = 'Ali'}) { ... }
output
Error: Named parameter 'name' is required and can't have a default value.

Choose one: either the caller must pass it, or there is a default.

6. Putting { } before positional parameters

dart
// void greet({String name = 'friend'}, String greeting) { ... }
output
Error: Expected ')' before this.

In the definition, the { } block always comes last.


Best Practices

  • Use named parameters when a function takes several values of the same type, and especially for bool flags: express: true beats a bare true.
  • Mark a named parameter required when there is no sensible default.
  • Use a nullable named parameter only when "not given" is a real, meaningful case.
  • Keep the one or two obvious main values positional, and make the extras named.
  • In calls, write positional arguments first and named arguments after them.
  • Let dart format lay out long parameter lists one per line.

Mini Challenge

Write void bookTicket with a positional String passenger, a required named String to, a named String seat defaulting to 'economy', and a nullable named String? meal. It prints one line. Call it for Ali (to Lahore), Sara (to Karachi, seat 'business', meal 'veg'), and Zayan (to Quetta, meal 'none' passed before to).

Your program should print exactly:

output
Ali → Lahore, economy, meal: standard
Sara → Karachi, business, meal: veg
Zayan → Quetta, economy, meal: none

Try it yourself before opening the solution.

Show solution
dart
void bookTicket(
  String passenger, {
  required String to,
  String seat = 'economy',
  String? meal,
}) {
  print('$passenger → $to, $seat, meal: ${meal ?? 'standard'}');
}

void main() {
  bookTicket('Ali', to: 'Lahore');
  bookTicket('Sara', to: 'Karachi', seat: 'business', meal: 'veg');
  bookTicket('Zayan', meal: 'none', to: 'Quetta');
}
output
Ali → Lahore, economy, meal: standard
Sara → Karachi, business, meal: veg
Zayan → Quetta, economy, meal: none

How it works

  1. to is required, so every call must pass it — by name, in any position.
  2. seat falls back to 'economy' when it is left out.
  3. meal is null for Ali, so ?? prints 'standard'.

Practice Questions

Work through these in order — they run from beginner to application to challenge. Every question gives you exact values, so you can compare your output with the answers.

Beginner

  1. Write void sayHi({String name = 'there'}) that prints Hi, <name>!. Call it once with name: 'Zayan' and once with no argument.
  2. Write int add({required int a, required int b}). Print add(b: 4, a: 6).
  3. Write void showCity({String? city}) that prints the city, or Unknown when it is missing (use ??). Call it with city: 'Lahore' and with no argument.

Application

  1. Write double circleArea({required double radius}) using 3.14 for π. Print the area for radius 10.
  2. Write void coffee({String size = 'small', int sugar = 1}) that prints <size> coffee, <sugar> sugar. Call it with only sugar: 0.
  3. Write String greeting(String name, {bool formal = false}) that returns Good day, <name>. when formal and Hey <name>! otherwise. Print it for Sara (formal) and Ali.
  4. Write int score({required int correct, int bonus = 0}) returning correct * 10 + bonus. Print score(correct: 7) and score(bonus: 5, correct: 8).
  5. Write double salePrice(double price, {double discount = 0}) where discount is a percentage. Print salePrice(1500, discount: 20) and salePrice(1500).

Challenge

  1. Write int deposit(int balance, {required int amount, int? bonus}) that adds the amount and, if bonus is not null, the bonus too. Starting from 500, deposit 200, then 100 with a bonus of 50, printing Balance: … after each step.
  2. Write String describeTemp(double celsius, {double hot = 30, double cold = 15}) that returns hot, cold, or mild. Print it for 34, for 20, and for 20 with cold: 22.

Practice Answers

Question 1 — Solution

dart
void sayHi({String name = 'there'}) {
  print('Hi, $name!');
}

void main() {
  sayHi(name: 'Zayan');
  sayHi();
}
output
Hi, Zayan!
Hi, there!

Question 2 — Solution

dart
int add({required int a, required int b}) {
  return a + b;
}

void main() {
  print(add(b: 4, a: 6));
}
output
10

Question 3 — Solution

dart
void showCity({String? city}) {
  print(city ?? 'Unknown');
}

void main() {
  showCity(city: 'Lahore');
  showCity();
}
output
Lahore
Unknown

Question 4 — Solution

dart
double circleArea({required double radius}) {
  return 3.14 * radius * radius;
}

void main() {
  print(circleArea(radius: 10));
}
output
314.0

Question 5 — Solution

dart
void coffee({String size = 'small', int sugar = 1}) {
  print('$size coffee, $sugar sugar');
}

void main() {
  coffee(sugar: 0);
}
output
small coffee, 0 sugar

Question 6 — Solution

dart
String greeting(String name, {bool formal = false}) {
  if (formal) {
    return 'Good day, $name.';
  }
  return 'Hey $name!';
}

void main() {
  print(greeting('Sara', formal: true));
  print(greeting('Ali'));
}
output
Good day, Sara.
Hey Ali!

Question 7 — Solution

dart
int score({required int correct, int bonus = 0}) {
  return correct * 10 + bonus;
}

void main() {
  print(score(correct: 7));
  print(score(bonus: 5, correct: 8));
}
output
70
85

Question 8 — Solution

dart
double salePrice(double price, {double discount = 0}) {
  return price - price * discount / 100;
}

void main() {
  print(salePrice(1500, discount: 20));
  print(salePrice(1500));
}
output
1200.0
1500.0

Question 9 — Solution

dart
int deposit(int balance, {required int amount, int? bonus}) {
  return balance + amount + (bonus ?? 0);
}

void main() {
  int balance = 500;
  balance = deposit(balance, amount: 200);
  print('Balance: $balance');
  balance = deposit(balance, amount: 100, bonus: 50);
  print('Balance: $balance');
}
output
Balance: 700
Balance: 850

Question 10 — Solution

dart
String describeTemp(double celsius, {double hot = 30, double cold = 15}) {
  if (celsius >= hot) {
    return 'hot';
  }
  if (celsius < cold) {
    return 'cold';
  }
  return 'mild';
}

void main() {
  print(describeTemp(34));
  print(describeTemp(20));
  print(describeTemp(20, cold: 22));
}
output
hot
mild
cold

Quick Revision

  1. How do you declare a named parameter?
  2. Are named parameters required or optional by default?
  3. Name three ways to fix "the implicit default value is 'null'".
  4. What does required do?
  5. What value does a missing String? named parameter have?
  6. Does the order of named arguments matter?
  7. Where must { } go in a definition? Where can named arguments go in a call?
  8. Can one function use both [ ] and { }?

Key Takeaways

  • Curly braces { } declare named parameters; callers pass them as name: value.
  • Named parameters are optional unless marked required.
  • An optional named parameter needs a default value or a nullable type.
  • required forces the caller to pass the value and cannot be combined with a default.
  • Named arguments can be given in any order, and any subset of optional ones can be set.
  • Positional parameters come first in the definition; named arguments may appear anywhere in the call, though positional-first reads best.
  • A function cannot have both [ ] and { } parameters.
  • Named parameters make calls self-explaining — especially for bool flags.

What's Next?

Lecture 034 — Arrow & Anonymous Functions. Many of our functions have a body of just one line: return width * height;. Dart has a shorter way to write them, the arrow =>. And sometimes a function is needed only once, so it does not even need a name. Next we learn both.


Video lecture

Subscribe
Placeholder video — the real recording isn't linked yet.