.docname {Extending functions}
.include {docs}

Function extension is a powerful feature that lets you transform, decorate, or replace a function's behavior.

.box 
    This is the backbone of the [element styling](element-styling.qd) engine, when the extended function is a [Markdown primitive](primitives.qd), such as [`.heading`](headings.qd). See its page for more details about extending Markdown elements.

You can extend any previously-declared function using the **`.extend`** .docslink {quarkdown-stdlib/com.quarkdown.stdlib.module.Flow/extend.html} function within a scope. The extension wraps the original function without losing the original definition.

.examplemirror
    .function {greet}
        name:
        Hello, .name!

    .extend {greet}
        .super::uppercase

    .greet {world}

## Accessing the original

Within the wrapper body, the original function is exposed as **`.super`**. Calling it invokes the original with the same arguments.

## Parameters

The wrapper body is a [lambda](lambda.qd). Its explicit parameters, if any, must match the names of the original function's parameters and let you intercept the arguments the caller passed.

Because `.super` is the original function itself, it accepts the same arguments. Any argument you pass overrides the one the wrapper was called with, while everything you leave out falls through unchanged.

.examplemirror
    .function {greet}
        greeting name:
        .greeting, .name!

    .extend {greet}
        name:
        .super greeting:{Howdy}

    .greet {Hello} {world}

.examplemirror prelude:{New argument values can also rely on the original arguments, letting you transform them before passing them on:}
    .function {greet}
        greeting name:
        .greeting, .name!

    .extend {greet}
        greeting name:
        .super greeting:{.greeting::uppercase}

    .greet {Hello} {world}

All wrapper parameters are always optional. You only need to declare the parameters you actually use in the body.

.examplemirror 
    .function {greet}
        greeting name surname:
        .greeting, .name .surname!

    .extend {greet}
        name:
        .super name:{.name::uppercase}

    .greet {Hello} name:{John} surname:{Doe}

## Conditional extension

An optional `where` [inline lambda](lambda.qd) parameter lets you define a condition that, if not met at call time, lets the whole call fall back to the original definition. Its parameters follow the same rules as the body lambda.

.examplemirror
    .function {greet}
        greeting name:
        .greeting, .name!

    .extend {greet} where:{name: .name::equals {world}}
        greeting:
        .super greeting:{.greeting::uppercase}

    .greet {Hello} {world}

    .greet {Hello} {John}

.exampleoutput {
    .heading {H2} depth:{2} indexed:{no} background:{teal}
    
    .heading {H3} depth:{3} indexed:{no} background:{teal}
    
    .heading {H4} depth:{4} indexed:{no}
} \
               prelude:{Built-in functions, such as [`\.heading`](headings.qd), can be extended. See [*Element styling*](element-styling.qd) for more details.}
    .extend {heading} where:{depth: .depth::islower than:{4}}
        content:
        .super background:{teal}

    ## H2

    ## H3

    ## H4