Como resultado da discussão de comentários aqui , pergunto-me se você pode aprender Programação Funcional em C?
Como resultado da discussão de comentários aqui , pergunto-me se você pode aprender Programação Funcional em C?
Respostas:
Obviamente, você pode fazer programação funcional em C. Em teoria, você também pode aprender princípios de programação funcional em C, mas a linguagem não facilita.
Presumo que você tenha pelo menos um pouco de experiência em OOP; se o fizer, lembre-se de que o POO pode ser feito em C, incluindo polimorfismo, getters / setters, regras de visibilidade, etc. etc., mas é bastante doloroso fazê-lo e você precisa conhecer OOP e C por dentro. fora para retirá-lo. É o mesmo com a FP.
O que você deve fazer é primeiro aprender uma linguagem de programação funcional (a maioria delas possui regras de sintaxe surpreendentemente simples; não é a sintaxe que as torna difíceis de aprender) e depois deixar sua sabedoria recém-adquirida influenciar a maneira como você escreve C.
Conforme solicitado, algumas coisas que você pode aprender com o FP e aplicar em, digamos, C, C ++ ou Java:
C pode ser hackeado para oferecer alguns conceitos funcionais:
Esta questão StackOverflow lhe dirá mais. Mas, embora pareça possível fazer programação funcional (ou um grande subconjunto de) em C, hacks e extensões de compilador e qualquer que seja a melhor maneira de aprender sobre um conceito.
Para realmente aprender a programação funcional, sua melhor aposta é uma das linguagens de programação funcional mais importantes, como Lisp e seus dialetos ( Clojure , Scheme ), Erlang e Haskell . Qualquer uma dessas são ferramentas perfeitas que funcionam dentro da mentalidade de programação funcional. O F # também é um bom candidato se você possui um background .Net, mas é uma linguagem de paradigmas múltiplos, não estritamente uma linguagem de programação funcional.
Como tdammers observa nos comentários:
Na verdade, LISP, clojure e esquema também são multiparadigmas; Haskell, apesar de ser puro e preguiçoso por padrão, também permite programação imperativa em um contexto monádico e possui amplo suporte para processamento simultâneo. Todos eles possuem mecanismos que implementam grande parte da sabedoria reunida no mundo OOP - encapsulamento, herança, responsabilidade única, composição etc. Não se trata tanto de uma linguagem PERMITIR outros paradigmas; é sobre qual paradigma forma o ponto de partida de uma linguagem.
Que eu saiba, o Lisp e seus dialetos e Erlang são melhores candidatos do que o F # porque incentivam a programação funcional em relação a outros paradigmas, o que o tdammers afirma lindamente como o ponto de partida da linguagem . O F # abrange programação funcional, mas não o encoraja sobre seus outros paradigmas suportados, imperativos e oo programação.
Você não pode aprender todos os aspectos da programação funcional em C. Mas certamente você pode iniciar a programação de estilos funcionais com qualquer linguagem imperativa. Esses bits iniciais são: "Como manter as coisas puras durante a programação". E isso pode ser feito C também. Verifique esta postagem do blog para obter detalhes-
http://www.johndcook.com/blog/2011/07/24/get-started-functional-programming/
A programação funcional é sobre fechamentos e suas aplicações. A menos que alguém possa lhe mostrar uma biblioteca de fechamento de descida para C, esqueça de usar o C para aprender a programação funcional.
O principal conceito de programação funcional é a noção de fechamentos que, grosso modo, captura uma função juntamente com as ligações das variáveis. Além do uso generalizado de fechamentos, existem algumas outras características distintivas na programação funcional, como o uso de funções recursivas e valores imutáveis (ambos funcionam bem juntos). Esses traços são mais uma questão cultural do que qualquer outra coisa, e não há obstrução técnica para usá-los em praticamente qualquer idioma; é por isso que me concentro nos fechamentos na minha resposta: nem todo idioma permite criar fechamentos com facilidade.
Um uso típico de fechamentos é a implementação de mecanismos de privacidade. Por exemplo, o código Javascript - nos exemplos que escolhi o Javascript porque é uma linguagem funcional com a chamada "sintaxe do tipo C" e sua pergunta sugere que você está familiarizado com o C:
create_counter = function()
{
var x = 0;
var counter = function()
{
++x;
return x;
};
return counter;
}
Então com
a = create_counter();
b = create_counter();
nós temos duas funções a
e b
contando coleções disjuntas. O ponto do exemplo é que as variáveis x
são capturadas pelo fechamento que define o counter
fechamento e cada vez que um novo counter
fechamento is instantiated by the function, it gets its fresh own idea of what
x` é.
Outro uso típico de fechamentos é a definição de aplicações parciais de funções. Suponha que tenhamos um recurso de relatório semelhante à syslog
implementação de uma função
var log = function(priority, message) {
…
};
onde os argumentos priority
e message
se espera que sejam cordas, sendo o primeiro um dos "debug"
, "info"
e assim por diante. Podemos definir uma fábrica de logs como esta:
var logWithPriority = function(priority) {
return function(message) {
log(priority, message);
};
};
e use-o para definir versões especializadas do nosso recurso de log:
var debug = logWithPriority("debug");
var info = logWithPriority("info");
…
Isso é muito útil, porque em vez de escrever for
loops propensos a erros como este
for(i = 0; i < journal.length; ++i) {
log("info", journal[i]);
}
podemos escrever o limpador, mais curto e muito mais simples (não existe i
, isso é muito melhor):
journal.forEach(logWithPriority("info"));
Um terceiro campo importante de aplicação de fechamentos é a implementação de avaliação lenta - observe que o suporte a idiomas especiais pode proporcionar uma melhor implementação.
Uma função preguiçosa, em vez de executar uma computação direta, retorna um fechamento que pode ser chamado (ou "forçado" no jargão da preguiça) a executar a pergunta. A motivação para fazer isso é que ele separa a preparação de uma computação e a execução de uma computação. Um exemplo prático disso é a compilação de expressões regulares: se um programa compilar muitas expressões regulares no momento da inicialização, precisará de muito tempo para iniciar. Se, em vez disso, compilamos preguiçosamente as expressões regulares e as forçamos conforme necessário, nosso programa pode ser iniciado rapidamente. Obviamente, expressões regulares podem ser substituídas aqui por qualquer estrutura que exija um tempo considerável de inicialização.
Aqui está como implementar uma avaliação lenta com fechamentos. Considere a implementação clássica da função arrayMax retornando o máximo em uma matriz:
function arrayMax(array) {
return array.reduce(function(a, b) {
return Math.min(a, b);
};
}
A variante preguiçosa seria:
function arrayMax(array) {
var memo = null;
function actuallyCompute() {
if(memo === null) {
memo = array.reduce(function(a, b) {
return Math.min(a, b);
});
}
return memo;
}
return actuallyCompute;
}
O valor retornado é um fechamento que pode ser usado para calcular o valor ou recuperá-lo outra vez, se já tiver sido calculado.
Com esses três exemplos, devemos ter certeza de que os fechamentos e suas aplicações são o núcleo da programação funcional.
Aprender programação funcional significa aprender a programar com fechamentos. Como conseqüência, as linguagens que permitem a fácil manipulação de fechamentos, e principalmente a aplicação parcial de funções, devem ser consideradas ao procurar uma linguagem para estudar programação funcional. Por outro lado, idiomas onde os fechamentos não podem ser facilmente manipulados seriam más escolhas.
Eu acho que as ferramentas que você usa influenciam muito seu aprendizado. É quase impossível aprender conceitos de programação para os quais a linguagem de programação usada não fornece os meios para fazer uso. Claro, você sempre pode aprender algumas coisas, mas não pode aprender corretamente.
Mas isso é de qualquer maneira acadêmica, porque, como Martinho diz em seu comentário , mesmo se você poderia aprender programação funcional, você deve não tentar fazer isso, porque existem línguas onde este é muito mais fácil.
Você não deve aprender programação funcional em C, mas em uma linguagem funcional estrita (Haskell, Caml, Erlang, etc.).
Se você é novo no funcional, nunca o receberá com uma linguagem não funcional. Provavelmente, você se treinará para fazer o que considera programação funcional e aprender as coisas da maneira errada. E é sempre mais difícil "reaprender" as coisas da maneira certa do que aprendê-las da maneira certa no começo.
Enfim, acho que fazer funcional em C é um bom exercício para alguém que já conhece funcional. Porque essa pessoa aprenderá o que está acontecendo por trás do capô - o que o computador está realmente fazendo.