¿Qué lenguaje de programación genera menos errores difíciles de encontrar? [cerrado]

54

En su opinión, ¿qué lenguaje le permite al programador promedio generar funciones con la menor cantidad de errores difíciles de encontrar? Esta es, por supuesto, una pregunta muy amplia, y estoy interesado en respuestas y conocimientos muy amplios y generales.

Personalmente encuentro que paso muy poco tiempo buscando errores extraños en los programas Java y C #, mientras que el código C ++ tiene su propio conjunto de errores recurrentes, y Python / similar tiene su propio conjunto de errores comunes y tontos que serían detectados por el compilador en otros idiomas.

También me resulta difícil considerar los lenguajes funcionales a este respecto, porque nunca he visto un programa grande y complejo escrito en código completamente funcional. Su entrada por favor.

Editar: Aclaración completamente arbitraria de un error difícil de encontrar: tarda más de 15 minutos en reproducirse, o más de 1 hora en encontrar la causa y la solución.

Perdóneme si este es un duplicado, pero no encontré nada sobre este tema específico.

    
pregunta Magnus Wolffelt 01.12.2010 - 17:20

12 respuestas

59

Cuanto más poderoso sea el sistema de tipos del lenguaje, más errores se detectarán en el mismo momento de compilación.

La siguiente figura compara algunos de los lenguajes de programación bien conocidos en términos de potencia, simplicidad y seguridad de sus sistemas tipo. [ Fuente ]

*Factoringenlacapacidaddeusarconstruccionesinseguras.

  

C#serellenaenlafilainseguradebidoalapalabraclave"insegura" y la maquinaria de puntero asociada. Pero si quiere pensar en estos como un tipo de mecanismo de función externa en línea, siéntase libre de subir a C # hacia el cielo.

     

He marcado Haskell '98 como puro, pero GHC Haskell como no puro debido a la familia de funciones inseguras *. Si desactivas el método no seguro *, salta GHC Haskell como corresponde.

    
respondido por el missingfaktor 09.03.2015 - 20:13
20

En mi opinión, Haskell te ayuda a evitar algunas fuentes comunes de errores:

  • es puramente funcional: las funciones no pueden tener efectos secundarios (no intencionales) y esto hace que la programación multinúcleo sea más fácil y menos propensa a errores
  • está fuertemente tipado: no puedes, por ejemplo. mezcla accidentalmente los valores bool, char, int y float
  • está escrito de forma estática: muchos errores de programación se detectan en tiempo de compilación
  • null no es parte de las definiciones de tipo de valor: con esto evita el error de mil millones de dólares
  • hay muchas funciones de orden superior listas para usar que puede reutilizar en lugar de escribir sus propias implementaciones, posiblemente defectuosas,
  • tiene un recolector de basura: los errores de memoria casi se eliminan (excepto por "fugas de espacio" debido a su perezosa estrategia de evaluación)
respondido por el LennyProgrammers 17.07.2016 - 03:46
18

Tradicionalmente, los errores más difíciles de encontrar son las condiciones de carrera en aplicaciones de subprocesos múltiples como son

  • casi imposible de reproducir
  • puede ser muy sutil

Por lo tanto, necesita lenguajes que administren el paralelismo para usted de la manera más discreta posible. Estos aún no son de la corriente principal. Java hace algo, pero te deja con la parte difícil.

A mi entender, necesitas un lenguaje funcional ya que "sin efectos secundarios" es lo que en primer lugar hace que desaparezcan los dos puntos. He visto que se está trabajando para que Haskell se convierta en un lenguaje eficiente de múltiples subprocesos, y creo que Fortress está diseñado desde cero para ser un lenguaje paralelo eficiente.

Editar: En Java Executors maneja aún más partes difíciles. Debe hacer que las tareas individuales se ajusten a la interfaz Callable .

    
respondido por el 2 revsuser1249 15.06.2011 - 14:58
13

Ada está diseñado para que la mayor cantidad posible se capture en tiempo de compilación en lugar de tiempo de ejecución. Lo que esto significa es que a menudo se tarda aproximadamente 10 veces más en compilar un programa en Ada que el equivalente en Java, pero cuando compila puede estar mucho más seguro de que no se manifestarán clases enteras de errores cuando el programa se ejecute. correr.

    
respondido por el Mark Pim 01.12.2010 - 12:08
7

Primero, una definición: un error difícil de encontrar, como lo entiendo, es un error que puede reproducirse pero la causa es difícil de encontrar.

