¿Cuáles son los beneficios de usar C # frente a F # o F # frente a C #?

Trabajo para una empresa de tecnología que hace más prototipos que el envío de productos. Me acaban de preguntar cuál es la diferencia entre C # y F #, por qué MS creó F # y qué escenarios sería mejor que C #.

He estado usando el lenguaje por un tiempo y me encanta, así que podría continuar sobre las excelentes características de F #, sin embargo, carezco de la experiencia en C # para decir por qué debemos usar una sobre la otra.

¿Cuáles son los beneficios de usar C # frente a F # o F # frente a C #?

Beneficios generales de la progtwigción funcional sobre los lenguajes imperativos:

Puede formular muchos problemas mucho más fácilmente, más cerca de su definición y más conciso en un lenguaje de progtwigción funcional como F # y su código es menos propenso a errores (inmutabilidad, sistema de tipo más potente, algoritmos recurrentes intuitivos). Puede codificar lo que quiere decir en lugar de lo que la computadora quiere que diga 😉 Encontrará muchas discusiones como esta cuando la busque en Google o incluso la busque en SO.

Ventajas especiales F #:

  • La progtwigción asincrónica es extremadamente fácil e intuitiva con async {} -expresiones : incluso con ParallelFX, el código C # correspondiente es mucho más grande

  • Integración muy fácil de comstackdores de comstackción e idiomas específicos de dominio

  • Extendiendo el idioma cuando lo necesite: LOP

  • Unidades de medida

  • Sintaxis más flexible

  • Soluciones a menudo más cortas y más elegantes

Eche un vistazo a este documento

Las ventajas de C # son que a menudo es más preciso que las aplicaciones “imperativas” (interfaz de usuario, algoritmos imperativos) que un lenguaje de progtwigción funcional, que el .NET-Framework que utiliza está diseñado imperativamente y está más extendido.

Además, puede tener F # y C # juntos en una solución, para que pueda combinar los beneficios de ambos idiomas y usarlos donde se necesiten.

Es como preguntar cuál es el beneficio de un martillo sobre un destornillador. En un nivel extremadamente alto, ambos hacen esencialmente lo mismo, pero a nivel de implementación es importante seleccionar la herramienta óptima para lo que estás tratando de lograr. Hay tareas que son difíciles y requieren mucho tiempo en c # pero fáciles en f #, como intentar golpear una uña con un destornillador. Puede hacerlo, seguro, simplemente no es ideal.

La manipulación de datos es un ejemplo que personalmente puedo señalar donde f # realmente brilla y c # puede ser potencialmente difícil de manejar. Por otro lado, diría (en términos generales) que la IU con estado complejo es más fácil en OO (c #) que funcional (f #). (Probablemente haya algunas personas que no estén de acuerdo con esto ya que es “genial” en este momento “probar” cuán fácil es hacer cualquier cosa en F #, pero lo resisto). Hay muchos otros.

  • F # tiene mejor rendimiento que C # en matemáticas
  • Podría usar proyectos F # en la misma solución con C # (y llamar de uno a otro)
  • F # es realmente bueno para la progtwigción algorítmica compleja, aplicaciones financieras y científicas
  • F # lógicamente es realmente bueno para la ejecución en paralelo (es más fácil hacer que el código F # se ejecute en núcleos paralelos, que C #)

Para responder a su pregunta tal como lo entiendo: ¿Por qué usar C #? (Usted dice que ya está vendido en F #.)

Antes que nada. No es solo “funcional versus OO”. Es “Funcional + OO versus OO”. Las características funcionales de C # son bastante rudimentarias. F # ‘s no lo son. Mientras tanto, F # hace casi todas las características OO de C #. En su mayor parte, F # termina como un superconjunto de la funcionalidad de C #.

