Sotto è la funzione repeat scritta usando un paradigma funzionale, in modo tale che quando chiamata come repeat(square, 2)(5) applicherà la square funzione 2 volte sul numero 5 , qualcosa come square(square(5)) .
def repeat(f, n):
def identity(x):
return x
def apply_n_times(n):
def recursive_apply(x):
return apply_n_times(n - 1)(f(x))
if n < 0:
raise ValueError("Cannot apply a function %d times" % (n))
elif n == 0:
return identity
else:
return recursive_apply
return apply_n_times(n)
def square(x):
return mul(x, x)
Riguardo all'astrazione, vedo che repeat(square, 2) restituisce un dettaglio di implementazione sotto forma di apply_n_times(n - 1)(f(x)) più volte prima di fornire il risultato effettivo.
Per quanto riguarda l'incapsulamento, per l'espressione f = repeat(square, 2) si potrebbero mutare i membri dell'oggetto funzione, ad esempio: f.__name__='garbage'
Il concetto di higher order function consente di supportare l'astrazione e l'incapsulamento? Perché restituiscono i dettagli dell'implementazione e forniscono l'accesso per la mutazione.
Tali implementazioni esistenti nei software di grandi dimensioni sono molto noiose da usare, in quanto l'utente deve avere un'idea dell'implementazione prima di utilizzarla.