# Python higher-order function (decorator) sample

I have made various tools and web scripts with Scheme on my own machine, but there is no way that it is compatible with Scheme with cheap, high-performance, high-performance PaaS and SaaS these days, and with Python as an alternative language, Scheme We created and organized a sample for handling higher-order functions, which is one of the features.

A Higher-order Function is simply a "function that takes the function itself as an argument or a return value". For details, refer to "Structure and Interpretation of Computer Programs" "1.3 Formulating Abstractions with Higher-Order Procedures".

# Definition and use of higher-order functions

Although lambda can be used in Python, it can only be handled as a single expression, so it seems that it is common to write a function that is locally defined by def.

#### higherorder.py

def threetimes(f):
def retfunc(x, y):
print(f(f(f(x, y), y), y))
return (retfunc)

def f(x, y):
return (2 * x + y)

threetimes(f)(10, 5)
# => f(f(f(x, y), y), y)
# => (2 * (2 * (2 * 10 + 5) + 5) + 5) => "115"

def threetimes_message(mes = ""):
def _threetimes(f):
def retfunc(x, y):
print(mes, end="")
print(f(f(f(x, y), y), y))
return (retfunc)
return (_threetimes)

threetimes_message("Result = ")(f)(10, 5)
# => "Result = 115"

threetimes_message()(f)(10, 5)
# => "115"

An example of the corresponding Scheme code is as follows. Confirm the execution with Gauche.

#### higherorder.scm

(define threetimes
(lambda (f)
(lambda (x y)
(print (f (f (f x y) y) y)))))

(define f (lambda (x y) (+ (* 2 x) y)))
((threetimes f) 10 5)
; => (f (f (f 10 5) 5) 5)
; => (+ (* 2 (+ (* 2 (+ (* 2 10) 5)) 5)) 5) => "115"

(define threetimes_message
(lambda (f . mes)
(lambda (x y)
(if (not (null? mes)) (display (car mes)))
(print (f (f (f x y) y) y)))))

((threetimes_message f "Result = ") 10 5)
; => "Result = 115"
((threetimes_message f) 10 5)
; => "115"

# Decorator

Syntax sugar when using higher-order functions. The etymology is a kind of design pattern. This is a convenient way to write a framework such as Flask when you want to define it as a higher-order function group and add functions to the user-defined functions that perform the original processing.

#### decorators.py

# threetimes，threetimes_message is higher order.Use py definition

@threetimes
def f(x, y):
return(2 * x + y)

f(10, 5) # => "115"

@threetimes_message(mes = "Result = ")
def f(x, y):
return(2 * x + y)

f(10, 5) # => "Result = 115"

@threetimes_message()
def f(x, y):
return (2 * x + y)

f(10, 5) # => "115"

# Other samples using lambda etc.

Example in Wikipedia article (higher-order function) Some excerpts.

#### others.py

def args_10_5(f):
def _args_10_5():
f(10, 5)
return (_args_10_5)

def f(x, y):
print("x = ", x, ", y = ", y)

args_10_5(f)() # => "x =  10 , y =  5"

def f(x, y, z, w):
return (4 * x + 3 * y + 2 * z + w)

f(2, 3, 4, 5) # => 30

def f(x):
return (lambda y: lambda z: lambda w: 4 * x + 3 * y + 2 * z + w)

f(2)(3)(4)(5) # => 30

def unfold(pred, f, update, seed):
if pred(seed):
return ([])
else:
r = unfold(pred, f, update, update(seed))
r.insert(0, f(seed))
return (r)

unfold(lambda x: x > 10, lambda x: x * x, lambda x: x + 1, 1)
# => [1, 4, 9, 16, 25, 36, 49, 64, 81, 100]