Ultimamente, tenho pensado muito em como fazer programação funcional em C ( não em C ++). Obviamente, C é uma linguagem processual e realmente não suporta programação funcional nativamente.
Existem extensões de compilador / idioma que adicionam algumas construções de programação funcional ao idioma? O GCC fornece funções aninhadas como uma extensão de idioma; funções aninhadas podem acessar variáveis do quadro de pilha pai, mas isso ainda está muito longe de fechamentos maduros.
Por exemplo, uma coisa que eu acho que poderia ser realmente útil em C é que, em qualquer lugar em que um ponteiro de função seja esperado, você poderá passar uma expressão lambda, criando um fechamento que se deteriora em um ponteiro de função. C ++ 0x vai incluir expressões lambda (o que eu acho incrível); no entanto, estou procurando ferramentas aplicáveis ao C. direto
[Editar] Para esclarecer, não estou tentando resolver um problema específico em C que seria mais adequado à programação funcional; Estou apenas curioso sobre quais ferramentas existem, se eu quisesse fazê-lo.
fonte
Respostas:
FFCALL permite criar fechamentos em C -
callback = alloc_callback(&function, data)
retorna um ponteiro de funçãocallback(arg1, ...)
equivalente à chamadafunction(data, arg1, ...)
. Você terá que lidar com a coleta de lixo manualmente, no entanto.De maneira semelhante, foram adicionados blocos ao fork do GCC da Apple; eles não são indicadores de função, mas permitem distribuir lambdas, evitando a necessidade de criar e liberar armazenamento manualmente para variáveis capturadas (efetivamente, algumas cópias e contagem de referência acontecem, ocultas atrás de algumas bibliotecas sintáticas de açúcar e tempo de execução).
fonte
Você pode usar as funções aninhadas do GCC para simular expressões lambda; na verdade, tenho uma macro para fazer isso por mim:
Use assim:
fonte
__fn__
é apenas um nome arbitrário para a função definida dentro do bloco({
...})
, não alguma extensão GCC ou macro predefinida? A escolha do nome__fn__
(parecido com a definição do GCC) realmente me fez coçar a cabeça e pesquisar na documentação do GCC sem nenhum bom efeito.A programação funcional não é sobre lambdas, é sobre funções puras. Portanto, o seguinte promove amplamente o estilo funcional:
Use apenas argumentos de função, não use estado global.
Minimize os efeitos colaterais, por exemplo, printf ou qualquer IO. Retorne dados que descrevem E / S que podem ser executados em vez de causar efeitos colaterais diretamente em todas as funções.
Isso pode ser alcançado em c simples, sem necessidade de mágica.
fonte
map
se alguém não tem recursos para passar uma função para ela?Atualmente, o livro de Hartel & Muller, Functional C , pode ser encontrado em (2012-01-02) em: http://eprints.eemcs.utwente.nl/1077/ (existe um link para a versão em PDF).
fonte
O pré-requisito para o estilo de programação funcional é uma função de primeira classe. Pode ser simulado no C portátil se você tolerar a seguir:
o tempo de execução desse código pode ser tão pequeno quanto o abaixo
Em essência, imitamos a função de primeira classe com os fechamentos representados como par de função / argumentos mais um monte de macroses. O código completo pode ser encontrado aqui .
fonte
O principal que vem à mente é o uso de geradores de código. Você gostaria de programar em um idioma diferente que fornecesse a programação funcional e depois gerar o código C a partir disso?
Se essa não é uma opção atraente, você pode abusar do CPP para fazer parte do caminho até lá. O sistema macro deve permitir que você emule algumas idéias de programação funcional. Ouvi dizer que o gcc é implementado dessa maneira, mas nunca verifiquei.
É claro que C pode transmitir funções usando ponteiros de função, os principais problemas são a falta de fechamentos e o sistema de tipos tende a atrapalhar. Você pode explorar sistemas macro mais poderosos que o CPP, como o M4. Acho que, em última análise, o que estou sugerindo é que o verdadeiro C não está pronto para a tarefa sem muito esforço, mas você pode estender o C para que esteja pronto para a tarefa. Essa extensão seria mais parecida com C se você usasse o CPP ou poderia ir para o outro extremo do espectro e gerar código C a partir de outro idioma.
fonte
Se você deseja implementar fechamentos, terá que se familiarizar com a linguagem assembly e trocar / gerenciar pilha. Não recomendando isso, apenas dizendo que é isso que você terá que fazer.
Não tenho certeza de como você lida com funções anônimas no C. Em uma máquina von Neumann, você pode executar funções anônimas no asm.
fonte
Veja o livro de Hartel & Muller, Functional C
http://www.ub.utwente.nl/webdocs/ctit/1/00000084.pdf
http://www.cs.bris.ac.uk/~henkm/f2c/index.html
fonte
A linguagem Felix é compilada em C ++. Talvez isso possa ser um passo, se você não se importa com C ++.
fonte
Bem, algumas linguagens de programação estão escritas em C. E algumas delas suportam funções como cidadãos de primeira classe, as linguagens nessa área são ecl (embbedabble common lisp IIRC), Gnu Smalltalk (gst) (Smalltalk tem blocos), então existem bibliotecas para "fechamentos", por exemplo, na glib2 http://library.gnome.org/devel/gobject/unstable/chapter-signal.html#closure que pelo menos se aproximou da programação funcional. Então, talvez usar algumas dessas implementações para fazer a programação funcional possa ser uma opção.
Bem, ou você pode aprender Ocaml, Haskell, Mozart / Oz ou similares ;-)
Saudações
fonte
O modo como desenvolvi a programação funcional em C foi escrever um intérprete de linguagem funcional em C. Chamei-o de Fexl, abreviação de "Function Expression Language".
O intérprete é muito pequeno, compilando até 68K no meu sistema com -O3 ativado. Também não é um brinquedo - estou usando-o para todo o novo código de produção que escrevo para o meu negócio (contabilidade baseada na Web para parcerias de investimento).
Agora, escrevo apenas o código C para (1) adicionar uma função interna que chama uma rotina do sistema (por exemplo, fork, exec, setrlimit etc.) ou (2) otimizar uma função que poderia ser escrita em Fexl (por exemplo, pesquisa para uma substring).
O mecanismo do módulo é baseado no conceito de "contexto". Um contexto é uma função (escrita em Fexl) que mapeia um símbolo para sua definição. Ao ler um arquivo Fexl, você pode resolvê-lo com qualquer contexto que desejar. Isso permite criar ambientes personalizados ou executar código em uma "caixa de areia" restrita.
http://fexl.com
fonte
O que você quer tornar funcional, a sintaxe ou a semântica em C? A semântica da programação funcional certamente poderia ser adicionada ao compilador C, mas quando você terminasse, você basicamente teria o equivalente a uma das linguagens funcionais existentes, como Scheme, Haskell, etc.
Seria melhor usar o tempo apenas para aprender a sintaxe daqueles idiomas que suportam diretamente essa semântica.
fonte
Não sei sobre C. No entanto, existem alguns recursos funcionais no Objective-C, o GCC no OSX também suporta alguns recursos; no entanto, eu recomendo novamente que você comece a usar uma linguagem funcional; há muitos mencionados acima. Eu, pessoalmente, comecei com o esquema, existem alguns livros excelentes, como The Little Schemer, que podem ajudá-lo.
fonte