Sin embargo, hay algunos casos en los que F # podría no ser la mejor opción:

  • Interop. Hay muchas bibliotecas que no van a ser demasiado cómodas desde F #. Tal vez exploten ciertas cosas C # OO que F # no hace lo mismo, o tal vez se basan en los componentes internos del comstackdor C #. Por ejemplo, Expresión. Si bien puede convertir fácilmente una cita F # en una Expresión, el resultado no siempre es exactamente lo que C # crearía. Ciertas bibliotecas tienen un problema con esto.

    • Sí, la interoperabilidad es una red bastante grande y puede provocar un poco de fricción con algunas bibliotecas.

    • Considero que la interoperabilidad también incluye si tiene una gran base de código existente. Puede que no tenga sentido comenzar a escribir partes en F #.

  • Herramientas de diseño. F # no tiene ninguno. No significa que no podría tener ninguno, pero ahora mismo no se puede actualizar una aplicación WinForms con código F # detrás. Incluso cuando es compatible, como en las páginas ASPX, actualmente no recibe IntelliSense. Por lo tanto, debe considerar cuidadosamente dónde estarán sus límites para el código generado. En un proyecto realmente pequeño que utiliza casi exclusivamente a varios diseñadores, puede que no valga la pena usar F # para el “pegamento” o lógica. En proyectos más grandes, esto podría convertirse en un problema menor.

    • Este no es un problema intrínseco A diferencia de la respuesta de Rex M, no veo nada intrínseco sobre C # o F # que los haga mejores para hacer una interfaz de usuario con muchos campos mutables. Tal vez se estaba refiriendo a la sobrecarga adicional de tener que escribir “mutable” y usar <- en lugar de =.

    • También depende de la biblioteca / diseñador utilizado. Nos encanta usar ASP.NET MVC con F # para todos los controladores, luego un proyecto web de C # para obtener los diseñadores de ASPX. Mezclamos el “código en línea” de ASPX real entre C # y F #, dependiendo de lo que necesitamos en esa página. (Tipos de IntelliSense frente a F #).

  • Otras herramientas. Quizás solo estén esperando C # y no sepan cómo lidiar con proyectos de F # o código comstackdo. Además, las bibliotecas de F # no se envían como parte de .NET, por lo que tienes un poco más para enviar.

  • ¿Pero el problema número uno? Gente. Si ninguno de sus desarrolladores quiere aprender F #, o peor, tiene dificultad para comprender ciertos aspectos, entonces probablemente esté brindando. (Aunque, de todos modos, diría que estás tostada en ese caso). Ah, y si la gerencia dice que no, eso podría ser un problema.

Escribí sobre esto hace un tiempo: ¿Por qué NO F #?

Usted está pidiendo una comparación entre un lenguaje de procedimiento y un lenguaje funcional, así que siento que su pregunta puede ser respondida aquí: ¿Cuál es la diferencia entre la progtwigción de procedimiento y la progtwigción funcional?

En cuanto a por qué MS creó F # la respuesta es simple: la creación de un lenguaje funcional con acceso a la biblioteca .Net simplemente expandió su base de mercado. Y viendo cómo la syntax es casi idéntica a OCaml, realmente no requirió mucho esfuerzo de su parte.

F # aún no es otro lenguaje de progtwigción si lo está comparando con C #, C ++, VB. C #, C, VB son todos los lenguajes de progtwigción imperativos o de procedimiento. F # es un lenguaje de progtwigción funcional.

Dos ventajas principales de los lenguajes de progtwigción funcionales (en comparación con los lenguajes imperativos) son 1. que no tienen efectos secundarios. Esto hace que el razonamiento matemático sobre las propiedades de su progtwig sea mucho más fácil. 2. que las funciones son ciudadanos de primera clase. Puede pasar funciones como parámetros a otras funciones tan fácilmente como a otros valores.

Ambos lenguajes de progtwigción imperativos y funcionales tienen sus usos. Aunque todavía no he hecho ningún trabajo serio en F #, actualmente estamos implementando un componente de progtwigción en uno de nuestros productos basado en C # y vamos a hacer un experimento codificando el mismo progtwigdor en F # para ver si la corrección del la implementación se puede validar más fácilmente que con el equivalente de C #.

F # es esencialmente el C ++ de los lenguajes de progtwigción funcionales. Conservaron casi todo, desde Objective Caml, incluidas las partes realmente estúpidas, y lo lanzaron encima del tiempo de ejecución de .NET de tal forma que trae todas las cosas malas de .NET también.

Por ejemplo, con Objective Caml obtienes un tipo de nulo, la opción . Con F # obtienes tres tipos de valores nulos, opción , Nullable y nulos de referencia. Esto significa que si tiene una opción, primero debe verificar si es “Ninguna”, entonces debe verificar si es “Some (null)”.

F # es como el antiguo clon de Java J #, solo un lenguaje bastardo solo para llamar la atención. A algunas personas les encantará, algunas de ellas incluso lo usarán, pero al final sigue siendo un lenguaje de 20 años añadido al CLR.

Uno de los aspectos de .NET que más me gusta son los generics. Incluso si escribe el código de procedimiento en F #, aún se beneficiará de la inferencia de tipo. Hace que escribir código genérico sea fácil.

En C #, se escribe un código concreto por defecto, y se debe agregar algo de trabajo adicional para escribir código genérico.

En F #, escribe código genérico de forma predeterminada. Después de pasar más de un año de progtwigción en F # y C #, encuentro que el código de la biblioteca que escribo en F # es más conciso y más genérico que el código que escribo en C #, y por lo tanto también es más reutilizable. Extraño muchas oportunidades para escribir código genérico en C #, probablemente porque estoy cegado por las anotaciones de tipo obligatorio.

Sin embargo, hay situaciones en las que es preferible usar C #, según el gusto y el estilo de progtwigción.

  • C # no impone un orden de statement entre tipos, y no es sensible al orden en que se comstackn los archivos.
  • C # tiene algunas conversiones implícitas que F # no puede permitirse debido a la inferencia de tipo.