Higher Order Function

· 339 words · 2 minute read

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.

 1func setupTestServer() (string, *http.ServeMux, func()) {
 2    router := http.NewServeMux()
 3    srv := httptest.NewServer(router)
 4
 5    return srv.URL, router, func() { srv.Close() }
 6}
 7
 8func TestSomething(t *testing.T) {
 9    url, router, close := setupTestServer()
10    defer close()
11
12    // ...
13}

É muito comum em JS utilziar funções de ordem superior como callbacks, como no exemplo abaixo:

 1function fetchData(url, callback) {
 2    fetch(url)
 3        .then(response => response.json())
 4        .then(data => callback(data))
 5        .catch(error => console.error('Error:', error));
 6}
 7
 8function processData(data) {
 9    console.log('Processed Data:', data);
10}
11
12fetchData('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.

 1func LoadParams(params map[string]string) {
 2    for key, value := range params {
 3        fmt.Println("Key:", key, "Value:", value)
 4    }
 5}
 6
 7func DoSomething(ctx context.Context, loader func(map[string]string)) {
 8    params := map[string]string{
 9        "param1": "value1",
10        "param2": "value2",
11    }
12
13    loader(params)
14}
15
16func main() {
17    DoSomething(context.Background(), LoadParams)
18}

Imagina criar algo parecido com isso?

1func Y(g func(any) any) func(any) any {
2    return func(f any) func(any) any {
3        return f.(func(any) any)(f).(func(any) any)
4    }(func(f any) any {
5        return g(func(x any) any{
6        return f.(func(any) any)(f).(func(any) any)(x)
7        })
8    })
9}