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}