On this page26 sections
- Prerequisites
- Connection With Previous Lectures
- Learning Objectives
- 1. What Is a Parameter?
- 2. Parameters and Arguments
- 3. More Than One Parameter
- 4. Dart Checks Every Argument
- 5. Returning a Value
- 6. Using a Returned Value
- 7. return Ends the Function
- 8. Returning Early
- 9. Every Path Must Return
- 10. void Means "Returns Nothing"
- 11. Don't Leave Out the Return Type
- 12. Nullable Return Types
- 13. late Can Delay a Calculation
- 14. A Real-World Example
- Code Examples
- Common Beginner Mistakes
- Best Practices
- Mini Challenge
- Practice Questions
- Practice Answers
- Quick Revision
- Key Takeaways
- What's Next?
Lecture 31 — Parameters & Return Values
| Category | 6 — Functions |
| Lecture | 031 of 140 |
| Estimated video length | 11 min |
| Target | Dart 3.12.2 |
| Level | Beginner |
A function that does the same thing every time is only half useful. Parameters let you hand a function new values on each call, and return values let it hand a result back.
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–030:
- variables, types, string interpolation, and
late(Lecture 006) - nullable types (
int?) and the??operator ifandif-elsestatements- defining a
voidfunction with no parameters and calling it frommain()
Connection With Previous Lectures
In Lecture 030 we wrote functions like this:
void greetAli() {
print('Hello, Ali!');
}It works, but it can only ever greet Ali. To greet Sara we would need a second function,
and a third for Zayan — the same code copied three times. And a void function that
calculates a total can only print it: the rest of the program never gets the number back.
Lecture 030 gave a short preview of the fix — String storeName() with the keyword
return. This lecture explains it properly, and fills the empty () too.
Learning Objectives
By the end of this lecture you will be able to:
- Define functions that take one or more typed parameters
- Explain the difference between a parameter and an argument
- Declare a return type and send a value back with
return - Store, print, and calculate with the value a function returns
- Use
returnto leave a function early - Recognize why every path of a non-
voidfunction must return a value - Explain why a missing return type is a problem
- Write functions with nullable return types for results that may be missing
1. What Is a Parameter?
A parameter is a variable that a function receives from whoever calls it. You write it inside the parentheses, with a type and a name.
Analogy — think of a form with a blank line: "Hello, ______!". The function is the form, the parameter is the blank, and each call fills the blank with a different name.
void greet(String name) {
print('Hello, $name!');
}
void main() {
greet('Ali');
greet('Sara');
}Hello, Ali!
Hello, Sara!One function now greets anyone.
2. Parameters and Arguments
The two words are easy to mix up:
- A parameter is the name in the function's definition —
nameabove. - An argument is the actual value you pass when calling it —
'Ali'and'Sara'.
void showAge(int age) {
// age is the parameter
print('Age: $age');
}
void main() {
showAge(20); // 20 is the argument
}Age: 20When the function runs, the parameter behaves like a local variable that already holds the argument's value.
3. More Than One Parameter
Separate parameters with commas. Arguments are matched by position: the first argument goes to the first parameter, the second to the second.
void showStudent(String name, int marks) {
print('$name scored $marks');
}
void main() {
showStudent('Zayan', 92);
}Zayan scored 92Swapping the arguments to showStudent(92, 'Zayan') would not compile — 92 is not a
String. Optional and named parameters, which loosen these rules, arrive in Lectures 032
and 033.
4. Dart Checks Every Argument
Each parameter has a type, so Dart checks each argument before the program runs:
void greet(String name) {
print('Hello, $name!');
}
void main() {
greet(25); // ✗
}Error: The argument type 'int' can't be assigned to the parameter type 'String'.
greet(25); // ✗
^The number of arguments is checked too. Every parameter in this lecture is required:
void showStudent(String name, int marks) {
print('$name scored $marks');
}
void main() {
showStudent('Ali'); // ✗ marks is missing
}Error: Too few positional arguments: 2 required, 1 given.
showStudent('Ali'); // ✗ marks is missing
^5. Returning a Value
So far our functions only print. To send a result back to the caller, replace void
with the type of the result — the return type — and use the return keyword.
int add(int a, int b) {
return a + b;
}
void main() {
int total = add(5, 3);
print(total);
}8Read int add(...) as "a function named add that gives back an int". The call
add(5, 3) is replaced by the value it returns, 8, which is stored in total. This is
exactly how the storeName() preview in Lecture 030 worked — it returned a String.
6. Using a Returned Value
A function call that returns a value can go anywhere a value of that type can go:
int add(int a, int b) {
return a + b;
}
void main() {
int total = add(10, 20); // store it
print(add(1, 2)); // print it directly
print('Total: ${add(4, 4)}'); // inside a string
print(add(10, 20) * 2); // in a calculation
print(add(add(1, 2), 3)); // as an argument
print(total);
}3
Total: 8
60
6
30In the last line before print(total), the inner add(1, 2) runs first and its result,
3, becomes the first argument of the outer call. Notice also the ${...} form of
interpolation: a function call needs the braces.
7. return Ends the Function
return does two things: it hands back the value and stops the function immediately.
Any line after it never runs.
int square(int n) {
return n * n;
print('Done'); // never runs
}
void main() {
print(square(4));
}16'Done' is never printed. dart analyze marks that line as unreachable:
warning - Dead code. Try removing the code, or fixing the code before it so that it can be reached. - dead_code8. Returning Early
Because return stops the function, you can use it inside an if to finish as soon as the
answer is known. This is called an early return.
String result(int marks) {
if (marks >= 50) {
return 'Pass';
}
return 'Fail';
}
void main() {
print(result(72));
print(result(35));
}Pass
FailFor 72, the first return runs and the function ends. For 35, the if is skipped and
the second return runs. No else is needed.
A void function can return early too — write return; with no value:
void withdraw(int balance, int amount) {
if (amount > balance) {
print('Not enough money');
return;
}
print('New balance: ${balance - amount}');
}
void main() {
withdraw(1000, 300);
withdraw(1000, 5000);
}New balance: 700
Not enough money9. Every Path Must Return
If a function promises an int, it must return an int on every path through its
body. Forget one, and Dart refuses to compile:
int bonus(int marks) {
if (marks >= 90) {
return 10;
}
// ✗ nothing is returned when marks is below 90
}
void main() {
print(bonus(95));
}Error: A non-null value must be returned since the return type 'int' doesn't allow null.
int bonus(int marks) {
^A function that reaches its closing } without return gives back null — and int does
not allow null. Add a final return 0; and the error is gone.
10. void Means "Returns Nothing"
A void function cannot return a value:
void greet(String name) {
return 'Hello, $name!'; // ✗
}
void main() {
greet('Ali');
}Error: Can't return a value from a void function.
return 'Hello, $name!'; // ✗
^And you cannot use the "result" of a void function, because there is none:
void greet(String name) {
print('Hello, $name!');
}
void main() {
String message = greet('Ali'); // ✗
print(message);
}Error: This expression has type 'void' and can't be used.
String message = greet('Ali'); // ✗
^If you want the text back, the function must return String instead of printing it.
11. Don't Leave Out the Return Type
Dart lets you write a function without a return type, but it does not infer one for you.
The result is quietly dynamic — and in Lecture 011 we saw that dynamic turns type
checking off.
add(int a, int b) {
return a + b;
}
void main() {
var total = add(2, 3);
print(total.length); // an int has no length
}This compiles, then crashes while running:
Unhandled exception:
NoSuchMethodError: Class 'int' has no instance getter 'length'.
Receiver: 5
Tried calling: lengthdart analyze warns about the missing type before you run anything:
info - Missing type annotation. Try adding a type annotation. - strict_top_level_inferenceWriting int add(int a, int b) turns that crash into a compile-time error. The same goes
for parameters: always give them a type.
12. Nullable Return Types
Sometimes a function honestly may not have an answer. Make the return type nullable with
? and return null when there is nothing to give back — just like int.tryParse, which
we met in Lecture 013.
int? findMark(String name) {
if (name == 'Ali') {
return 80;
}
if (name == 'Sara') {
return 95;
}
return null;
}
void main() {
print(findMark('Sara'));
print(findMark('Zayan'));
int mark = findMark('Zayan') ?? 0;
print(mark);
}95
null
0The caller gets an int?, so it must deal with the missing case — here with ??. Trying
to store it straight into an int fails:
int? findMark(String name) {
if (name == 'Ali') {
return 80;
}
return null;
}
void main() {
int mark = findMark('Sara'); // ✗
print(mark);
}Error: A value of type 'int?' can't be assigned to a variable of type 'int'.
int mark = findMark('Sara'); // ✗
^13. late Can Delay a Calculation
Lecture 006 promised one more use of late. When a late variable is given a value from a
function call, the call does not run at the declaration. It runs the first time the
variable is read — and only once.
int loadBalance() {
print('Loading balance...');
return 1000;
}
void main() {
late final int balance = loadBalance();
print('Program started');
print('Balance: $balance');
print('Again: $balance');
}Program started
Loading balance...
Balance: 1000
Again: 1000'Loading balance...' appears after 'Program started', and only once. Remove late and
the order flips: loadBalance() runs right away on the declaration line, before
'Program started'. This is useful for slow calculations that might not be needed at all.
14. A Real-World Example
double subtotal(double price, int quantity) {
return price * quantity;
}
double discount(double amount) {
if (amount < 1000) {
return 0;
}
return amount * 0.10;
}
void printReceipt(String customer, double price, int quantity) {
double sub = subtotal(price, quantity);
double off = discount(sub);
print('Customer: $customer');
print('Subtotal: $sub');
print('Discount: $off');
print('Total: ${sub - off}');
}
void main() {
printReceipt('Sara', 450, 3);
}Customer: Sara
Subtotal: 1350.0
Discount: 135.0
Total: 1215.0Each function has one job. subtotal and discount calculate and return; printReceipt
takes parameters, combines the returned values, and prints. Small functions that return
values can be combined like building blocks.
Code Examples
Example 1 — One Parameter
void welcome(String name) {
print('Welcome, $name!');
}
void main() {
welcome('Ali');
welcome('Zayan');
}Welcome, Ali!
Welcome, Zayan!Example 2 — Two Parameters
void showPrice(String product, double price) {
print('$product costs $price');
}
void main() {
showPrice('Notebook', 250);
showPrice('Pen', 40.5);
}Notebook costs 250.0
Pen costs 40.5Example 3 — Returning an int
int multiply(int a, int b) {
return a * b;
}
void main() {
int result = multiply(6, 7);
print(result);
}42Example 4 — Returning a bool
bool isAdult(int age) {
return age >= 18;
}
void main() {
print(isAdult(20));
print(isAdult(6));
}true
falseage >= 18 is already a bool, so the function returns it directly — no if needed.
Example 5 — Returning a String
String fullName(String first, String last) {
return '$first $last';
}
void main() {
String name = fullName('Sara', 'Khan');
print('Hello, $name');
}Hello, Sara KhanExample 6 — Early Return
String sign(int n) {
if (n > 0) {
return 'positive';
}
if (n < 0) {
return 'negative';
}
return 'zero';
}
void main() {
print(sign(5));
print(sign(-3));
print(sign(0));
}positive
negative
zeroExample 7 — Student Marks
int total(int math, int science, int english) {
return math + science + english;
}
double average(int sum, int subjects) {
return sum / subjects;
}
void main() {
int sum = total(80, 75, 85);
print('Total: $sum');
print('Average: ${average(sum, 3)}');
}Total: 240
Average: 80.0How it works
totaladds three marks and returns240.- That returned value is stored in
sumand passed on toaverage. /always produces adouble, soaveragereturns80.0.
Example 8 — Shopping Total
double lineTotal(double price, int quantity) {
return price * quantity;
}
void main() {
double notebooks = lineTotal(250, 3);
double pens = lineTotal(40, 5);
print('Notebooks: $notebooks');
print('Pens: $pens');
print('Grand total: ${notebooks + pens}');
}Notebooks: 750.0
Pens: 200.0
Grand total: 950.0How it works
- One function calculates any line of the bill.
- Each call returns a
double, stored in its own variable. - The grand total is simply the two returned values added together.
Example 9 — Bank Balance
int withdraw(int balance, int amount) {
if (amount > balance) {
print('Declined: only $balance available');
return balance;
}
return balance - amount;
}
void main() {
int balance = 1000;
balance = withdraw(balance, 300);
print('Balance: $balance');
balance = withdraw(balance, 900);
print('Balance: $balance');
}Balance: 700
Declined: only 700 available
Balance: 700How it works
withdrawreturns the new balance, andmainstores it back intobalance.- When the amount is too large, the early return gives back the unchanged balance.
- The function never changes
main's variable itself —maindecides to store the result.
Example 10 — Temperature Conversion
double toFahrenheit(double celsius) {
return celsius * 9 / 5 + 32;
}
String describe(double celsius) {
if (celsius >= 30) {
return 'hot';
}
if (celsius >= 15) {
return 'mild';
}
return 'cold';
}
void main() {
double today = 34;
print('$today°C is ${toFahrenheit(today)}°F, which is ${describe(today)}');
}34.0°C is 93.2°F, which is hotBoth returned values sit directly inside the string with ${...}.
Common Beginner Mistakes
1. Passing arguments in the wrong order
// void showStudent(String name, int marks) { ... }
// showStudent(92, 'Zayan');Error: The argument type 'int' can't be assigned to the parameter type 'String'.Positional arguments must follow the order of the parameters.
2. Passing the wrong number of arguments
// int add(int a, int b) { ... }
// add(5, 3, 2);Error: Too many positional arguments: 2 allowed, but 3 found.
Try removing the extra positional arguments.3. Calculating a value but forgetting return
// int add(int a, int b) {
// a + b;
// }Error: A non-null value must be returned since the return type 'int' doesn't allow null.a + b computes the sum and throws it away. Write return a + b;.
4. Printing instead of returning
A function that prints its result cannot be used in a calculation. If the caller needs the value, return it and let the caller print it.
5. Storing the result in the wrong type
// int add(int a, int b) { ... }
// String total = add(2, 3);Error: A value of type 'int' can't be assigned to a variable of type 'String'.6. Leaving out the return type
The return type becomes dynamic, and mistakes slip through to run time. Always write it.
Best Practices
- Always write the return type and the type of every parameter.
- Name functions with verbs or questions:
calculateTotal,isAdult,findMark. - Prefer functions that return values over functions that print them; print in one place.
- Use early returns to handle special cases first, keeping the main path unindented.
- Use a nullable return type only when "no result" is a real possibility.
- Keep each function to one job, and keep its parameter list short.
Mini Challenge
Write a function grade that takes an int mark and returns a String: 'A' for 80 or
more, 'B' for 60 or more, and 'C' otherwise. Use early returns. Call it for Ali (85),
Sara (64), and Zayan (40).
Your program should print exactly:
Ali: A
Sara: B
Zayan: CTry it yourself before opening the solution.
Show solution
String grade(int marks) {
if (marks >= 80) {
return 'A';
}
if (marks >= 60) {
return 'B';
}
return 'C';
}
void main() {
print('Ali: ${grade(85)}');
print('Sara: ${grade(64)}');
print('Zayan: ${grade(40)}');
}Ali: A
Sara: B
Zayan: CHow it works
- Each
ifreturns as soon as a grade matches, ending the function. - The final
return 'C';covers every remaining mark, so every path returns. - The calls sit inside the strings with
${...}.
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
- Write a function
sayGoodbyethat takes aStringname and printsGoodbye, <name>!. Call it with'Zayan'. - Write a function
halfthat takes adoubleand returns half of it as adouble. Printhalf(9). - Write a function
isEventhat takes anintand returns abool. PrintisEven(10)andisEven(7).
Application
- Write
int rectangleArea(int width, int height). Print the area forwidth = 12andheight = 5. - Write
int subtract(int a, int b). Storesubtract(100, 35)in a variable and printResult: 65. - Write
String initials(String first, String last)that returns the first letter of each name joined together (usefirst[0]). Printinitials('Ali', 'Raza'). - Write
int maxOf(int a, int b)using an early return. PrintmaxOf(8, 3)andmaxOf(4, 9). - Write
double priceWithTax(double price)that adds 5% tax. PrintpriceWithTax(200).
Challenge
- Write
int? safeDivide(int a, int b)that returnsnullwhenbis0, otherwisea ~/ b. PrintsafeDivide(20, 4), then printsafeDivide(5, 0) ?? -1. - Write
int deposit(int balance, int amount)andint withdraw(int balance, int amount)(decline with an early return if the amount is too large). Starting from500, deposit200, withdraw1000, then withdraw300, printing the balance after each step asBalance: ….
Practice Answers
Question 1 — Solution
void sayGoodbye(String name) {
print('Goodbye, $name!');
}
void main() {
sayGoodbye('Zayan');
}Goodbye, Zayan!Question 2 — Solution
double half(double n) {
return n / 2;
}
void main() {
print(half(9));
}4.5The argument 9 is accepted for a double parameter and becomes 9.0.
Question 3 — Solution
bool isEven(int n) {
return n % 2 == 0;
}
void main() {
print(isEven(10));
print(isEven(7));
}true
falseQuestion 4 — Solution
int rectangleArea(int width, int height) {
return width * height;
}
void main() {
print(rectangleArea(12, 5));
}60Question 5 — Solution
int subtract(int a, int b) {
return a - b;
}
void main() {
int result = subtract(100, 35);
print('Result: $result');
}Result: 65Question 6 — Solution
String initials(String first, String last) {
return '${first[0]}${last[0]}';
}
void main() {
print(initials('Ali', 'Raza'));
}ARQuestion 7 — Solution
int maxOf(int a, int b) {
if (a > b) {
return a;
}
return b;
}
void main() {
print(maxOf(8, 3));
print(maxOf(4, 9));
}8
9Question 8 — Solution
double priceWithTax(double price) {
return price * 1.05;
}
void main() {
print(priceWithTax(200));
}210.0Question 9 — Solution
int? safeDivide(int a, int b) {
if (b == 0) {
return null;
}
return a ~/ b;
}
void main() {
print(safeDivide(20, 4));
print(safeDivide(5, 0) ?? -1);
}5
-1Dividing by zero has no sensible answer, so the function says so with null, and the caller
picks a fallback with ??.
Question 10 — Solution
int deposit(int balance, int amount) {
return balance + amount;
}
int withdraw(int balance, int amount) {
if (amount > balance) {
print('Declined');
return balance;
}
return balance - amount;
}
void main() {
int balance = 500;
balance = deposit(balance, 200);
print('Balance: $balance');
balance = withdraw(balance, 1000);
print('Balance: $balance');
balance = withdraw(balance, 300);
print('Balance: $balance');
}Balance: 700
Declined
Balance: 700
Balance: 400Quick Revision
- What is the difference between a parameter and an argument?
- How does Dart match arguments to parameters in this lecture?
- What two things does
returndo? - What does
voidmean as a return type? - Why must a function with return type
intreturn on every path? - What return type does a function get if you leave the return type out?
- When should a function have a nullable return type like
int?? - When does
late final x = compute();callcompute()? - Why do you need
${...}to put a function call inside a string?
Key Takeaways
- A parameter is a typed variable in the function definition; an argument is the value passed in a call.
- Arguments are matched to parameters by position, and Dart checks both their types and their number.
- The return type before the name says what the function gives back;
voidmeans nothing. returnhands back a value and ends the function immediately.- A returned value can be stored, printed, interpolated, calculated with, or passed to another function.
- Early returns handle special cases first; a
voidfunction uses a barereturn;. - A non-
void, non-nullable function must return a value on every path. - Leaving out the return type makes it
dynamic— always write it. - A nullable return type (
int?) tells the caller "there may be no answer". latewith a function call delays that call until the variable is first read.
What's Next?
Lecture 032 — Positional Parameters. Every parameter in this lecture was required: miss
one and the program does not compile. But some values are genuinely optional — a greeting
that is usually 'Hello', a discount that is usually zero. Next we look closer at positional
parameters and learn how to make some of them optional, with default values.