Concepts / Built-in Functions and Their Types

Built-in Functions and Their Types

Calling one function from another lets you build complex behavior from simpler reusable pieces. The important tracing habit is to return to the function that made the most recent call before continuing outward.

  • Programming

A Function Name Holds a Value

When you define a function, Python creates a variable whose value is a function object. This means the function name is not merely a label for some lines of code. It refers to an object that contains the instructions written inside the function definition.

print_lyricsvariableFunction objectcontains the functioninstructionsrefers to
What does the variable created by a function definition contain, and how does it refer to the function object?

The same idea applies to ordinary variables. A variable such as x can hold a number, and a variable such as name can hold a string. A function name holds a function object. Because the function object is a value, you can inspect it just as you can inspect other values.

Inspecting the Function Type

A function object has the type function. After defining a function named print_lyrics, you can print the function name to inspect the function object and check its type. The printed function representation identifies it as a function object, while the type check reveals function as its type.

print_lyricsfunction objectfunctiontype of the objectInspectionprint and type checkhas typecan be inspected
How is a function object represented as a value, and what does inspecting its type reveal?
Worked example

Inspecting print_lyrics

Suppose a function named print_lyrics has already been defined. What two things can you learn by inspecting its name?

  1. 1
    Inspect the value

    Printing print_lyrics displays a representation of the function object held by that variable.

  2. 2
    Inspect the type

    Checking the type of print_lyrics identifies the object as having type function.

  3. 3
    Interpret the result

    The name refers to an object containing the instructions from the function definition; it is not just an inactive label.

Result

The variable print_lyrics holds a function object, and that object has type function.

Calling a Function

Definition

To call a function, write its name followed by parentheses. The general form is function_name(). The parentheses tell Python to execute the code inside the function object.

This syntax is the same for a custom function and a built-in function. For example, calling print_lyrics() uses the same name-and-parentheses pattern as calling print(). Their implementations differ, but the act of calling them follows the same basic form.

Function kindCall formWhere the implementation is visible
Built-in functionfunction_name()The code is written in C and hidden from you
Custom functionfunction_name()You can see and understand the function body

Built-in and custom functions share the same calling syntax, although their implementations are presented differently.

print()built-in functionprint_lyrics()custom functionName plus parenthesescalls the functionFunction bodybuilt-in code is hidden;custom code is visibleusesusesexecutes
What is the same about calling a built-in function and a custom function, and where does their execution differ?

Following Control Flow

When Python reaches a function call, execution pauses at that call. Control moves into the function body, where the statements run in order. When the function finishes, control returns to the line immediately after the call. This movement explains why statements inside a function do not run merely because the function was defined; they run when the function is called.

Callerreaches the function callFunction bodystatements run in orderCallercontinues after the callcallreturn after finishing
What happens to execution when a function is called, and how does control return to the caller after the function finishes?
Worked example

Tracing print_lyrics()

Trace what happens when a caller reaches print_lyrics(), whose body contains two print statements.

  1. 1
    Reach the call

    Execution reaches the statement that calls print_lyrics() and pauses at that point.

  2. 2
    Enter the body

    Control jumps into the print_lyrics function body.

  3. 3
    Run the statements

    The two print statements in the body execute in order, so their output appears in that order.

  4. 4
    Return to the caller

    After the function body finishes, control returns to the line immediately after the call.

Result

The call temporarily moves execution into print_lyrics, then execution resumes after the call when the body is complete.

Nested Function Calls

A function can call another function from inside its own body. Control then becomes nested: execution enters the outer function, moves into the inner function, returns to the outer function when the inner function finishes, and finally returns to the original caller when the outer function finishes.

Worked example

Tracing repeat_lyrics()

Suppose repeat_lyrics contains two calls to print_lyrics. Trace the order of control.

  1. 1
    Call repeat_lyrics

    The original caller transfers control into repeat_lyrics.

  2. 2
    Make the first inner call

    The first call to print_lyrics transfers control into print_lyrics, whose statements run in order.

  3. 3
    Return to repeat_lyrics

    When print_lyrics finishes, control returns to the next statement inside repeat_lyrics.

  4. 4
    Make the second inner call

    The second call to print_lyrics runs the same function body again.

  5. 5
    Return to the original caller

    After repeat_lyrics finishes, control returns to the line after the original call.

Result

The nesting is caller to repeat_lyrics, repeat_lyrics to print_lyrics, back to repeat_lyrics, and then back to the original caller.

Key point

Calling one function from another lets you build complex behavior from simpler reusable pieces. The important tracing habit is to return to the function that made the most recent call before continuing outward.

Mistakes with Function Objects

  • Common mistake

    Treating a function name as only a label for code

    What it looks like

    Assuming print_lyrics is not a value that can be inspected

    Why it fails

    The name is a variable that holds a function object.

    Do this instead

    Remember that the function object can be printed, checked for its type, and treated as a value.

  • Common mistake

    Forgetting the parentheses when calling a function

    What it looks like

    Writing only the function name when the goal is to execute it

    Why it fails

    The function name refers to the function object, while the parentheses tell Python to execute the code inside it.

    Do this instead

    Use the form function_name() when you want to call the function.

  • Common mistake

    Assuming a function body runs when the function is defined

    What it looks like

    Expecting the statements inside print_lyrics to run before print_lyrics() is called

    Why it fails

    The body runs when Python encounters the function call.

    Do this instead

    Trace execution from the call into the body, then back to the line after the call.

  • Common mistake

    Skipping the inner call while tracing nested functions

    What it looks like

    Moving directly from repeat_lyrics to the line after repeat_lyrics without tracing print_lyrics

    Why it fails

    Control enters the inner function before returning to the outer function.

    Do this instead

    Track each call and return in order: outer function, inner function, outer function, original caller.

Best practice

When reasoning about unfamiliar code, separate two questions: what value does the function name hold, and when is that function object called? This distinction prevents confusion between inspecting a function and executing it.

Practice the Trace

MEDIUM

A function named outer_function calls inner_function from inside its body. Describe the complete control-flow path from the original caller until execution resumes after the call to outer_function.

Hints
  • Begin with the original caller.
  • Identify which function receives control first.
  • After inner_function finishes, return to the next statement in outer_function.
  • Only after outer_function finishes does control return to the original caller.
EASY

Explain the difference between inspecting print_lyrics and calling print_lyrics(). Your answer should mention the function object, its type, and the role of parentheses.

Hints
  • Inspection treats the name as a value.
  • The type of that value is function.
  • Parentheses request execution of the function body.

Key Takeaways

  1. 1
    Defining a function creates a variable that holds a function object.
  2. 2
    A function object has type function and can be inspected like other values.
  3. 3
    Custom functions and built-in functions use the same name-and-parentheses calling syntax.
  4. 4
    A function call moves control into the function body and returns control to the line after the call when the body finishes.
  5. 5
    Nested calls return control inward to outward: the inner function returns to the outer function, which then returns to its caller.

At a glance

  • A defined function is stored as a function object in a variable named by the function definition.
  • The function object has type function and can be inspected without calling it.
  • Parentheses distinguish calling a function from merely referring to its function object.
  • Execution enters the function body during a call and resumes after the call when the body finishes.
  • Functions can call other functions, creating nested control flow.

More concepts starting with B