Probablemente, el aspecto más importante es lo que yo llamaría estrechez , es decir, a qué distancia puede escapar un error, qué tan grande es el alcance que un error puede influir. En lenguajes como C, un error, por ejemplo. un índice de matriz negativo o un puntero sin inicializar puede afectar literalmente todo en cualquier parte del programa, por lo que en el peor de los casos, debe verificar todo en cualquier parte para encontrar la fuente de su problema.

A este respecto, los buenos lenguajes son compatibles con los modificadores de acceso y los aplican de una manera que hace que sea difícil o imposible evitarlos. Los buenos lenguajes lo alientan a limitar el alcance de sus variables, en lugar de hacer que sea muy fácil tener variables globales (por ejemplo, "todo lo que no se declara explícitamente es una variable global con un tipo y valor predeterminados").

El segundo aspecto importante es concurrencia . Las condiciones de la raza son generalmente difíciles de reproducir y, por lo tanto, difíciles de encontrar. Los buenos idiomas ofrecen mecanismos de sincronización fáciles de usar, y sus librerías estándar son seguras para subprocesos cuando sea necesario.

Esto ya completa mi lista; otras cosas como la ayuda de escritura fuerte para detectar errores en tiempo de compilación, pero probablemente no sería difícil encontrarlos más tarde.

Considerando todo eso, diría que Java y C #, y muchos otros idiomas en el mundo de JVM y .net, son adecuados para evitar errores difíciles de encontrar.

    
respondido por el user281377 01.12.2010 - 12:55
7

Ya que Excel es el DSL más utilizado, usaré Excel. (excluyendo VBA por supuesto)

Se ajusta a la cuenta:

  • Siempre es fácil de reproducir (aquí hay una hoja de cálculo, no funciona)
  • Es bastante fácil encontrar el error, ya que es totalmente "funcional": comience con la celda que está mal y rastree todas sus dependencias.
respondido por el Scott Whitlock 02.12.2010 - 12:02
7

Esta es una pregunta difícil porque la mayoría de los errores no son culpa del lenguaje en sí, sino que son culpa de los desarrolladores que cometen errores en la forma en que usan el lenguaje.

Creo que hay varios aspectos de las características del lenguaje que afectan la probabilidad de errores:

  • Interactividad : los lenguajes dinámicos con REPL fomentan la interacción / experimentación con programas en ejecución y ciclos de código / prueba mucho más pequeños. Si cree que la iteración es una buena manera de descubrir soluciones simples y sencillas y detectar / eliminar errores, esto favorecerá los lenguajes interactivos.

  • Expresividad : si el código es más corto y tiene menos inconveniente / menor complejidad, es más fácil ver errores / errores lógicos.

  • Tipo de seguridad : cuanto más compilamos en el tiempo de compilación, más errores detectará el compilador, por lo que, en general, la seguridad de tipos es una buena cosa. Sin embargo, estos errores generalmente no son difíciles de encontrar , incluso en un lenguaje completamente dinámico, el tipo incorrecto en una estructura de datos generalmente causa un error de ejecución muy obvio, y TDD casi siempre detecta este tipo de errores .

  • Inmutabilidad : muchos errores graves se deben a interacciones complejas de estado mutable. Los idiomas que enfatizan la inmutabilidad (Haskell, Clojure, Erlang) tienen una enorme ventaja al evitar la mutabilidad.

  • Programación funcional : los enfoques funcionales para escribir código tienden a ser más "probablemente correctos" que el código orientado a objetos con secuencias complejas de efectos / interacciones. Mi experiencia es que FP ayuda a evitar errores complicados. Creo que hay una investigación académica en algún lugar que actualmente no puedo encontrar que respalde esto.

  • Soporte de concurrencia : los problemas de concurrencia son particularmente difíciles de detectar y depurar, por eso es tan importante. Cualquier cosa que requiera un bloqueo manual está condenada a fallar (y esto incluye casi cada enfoque orientado a objetos para la concurrencia). El mejor lenguaje que conozco a este respecto es Clojure: tiene un enfoque único para administrar la concurrencia que combina la memoria transaccional de software con estructuras de datos inmutables para obtener un marco de concurrencia novedoso, confiable y comperable. Consulte enlace para obtener más información

respondido por el mikera 05.06.2015 - 07:53
5

Cuanto menos poderoso es un idioma, menos opciones te da para disparar tu propio pie.

