Quais são os benefícios de usar C # vs F # ou F # vs C #? [fechadas]
93
Trabalho para uma empresa de tecnologia que faz mais protótipos do que remessa de produtos. Acabei de ser perguntado qual é a diferença entre C # e F #, por que o MS criou o F # e quais cenários ele seria melhor do que o C #.
Eu uso a linguagem há um tempo e adoro-a, então poderia facilmente continuar sobre os excelentes recursos do F #, mas não tenho experiência em C # para dizer por que devemos usar um em vez do outro.
Quais são os benefícios de usar C # vs F # ou F # vs C #?
Parece-me que já há muitas perguntas sobre o SO que respondem pelo menos parcialmente à sua pergunta. Você já tentou pesquisar usando "[F #] palavra-chave" em vez de "f # palavra-chave"? ("[f #] vantagens", por exemplo)
Benjol
Respostas:
86
Benefícios gerais da programação funcional em relação às linguagens imperativas:
Você pode formular muitos problemas com muito mais facilidade, mais perto de sua definição e mais conciso em uma linguagem de programação funcional como F # e seu código é menos sujeito a erros (imutabilidade, sistema de tipos mais poderoso, algoritmos recurivos intuitivos). Você pode codificar o que você quer dizer em vez do que o computador quer que você diga ;-) Você encontrará muitas discussões como esta quando você pesquisar no Google ou até mesmo no SO.
Vantagens F # especiais:
A programação assíncrona é extremamente fácil e intuitiva com async {}-expressions - Mesmo com ParallelFX, o código C # correspondente é muito maior
Integração muito fácil de compiladores de compiladores e linguagens específicas de domínio
As vantagens do C # são que ele costuma ser mais preciso para aplicativos "imperativos" (interface do usuário, algoritmos imperativos) do que uma linguagem de programação funcional, pois o .NET-Framework que usa é projetado de forma imperativa e mais difundido.
Além disso, você pode ter F # e C # juntos em uma solução, para que possa combinar os benefícios de ambas as linguagens e usá-los onde forem necessários.
Eles se combinam de maneiras muito estranhas. Por exemplo, você pode sobrecarregar o operador> em F #. Os desenvolvedores C # podem então usá-lo. No entanto, os desenvolvedores do F # não podem. Isso mesmo, F # pode emitir sobrecargas de operador que não pode consumir.
Jonathan Allen
O link "este documento" está quebrado ...
Eduardo Brites
36
É como perguntar qual é a vantagem de um martelo sobre uma chave de fenda. Em um nível extremamente alto, ambos fazem essencialmente a mesma coisa, mas no nível de implementação é importante selecionar a ferramenta ideal para o que você está tentando realizar. Existem tarefas que são difíceis e demoradas em C #, mas fáceis em F # - como tentar martelar um prego com uma chave de fenda. Você pode fazer isso, com certeza - não é o ideal.
A manipulação de dados é um exemplo que posso apontar pessoalmente onde f # realmente brilha e c # pode ser potencialmente difícil de controlar. Por outro lado, eu diria (de modo geral) a IU com estado complexa é mais fácil em OO (c #) do que funcional (f #). (Provavelmente haveria algumas pessoas que discordariam disso, já que é "legal" agora "provar" como é fácil fazer qualquer coisa em F #, mas eu mantenho isso). Existem inúmeros outros.
Se você só tem um martelo, tudo parece um prego. -Maslow
Charlie Salts
20
Não vou votar nisso porque não dá nenhuma especificação real, exceto para o exemplo de um dado. Eu sei que são ferramentas diferentes. Estou perguntando em quais empregos essas duas ferramentas são melhores e piores em comparação uma com a outra. Sei que um philips costuma ser a melhor ferramenta para o trabalho, embora um flathead menor funcione.
gradbot
3
Se ele não votar em você, eu vou. : P +1
Spencer Ruport
14
Se tudo o que você tem é um martelo, tudo se parece com um polegar.
Ed Power
6
Eu concordo com o gradbot, esta é uma boa resposta, portanto, nenhum downvote meu, no entanto, não chega aos detalhes das perguntas originais. Essa resposta é apenas uma explicação conceitual vaga, mas realmente perde o objetivo de responder à pergunta com exatidão.
@Joh: inlineé um exemplo óbvio de algo que pode fornecer melhorias massivas de desempenho no F # que o C # não consegue expressar.
JD
@Jon Harrop: Eu estava me referindo especificamente à entrada do blog de Rinat. Parece que o tempo a favor do F # que ele obteve foi devido ao código C # abaixo do ideal.
Joh
27
Para responder à sua pergunta da forma como a entendo: Por que usar C #? (Você diz que já vendeu o F #.)
Primeiramente. Não é apenas "funcional versus OO". É "Funcional + OO versus OO". Os recursos funcionais do C # são bem rudimentares. F # não são. Enquanto isso, o F # executa quase todos os recursos OO do C #. Na maior parte, F # termina como um superconjunto da funcionalidade do C #.
No entanto, existem alguns casos em que F # pode não ser a melhor escolha:
Interop. Existem muitas bibliotecas que simplesmente não ficarão muito confortáveis com o F #. Talvez eles explorem certas coisas do C # OO que o F # não faz da mesma forma, ou talvez eles dependam de componentes internos do compilador C #. Por exemplo, Expression. Embora você possa facilmente transformar uma citação F # em uma Expressão, o resultado nem sempre é exatamente o que C # criaria. Algumas bibliotecas têm problemas com isso.
Sim, a interoperabilidade é uma rede muito grande e pode resultar em um pouco de atrito com algumas bibliotecas.
Eu considero a interoperabilidade para incluir também se você tiver uma grande base de código existente. Pode não fazer sentido apenas começar a escrever partes em F #.
Ferramentas de design. F # não tem nenhum. Não significa que não poderia ter nenhum, mas agora você não pode agitar um aplicativo WinForms com F # codebehind. Mesmo onde há suporte, como em páginas ASPX, você atualmente não obtém o IntelliSense. Portanto, você precisa considerar cuidadosamente onde estarão seus limites para o código gerado. Em um projeto realmente pequeno que usa quase exclusivamente os vários designers, pode não valer a pena usar F # para a "cola" ou lógica. Em projetos maiores, isso pode se tornar um problema menor.
Este não é um problema intrínseco. Ao contrário da resposta do Rex M, não vejo nada intrínseco sobre C # ou F # que os torne melhores para fazer uma IU com muitos campos mutáveis. Talvez ele estivesse se referindo à sobrecarga extra de ter que escrever "mutável" e usar <- em vez de =.
Depende também da biblioteca / designer utilizada. Adoramos usar ASP.NET MVC com F # para todos os controladores e, em seguida, um projeto da web C # para obter os designers ASPX. Misturamos o "código embutido" ASPX real entre C # e F #, dependendo do que precisamos nessa página. (IntelliSense versus tipos F #.)
Outras ferramentas. Eles podem estar esperando apenas C # e não saberem como lidar com projetos F # ou código compilado. Além disso, as bibliotecas do F # não são fornecidas como parte do .NET, portanto, você tem um pouco mais para distribuir.
Mas o problema número um? Pessoas. Se nenhum de seus desenvolvedores deseja aprender F #, ou pior, tem grande dificuldade em compreender certos aspectos, então você provavelmente está frito. (Embora, eu diria que você está frito de qualquer maneira nesse caso.) Ah, e se a gerência disser não, isso pode ser um problema.
Quanto ao motivo pelo qual a MS criou o F #, a resposta é simples: Criar uma linguagem funcional com acesso à biblioteca .Net simplesmente expandiu sua base de mercado. E vendo como a sintaxe é quase idêntica ao OCaml, realmente não exigiu muito esforço da parte deles.
Embora eu ache que sua resposta geral está correta de que a verdadeira questão é sobre a comparação de paradigmas de programação e não de linguagens, acho que a resposta à questão que você está se referindo é um pouco superficial.
Jeroen Huinink
Sinta-se à vontade para sugerir outra pergunta se tiver outra melhor. Esse é o mais bem avaliado que encontrei em uma pesquisa no Google.
Spencer Ruport
1
Acho que ele estava tentando ser gentil sobre você soar como um idiota por dizer que F # não exigia muito esforço da parte da Micrsoft.
Matthew Whited
1 para comentário da base de mercado. Simples e tem alguma verdade.
gradbot
1
Eu não acredito naquele outro link respondendo à minha pergunta. C # oferece suporte a muitas construções funcionais em versões mais recentes.
gradbot
5
F # ainda não é outra linguagem de programação se você estiver comparando com C #, C ++, VB. C #, C, VB são linguagens de programação imperativas ou procedurais. F # é uma linguagem de programação funcional.
Dois principais benefícios das linguagens de programação funcional (em comparação com as linguagens imperativas) são 1. que elas não têm efeitos colaterais. Isso torna o raciocínio matemático sobre as propriedades do seu programa muito mais fácil. 2. que funções são cidadãos de primeira classe. Você pode passar funções como parâmetros para outras funções com a mesma facilidade com que faz outros valores.
As linguagens de programação imperativas e funcionais têm seus usos. Embora eu não tenha feito nenhum trabalho sério em F # ainda, estamos atualmente implementando um componente de programação em um de nossos produtos baseado em C # e faremos um experimento codificando o mesmo escalonador em F # para ver se a correção do implementação pode ser validada mais facilmente do que com o equivalente em C #.
-1. F # é uma linguagem multiparadigma (OO + FP). Apenas linguagens puramente funcionais não têm efeitos colaterais (como Haskell), mas F # não é puro.
Mauricio Scheffer,
5
F # é essencialmente o C ++ das linguagens de programação funcionais. Eles mantiveram quase tudo do Objective Caml, incluindo as partes realmente estúpidas, e o colocaram no topo do runtime do .NET de uma forma que trazia todas as coisas ruins do .NET também.
Por exemplo, com Objective Caml você obtém um tipo de nulo, a opção <T>. Com F # você obtém três tipos de nulos, opção <T>, Nullable <T> e nulos de referência. Isso significa que se você tiver uma opção, você precisa primeiro verificar se é "Nenhum", então você precisa verificar se é "Algum (nulo)".
F # é como o antigo clone Java J #, apenas uma linguagem bastardizada apenas para atrair a atenção. Algumas pessoas vão adorar, algumas até vão usá-lo, mas no fim das contas ainda é uma linguagem de 20 anos inserida no CLR.
+1, Esta pode ser a verdade dura, mas ainda estou muito feliz por poder usar uma linguagem funcional no VS com .NET
gradbot
1
Eu concordo que Nullable <T> deve fazer com que o compilador faça alguns apelidos mágicos para nós. Não tenho certeza de que tornar "Some null" equivalente a None sempre funcionaria - algum código de interoperabilidade pode depender disso. Mas referência nula? Como você vai contornar um grande buraco no .NET? Envolver cada tipo de referência em uma opção? Na prática, isso só parece ser um problema com determinados cenários de interoperabilidade.
MichaelGG
12
FWIW, estive programando profissionalmente em F # por vários anos (mais do que quase qualquer outra pessoa no mundo) e nunca vi esse problema ou o código Some nullem qualquer código F # em qualquer lugar. De todas as coisas que as pessoas possam queixar, isso tem que ser muuuito para baixo na lista ...
JD
1
Comparar F # com C ++ é um pouco rebuscado. Muitas partes do C ++ têm semântica indefinida ou pouco clara, o F # é simples e bem definido. A qualidade do tempo de execução .NET não pode ser comparada ao F #, já que qualquer linguagem .NET terá os mesmos problemas.
Joh,
1
Em mais de 2 anos de programação profissional em F #, como @Jon, nunca vi nenhum problema relacionado a 'Some null'. Por outro lado, tenho lucrado imensamente com os recursos do framework .Net.
Marc Sigrist,
5
Um dos aspectos do .NET que eu mais gosto são os genéricos. Mesmo se você escrever código procedural em F #, ainda se beneficiará da inferência de tipo. Facilita a escrita de código genérico.
Em C #, você escreve código concreto por padrão e tem que fazer algum trabalho extra para escrever código genérico.
Em F #, você escreve código genérico por padrão. Depois de passar mais de um ano programando em F # e C #, descobri que o código de biblioteca que escrevo em F # é mais conciso e genérico do que o código que escrevo em C # e, portanto, também é mais reutilizável. Perco muitas oportunidades de escrever código genérico em C #, provavelmente porque estou cego pelas anotações de tipo obrigatórias.
No entanto, existem situações em que o uso de C # é preferível, dependendo do gosto e estilo de programação de cada um.
C # não impõe uma ordem de declaração entre os tipos e não é sensível à ordem em que os arquivos são compilados.
C # tem algumas conversões implícitas que F # não pode pagar devido à inferência de tipo.
Respostas:
Benefícios gerais da programação funcional em relação às linguagens imperativas:
Você pode formular muitos problemas com muito mais facilidade, mais perto de sua definição e mais conciso em uma linguagem de programação funcional como F # e seu código é menos sujeito a erros (imutabilidade, sistema de tipos mais poderoso, algoritmos recurivos intuitivos). Você pode codificar o que você quer dizer em vez do que o computador quer que você diga ;-) Você encontrará muitas discussões como esta quando você pesquisar no Google ou até mesmo no SO.
Vantagens F # especiais:
A programação assíncrona é extremamente fácil e intuitiva com
async {}
-expressions - Mesmo com ParallelFX, o código C # correspondente é muito maiorIntegração muito fácil de compiladores de compiladores e linguagens específicas de domínio
Estendendo a linguagem conforme necessário: LOP
Unidades de medida
Sintaxe mais flexível
Muitas vezes, soluções mais curtas e elegantes
Dê uma olhada neste documento
As vantagens do C # são que ele costuma ser mais preciso para aplicativos "imperativos" (interface do usuário, algoritmos imperativos) do que uma linguagem de programação funcional, pois o .NET-Framework que usa é projetado de forma imperativa e mais difundido.
Além disso, você pode ter F # e C # juntos em uma solução, para que possa combinar os benefícios de ambas as linguagens e usá-los onde forem necessários.
fonte
É como perguntar qual é a vantagem de um martelo sobre uma chave de fenda. Em um nível extremamente alto, ambos fazem essencialmente a mesma coisa, mas no nível de implementação é importante selecionar a ferramenta ideal para o que você está tentando realizar. Existem tarefas que são difíceis e demoradas em C #, mas fáceis em F # - como tentar martelar um prego com uma chave de fenda. Você pode fazer isso, com certeza - não é o ideal.
A manipulação de dados é um exemplo que posso apontar pessoalmente onde f # realmente brilha e c # pode ser potencialmente difícil de controlar. Por outro lado, eu diria (de modo geral) a IU com estado complexa é mais fácil em OO (c #) do que funcional (f #). (Provavelmente haveria algumas pessoas que discordariam disso, já que é "legal" agora "provar" como é fácil fazer qualquer coisa em F #, mas eu mantenho isso). Existem inúmeros outros.
fonte
fonte
inline
é um exemplo óbvio de algo que pode fornecer melhorias massivas de desempenho no F # que o C # não consegue expressar.Para responder à sua pergunta da forma como a entendo: Por que usar C #? (Você diz que já vendeu o F #.)
Primeiramente. Não é apenas "funcional versus OO". É "Funcional + OO versus OO". Os recursos funcionais do C # são bem rudimentares. F # não são. Enquanto isso, o F # executa quase todos os recursos OO do C #. Na maior parte, F # termina como um superconjunto da funcionalidade do C #.
No entanto, existem alguns casos em que F # pode não ser a melhor escolha:
Interop. Existem muitas bibliotecas que simplesmente não ficarão muito confortáveis com o F #. Talvez eles explorem certas coisas do C # OO que o F # não faz da mesma forma, ou talvez eles dependam de componentes internos do compilador C #. Por exemplo, Expression. Embora você possa facilmente transformar uma citação F # em uma Expressão, o resultado nem sempre é exatamente o que C # criaria. Algumas bibliotecas têm problemas com isso.
Sim, a interoperabilidade é uma rede muito grande e pode resultar em um pouco de atrito com algumas bibliotecas.
Eu considero a interoperabilidade para incluir também se você tiver uma grande base de código existente. Pode não fazer sentido apenas começar a escrever partes em F #.
Ferramentas de design. F # não tem nenhum. Não significa que não poderia ter nenhum, mas agora você não pode agitar um aplicativo WinForms com F # codebehind. Mesmo onde há suporte, como em páginas ASPX, você atualmente não obtém o IntelliSense. Portanto, você precisa considerar cuidadosamente onde estarão seus limites para o código gerado. Em um projeto realmente pequeno que usa quase exclusivamente os vários designers, pode não valer a pena usar F # para a "cola" ou lógica. Em projetos maiores, isso pode se tornar um problema menor.
Este não é um problema intrínseco. Ao contrário da resposta do Rex M, não vejo nada intrínseco sobre C # ou F # que os torne melhores para fazer uma IU com muitos campos mutáveis. Talvez ele estivesse se referindo à sobrecarga extra de ter que escrever "mutável" e usar <- em vez de =.
Depende também da biblioteca / designer utilizada. Adoramos usar ASP.NET MVC com F # para todos os controladores e, em seguida, um projeto da web C # para obter os designers ASPX. Misturamos o "código embutido" ASPX real entre C # e F #, dependendo do que precisamos nessa página. (IntelliSense versus tipos F #.)
Outras ferramentas. Eles podem estar esperando apenas C # e não saberem como lidar com projetos F # ou código compilado. Além disso, as bibliotecas do F # não são fornecidas como parte do .NET, portanto, você tem um pouco mais para distribuir.
Mas o problema número um? Pessoas. Se nenhum de seus desenvolvedores deseja aprender F #, ou pior, tem grande dificuldade em compreender certos aspectos, então você provavelmente está frito. (Embora, eu diria que você está frito de qualquer maneira nesse caso.) Ah, e se a gerência disser não, isso pode ser um problema.
Eu escrevi sobre isso há um tempo: Por que NÃO F #?
fonte
Você está pedindo uma comparação entre uma linguagem procedural e uma linguagem funcional, então acho que sua pergunta pode ser respondida aqui: Qual é a diferença entre programação procedural e programação funcional?
Quanto ao motivo pelo qual a MS criou o F #, a resposta é simples: Criar uma linguagem funcional com acesso à biblioteca .Net simplesmente expandiu sua base de mercado. E vendo como a sintaxe é quase idêntica ao OCaml, realmente não exigiu muito esforço da parte deles.
fonte
F # ainda não é outra linguagem de programação se você estiver comparando com C #, C ++, VB. C #, C, VB são linguagens de programação imperativas ou procedurais. F # é uma linguagem de programação funcional.
Dois principais benefícios das linguagens de programação funcional (em comparação com as linguagens imperativas) são 1. que elas não têm efeitos colaterais. Isso torna o raciocínio matemático sobre as propriedades do seu programa muito mais fácil. 2. que funções são cidadãos de primeira classe. Você pode passar funções como parâmetros para outras funções com a mesma facilidade com que faz outros valores.
As linguagens de programação imperativas e funcionais têm seus usos. Embora eu não tenha feito nenhum trabalho sério em F # ainda, estamos atualmente implementando um componente de programação em um de nossos produtos baseado em C # e faremos um experimento codificando o mesmo escalonador em F # para ver se a correção do implementação pode ser validada mais facilmente do que com o equivalente em C #.
fonte
F # é essencialmente o C ++ das linguagens de programação funcionais. Eles mantiveram quase tudo do Objective Caml, incluindo as partes realmente estúpidas, e o colocaram no topo do runtime do .NET de uma forma que trazia todas as coisas ruins do .NET também.
Por exemplo, com Objective Caml você obtém um tipo de nulo, a opção <T>. Com F # você obtém três tipos de nulos, opção <T>, Nullable <T> e nulos de referência. Isso significa que se você tiver uma opção, você precisa primeiro verificar se é "Nenhum", então você precisa verificar se é "Algum (nulo)".
F # é como o antigo clone Java J #, apenas uma linguagem bastardizada apenas para atrair a atenção. Algumas pessoas vão adorar, algumas até vão usá-lo, mas no fim das contas ainda é uma linguagem de 20 anos inserida no CLR.
fonte
Some null
em qualquer código F # em qualquer lugar. De todas as coisas que as pessoas possam queixar, isso tem que ser muuuito para baixo na lista ...Um dos aspectos do .NET que eu mais gosto são os genéricos. Mesmo se você escrever código procedural em F #, ainda se beneficiará da inferência de tipo. Facilita a escrita de código genérico.
Em C #, você escreve código concreto por padrão e tem que fazer algum trabalho extra para escrever código genérico.
Em F #, você escreve código genérico por padrão. Depois de passar mais de um ano programando em F # e C #, descobri que o código de biblioteca que escrevo em F # é mais conciso e genérico do que o código que escrevo em C # e, portanto, também é mais reutilizável. Perco muitas oportunidades de escrever código genérico em C #, provavelmente porque estou cego pelas anotações de tipo obrigatórias.
No entanto, existem situações em que o uso de C # é preferível, dependendo do gosto e estilo de programação de cada um.
fonte