A função de ordem superior (Higher Order Function) é um conceito fundamental na programação funcional, onde uma função pode receber outras funções como argumentos ou retornar funções como resultado. Esse padrão é amplamente utilizado em linguagens como JavaScript, Haskell e Lisp, permitindo a criação de código mais modular e reutilizável. Embora Go não seja uma linguagem puramente funcional, ela suporta funções de ordem superior.
Neste exemplo, a função setupTestServer()
cria um servidor de teste HTTP e retorna uma URL, um roteador e uma função. Ela é considerada uma Higher Order Function porque retorna uma função que pode ser usada para fechar o servidor após os testes.
1
2
3
4
5
6
7
8
9
10
11
12
13
| func setupTestServer() (string, *http.ServeMux, func()) {
router := http.NewServeMux()
srv := httptest.NewServer(router)
return srv.URL, router, func() { srv.Close() }
}
func TestSomething(t *testing.T) {
url, router, close := setupTestServer()
defer close()
// ...
}
|
É muito comum em JS utilziar funções de ordem superior como callbacks, como no exemplo abaixo:
1
2
3
4
5
6
7
8
9
10
11
12
| function fetchData(url, callback) {
fetch(url)
.then(response => response.json())
.then(data => callback(data))
.catch(error => console.error('Error:', error));
}
function processData(data) {
console.log('Processed Data:', data);
}
fetchData('https://api.example.com/data', processData);
|
Em Go também podemos criar funções que recebem outras funções como argumentos. Na função DoSomething()
abaixo, passamos uma função como argumento para processar um mapa de parâmetros. Essa abordagem permite que a função seja flexível e reutilizável, aceitando diferentes implementações dessa função de carregamento de parâmetros.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
| func LoadParams(params map[string]string) {
for key, value := range params {
fmt.Println("Key:", key, "Value:", value)
}
}
func DoSomething(ctx context.Context, loader func(map[string]string)) {
params := map[string]string{
"param1": "value1",
"param2": "value2",
}
loader(params)
}
func main() {
DoSomething(context.Background(), LoadParams)
}
|
Imagina criar algo parecido com isso?
1
2
3
4
5
6
7
8
9
| func Y(g func(any) any) func(any) any {
return func(f any) func(any) any {
return f.(func(any) any)(f).(func(any) any)
}(func(f any) any {
return g(func(x any) any{
return f.(func(any) any)(f).(func(any) any)(x)
})
})
}
|