Los lenguajes de alto nivel como Java y C # producirán menos errores que los lenguajes de bajo nivel como C ++.

Habiendo dicho eso, creo que Java es más seguro que C #. Java está limitado artificialmente para que un programador promedio sin conocimientos avanzados pueda dominarlo y producir programas estables.

    
respondido por el 2 revsuser8685 01.12.2010 - 14:55
3
  

En tu opinión, qué idioma permite   el programador promedio para la salida   características con la menor cantidad de   errores difíciles de encontrar?

En mi opinión, Delphi. Al estar basado en Pascal, el lenguaje es lo suficientemente simple e intuitivo para el programador promedio (o incluso sin experiencia programadores) para recoger fácilmente, y su amplia herramienta y soporte de biblioteca hacen que la mayoría de los errores sean fáciles de encontrar.

  • Tipo fuerte y un compilador estricto que detecta muchos errores comunes.
  • Sintaxis intuitiva que no fomenta errores comunes. ("El último error del mundo," if (alert = RED) {LaunchNukes;} , no se compilará, por ejemplo.)
  • Un modelo de objeto bien diseñado que elimina muchos de los errores comunes de OOP de C ++.
  • Control de límites y control de rango integrado en el idioma, reduciendo drásticamente las posibilidades de seguridad problemas.
  • Probablemente el compilador más rápido conocido por el hombre, lo que aumenta su productividad y hace que sea más difícil perder su tren de pensamiento mientras espera en una compilación.
  • El depurador El depurador de Visual Studio quiere ser como cuando crezca.
  • El seguimiento de fugas está integrado directamente en el administrador de memoria, lo que hace que la búsqueda y la solución de fugas de memoria sean triviales.
  • Una biblioteca estándar grande y madura que proporciona formas precompiladas y probadas previamente para realizar tareas comunes sin tener que crear sus propias implementaciones, posiblemente con errores.
  • Se envía con herramientas útiles, como un potente sistema de registro y un generador de perfiles, para facilitar el seguimiento de los problemas.
  • Compatibilidad con la comunidad sólida para problemas comunes que no están en la biblioteca estándar, incluida una potente biblioteca de concurrencia de terceros .
respondido por el Mason Wheeler 01.12.2010 - 14:49
2

Una cosa a tener en cuenta es el tiempo de respuesta.

Durante los últimos cinco años más o menos, he desarrollado principalmente aplicaciones web en java (JSF, Seam, etc.). Recientemente obtuve un nuevo trabajo y estamos usando Perl (con Catalyst y Moose).

Soy mucho más productivo en Perl que en Java.

No es necesario compilar y desplegar (en caliente), es una de las razones. También encuentro que escribir casos de uso es más fácil, ya que se puede hacer de una manera más iterativa. Y los marcos en Java parecen ser complejos innecesarios, al menos para los proyectos en los que he participado.

Supongo que la cantidad de errores en mi código Perl es más o menos la misma que la cantidad de errores en mi código Java, incluso podría ser mayor. Pero me resulta más fácil y rápido encontrar y corregir estos errores.

    
respondido por el slu 02.12.2010 - 10:12
1

Tal vez dar una idea de la cantidad de herramientas disponibles para el análisis de código estático y dinámico para cada lenguaje de programación. Cuantas más herramientas para un idioma, es más probable que el lenguaje sea muy popular entre los usuarios o muy popular para generar errores difíciles de encontrar. Pero no puedo hacer que Google me señale ningún estudio realizado sobre este tema. También se debe tener en cuenta que algunos lenguajes como C se pueden usar para solucionar los errores de hardware subyacentes, así como para evitar el desgaste del hardware a medida que envejece.

    
respondido por el vpit3833 01.12.2010 - 12:41
1

En lugar de hablar sobre idiomas, sobre hablar de características de idioma

  • java te obliga a pensar en las excepciones (lanzamientos ...) y debes publicar o manejar estas excepciones. ¿Eso realmente me impide olvidar las situaciones de error o estoy usando más excepciones derivadas de SystemException que no necesitan este manejo?
  • ¿qué pasa con el "diseño por contrato" (http://en.wikipedia.org/wiki/Design_by_contract) que me obliga a pensar en las condiciones previas y posteriores? He leído que ahora es posible con c # -4.0.
respondido por el k3b 03.12.2010 - 12:25

Lea otras preguntas en las etiquetas