We're sorry but this app doesn't work properly without JavaScript enabled. Please enable it to continue.

This lesson's interactive features are locked, please to keep using them

Why Transform?

You might be wondering:

  • "When would I use function transformations in the real world?"
  • "Isn't it simpler to just define functions at the top level of the code, and call them as needed?"

Good questions. To be clear, we don't just transform functions at runtime for the fun of it! We use advanced techniques like function transformation only when they make our code simpler than it would otherwise be.

Code Reusability

Creating variations of the same function dynamically can make it a lot easier to share common functionality. Take a look at this formatter function. It accepts a "pattern" and returns a new function that formats text according to that pattern:

from collections.abc import Callable


def formatter(pattern: str) -> Callable[[str], str]:
    def inner_func(text: str) -> str:
        result: str = ""
        i: int = 0
        while i < len(pattern):
            if pattern[i : i + 2] == "{}":
                result += text
                i += 2
            else:
                result += pattern[i]
                i += 1
        return result

    return inner_func

Now we can create new formatters easily:

bold_formatter: Callable[[str], str] = formatter("**{}**")
italic_formatter: Callable[[str], str] = formatter("*{}*")
bullet_point_formatter: Callable[[str], str] = formatter("* {}")

And use them like this:

print(bold_formatter("Hello"))
# **Hello**
print(italic_formatter("Hello"))
# *Hello*
print(bullet_point_formatter("Hello"))
# * Hello

Closures

90% of the time, when I use function transformations, it's because I want to create a closure. We'll talk about closures in the next chapter!