Concepts / How to Write a Function

How to Write a Function

Functions allow you to name groups of statements, which is the foundation of readable code.

  • Programming

From Statements to Intent

A program can be viewed in two ways. At a detailed level, it is a sequence of statements that a computer follows. At a higher level, it is a message that explains an intended process to the people who read and maintain it. Functions help connect these two views by giving a name to a group of statements.

A function is a named group of statements. The name lets a reader understand the purpose of that group without immediately examining every statement inside it. Instead of seeing a long sequence of implementation details, the reader can follow a sequence of meaningful names.

The main readability benefit of a function is not merely that statements are grouped together. The benefit is that the group has a name that communicates what the group does.

Naming a Group of Statements

To organize a program into functions, identify statements that belong to one clear task and give that group a descriptive name. The name should describe what the function does, rather than how its internal statements accomplish that task. A focused function has a single, well-defined purpose.

namesstartsidentifiescalculate_averagemeaningful function nameRelated statementsone well-defined purposeFunction calluse the function nameFunction executionstatements inside the grouprun
What statements belong inside a function, and how does calling its name execute that group?

Turning Grade Processing into Named Steps

Imagine a program that processes student grades. How can its overall purpose become easier to read?

Identify related work: Group the statements that calculate an average, determine a letter grade, and display the results.

Give each group a descriptive name: Use the names calculate_average, determine_letter_grade, and display_results to communicate the purpose of the three groups.

Read the high-level flow: A reader can now understand the main sequence as calculating the average, determining the grade, and displaying the results without first tracing every internal statement.

The named functions transform a long sequence of grade-processing statements into a readable description of the program's logical flow.

Following the Execution Path

A function name does not replace the work of the statements inside the function. It provides a clear entry point to that work. When the program calls a function, execution moves into the function, carries out the statements inside it, and then returns to the point where the call was made. The program continues from there.

callsjumps intoreturns toMain programbefore the callcalculate_averagefunction callFunction statementswork is carried outMain programcontinues after the call
How does execution move from the main program into a function and back again?

What do you think happens?

A main program calls determine_letter_grade and then display_results. After determine_letter_grade finishes, what is the next high-level step?

  • The program continues with display_results
  • The program permanently remains inside determine_letter_grade
  • The program must scan every statement in the whole program again
Reveal answer

Answer: The program continues with display_results.

A function carries out its internal statements and then returns execution to the point where it was called. The reader can therefore follow the sequence of named calls as the program's high-level path.

Reading function calls in order provides a high-level execution path. You can follow the main logic through the names first, then inspect a function's internal statements only when you need its implementation details.

Readable Structure Before and After

A monolithic block places every statement in one long sequence. To understand its overall purpose, a reader must trace through the individual lines. Dividing the same logic into named functions creates layers: the function names show the program's structure, while the statements inside each function preserve the details.

thenthenGrade statementsall details in one sequencecalculate_averagenamed stepdetermine_letter_gradenamed stepdisplay_resultsnamed step
How does the same student-grade program look before and after related statements are divided into named functions?
OrganizationWhat the reader must doWhat the structure communicates
Monolithic blockTrace individual statements to understand the overall purposeThe details are present, but the high-level intent is difficult to see
Named functionsRead the function names first and inspect details when neededThe logical sequence and purpose of each step are visible

Names That Support Maintenance

Meaningful names continue to help after the program has been written. When a bug appears, a descriptive function name can indicate which part of the program to investigate. Instead of scanning a monolithic block, you can focus on the function whose stated purpose is connected to the problem.

Names also act as documentation when you return to the program later. Code that is easy to read is easier to fix when bugs appear, easier to modify when requirements change, and easier to learn from during later review. A function name should therefore be specific enough to communicate purpose, while the function itself should remain focused on one well-defined task.

  • Using a vague function name

    The reader still has to inspect the implementation details to understand the function's purpose.

    Fix: Choose a descriptive name that communicates the function's purpose at a glance.

  • Naming a function after its implementation details

    The name becomes less useful as an explanation of the program's intent.

    Fix: Describe what the function does, not how it does it.

  • Putting several unrelated purposes into one function

    The function becomes harder to understand and makes the program's logical sequence less clear.

    Fix: Keep each function focused on a single, well-defined purpose.

  • Ignoring function names while debugging

    This wastes effort in code that may be unrelated to the bug.

    Fix: Use descriptive names to identify the part of the program that is most likely worth investigating first.

Practice the Design Choice

EASY

A student-grade program contains three related stages: it calculates an average, determines a letter grade, and displays the results. Explain how you would divide these stages into functions and why your names would help someone read or debug the program.

Hints
  • Give each distinct stage a name that communicates its purpose.
  • Keep the names focused on what each function does.
  • Describe how the sequence of names would show the program's high-level flow.
  1. Find a group of statements with one clear purpose.
  2. Choose a name that describes what that group does.
  3. Keep the function focused on that single purpose.
  4. Read the function names in sequence to check whether the program's high-level intent is clear.
  5. When debugging, begin by investigating the function whose purpose is connected to the problem.

Key Takeaways

  1. A function gives a name to a group of statements.
  2. A descriptive name communicates purpose without requiring the reader to inspect implementation details.
  3. Function calls create a readable high-level sequence: execution enters the function, completes its statements, and returns to the calling point.
  4. Organizing code into focused, well-named functions transforms a monolithic block into a logical narrative.
  5. Meaningful names make debugging, modification, and later code review easier.

Key Takeaways

  • Functions allow you to name groups of statements so readers can understand program intent more easily.
  • A function call provides a named checkpoint in the program's execution path.
  • Descriptive names reveal what a function does without forcing readers to study its internal details.
  • Focused functions with meaningful names make debugging, maintenance, and future review more efficient.