为什么追加函数调用时函数执行顺序看起来相反?

I was reading this question: Decorator functions in Go and am wondering why the execution order of the example in the accepted answer seems reversed to me.

I have broken it down to the following minimal example and am wondering if the effect is due to function chaining.

// Interesting Part
some_string := "Some_String"
var fn3 StringManipulator = ident
fn3 = AppendDecorator(" GOLANG", ToLower(PrependDecorator("DECORATED ", fn3)))
fmt.Println(fn3(some_string))
// Prints "DECORATED some_string golang"

// Function Definitions
func ToLower(m StringManipulator) StringManipulator {
    return func(s string) string {
        lower := strings.ToLower(s)
        return m(lower)
    }
}

func AppendDecorator(x string, m StringManipulator) StringManipulator {
        return func(s string) string {
            return m(s + x)
        }
}

func PrependDecorator(x string, m StringManipulator) StringManipulator {
    return func(s string) string {
        return m(x + s)
    }
}

As mentioned in the code this yields "DECORATED some_string golang" indicating that the functions were executed from left to right, whereas normal functions evaluate from innermost to outermost, i.e. right to left. [This reminds me of postmultiplication of transformation matrices - there the order is also "reversed", i.e. M_1 * M_2 * M_3] Is this due to function chaining or what is the reason? Could somebody help me understand how this executes in detail?

Thank you in advance.

I rewrote your example to illustrate.

The nested function calls execute from inside to outside. Each function call returns a function. Eventually the variable m is assigned the result of AppendDecorator which is itself a function composed of all the decorators that looks something like this:

m := func(s string) string {
    return ("DECORATED " + strings.ToLower(s + " GOLANG"))
}

When we execute m(s) (inside fmt.Println(m(s)) we are executing the function returned by AppendDecorator. This function calls m(s + x) where m is the function returned by ToLower. When this function executes it calls m(lower) where m is the function returned by PrependDecorator. When this function executes it calls m(x + s) where m is the Identity function that we passed in.

package main

import (
    "fmt"
    "strings"
)

// StringManipulator manipulate a string
type StringManipulator func(str string) string

// Identity a string manipulator that leaves the string unchanged
func Identity(s string) string {
    fmt.Println("Executing Identity manipulator")
    return s
}

// ToLower a lower case string manipulator
func ToLower(m StringManipulator) StringManipulator {
    fmt.Println("Returning ToLower manipulator")
    return func(s string) string {
        fmt.Println("Executing ToLower manipulator")
        lower := strings.ToLower(s)
        return m(lower)
    }
}

// AppendDecorator append a string manipulator
func AppendDecorator(x string, m StringManipulator) StringManipulator {
    fmt.Println("Returning Append manipulator")
    return func(s string) string {
        fmt.Println("Executing Append manipulator")
        return m(s + x)
    }
}

// PrependDecorator prepend a string manipulator
func PrependDecorator(x string, m StringManipulator) StringManipulator {
    fmt.Println("Returning Prepend manipulator")
    return func(s string) string {
        fmt.Println("Executing Prepend manipulator")
        return m(x + s)
    }
}

func main() {
    s := "Some_String"

    m := AppendDecorator(" GOLANG", ToLower(PrependDecorator("DECORATED ", Identity)))
    fmt.Println(m(s))
}

The output from m := AppendDecorator(" GOLANG", ToLower(PrependDecorator("DECORATED ", Identity))) is:

Returning Prepend manipulator
Returning ToLower manipulator
Returning Append manipulator

and the output from fmt.Println(m(s)) is:

Executing Append manipulator
Executing ToLower manipulator
Executing Prepend manipulator
Executing Identity manipulator
DECORATED some_string golang