¿Cuáles son las cinco cosas que odias de tu idioma favorito? [cerrado]

403

Últimamente ha habido un grupo de Perl-hate en Stack Overflow, así que pensé en llevar mi pregunta " Cinco cosas que odias de tu idioma favorito " a Stack Overflow. Toma tu idioma favorito y dime cinco cosas que odias de él. Esas pueden ser cosas que simplemente te molestan, defectos de diseño admitidos, problemas de rendimiento reconocidos o cualquier otra categoría. Solo tienes que odiarlo, y tiene que ser tu idioma favorito.

No lo compares con otro idioma, y ​​no hables de idiomas que ya odias. No hables de las cosas que te gustan en tu idioma favorito. Solo quiero escuchar las cosas que odias pero que toleras para que puedas usar todas las otras cosas, y quiero escuchar sobre el lenguaje que deseas que otras personas usen.

Pregunto esto cada vez que alguien intenta presionarme su idioma favorito, y algunas veces como una pregunta de entrevista. Si alguien no puede encontrar cinco cosas que odiar de su herramienta favorita, no lo sabe lo suficiente como para abogar por ella o obtener los grandes dólares usándola. No lo ha usado en suficientes situaciones diferentes para explorarlo completamente. Lo defiende como una cultura o religión, lo que significa que si no elijo su tecnología favorita, me equivoco.

No me importa mucho qué idioma usas. ¿No quieres usar un idioma en particular? Entonces no lo hagas. ¿Pasas por la debida diligencia para tomar una decisión informada y aún no la usas? Multa. A veces, la respuesta correcta es "Tienes un equipo de programación fuerte con buenas prácticas y mucha experiencia en Bar. Cambiar a Foo sería estúpido".


Esta es una buena pregunta para las revisiones de código también. Las personas que realmente conocen una base de código tendrán todo tipo de sugerencias, y aquellos que no la conocen tan bien tienen quejas no específicas. Pregunto cosas como "Si pudieras comenzar de nuevo en este proyecto, ¿qué harías de manera diferente?" En esta tierra de fantasía, los usuarios y los programadores pueden quejarse de todo lo que no les gusta. "Quiero una mejor interfaz", "Quiero separar el modelo de la vista", "Usaría este módulo en lugar de este otro", "Cambiaría el nombre de este conjunto de métodos", o lo que sea que realmente no No me gusta la situación actual. Así es como obtengo una idea de cuánto sabe un desarrollador en particular sobre la base de código. También es una pista sobre cuánto del programador '

El odio no es la única dimensión de averiguar cuánto sabe la gente, pero he descubierto que es bastante buena. Las cosas que odian también me dan una idea de lo bien que piensan sobre el tema.

brian d foy
fuente
11
Este es un giro realmente agradable en la vieja pregunta de "su idioma favorito". Buena justificacion.
Tom Leys
14
Me parece interesante que a pesar de que SO tenga una gran audiencia de .NET, en el momento de escribir este artículo hay 24 respuestas, solo una de las cuales (la mía) es sobre .NET o un lenguaje .NET. No tengo idea de lo que esto dice sobre SO o .NET, pero es interesante ...
Jon Skeet
22
Los primeros 15 años de programación con C / C ++, odié (en orden alfabético): 1. Punteros 2. Punteros 3. Punteros 4. Punteros 5. Punteros
ileon
44
Me pregunto cuántos comentarios hicieron las personas acerca de odiar su idioma de elección porque no entendieron cómo programar en su idioma de elección ...
Kris
3
Esta es una pregunta fantástica. Si se pregunta cómo es un idioma, leer 3 respuestas diferentes al respecto en esta página sería fácilmente la mejor información útil para pasar el tiempo que pueda encontrar. También es una excelente manera de medir los niveles de experiencia (y humildad) de un programador si ya conoce el idioma.
j_random_hacker 01 de

Respuestas:

182

Cinco cosas que odio de Java:

  • No hay funciones de primera clase.
  • Sin inferencia de tipos.
  • Falta de valores predeterminados sanos en, por ejemplo, gráficos
  • NullPointerException no contiene más información sobre lo que es nulo.
  • La proliferación de frameworks / interfaces de proveedores de servicios / clases de fábrica / sistemas de inyección de dependencias "configurables" sin sentido. La configurabilidad casi nunca se usa, DRY se viola atrozmente y el código se cuadruplica en tamaño y se reduce a la mitad en legibilidad.

Lo sé, debería revisar Scala.

Zarkonnen
fuente
77
@both: el NPE se muestra en la primera línea del trance de la pila. Contiene (la mayoría de las veces) clase, nombre de archivo java y número de línea como: "en your.faulty.code.Instance (Intance.java:1234)" Luego simplemente abra ese archivo, vaya a esa línea y allí es una variable que no tiene nada asignado.
OscarRyz
35
@Oscar Reyes - Er, eso lo sabemos. Pero puede haber múltiples variables en esa línea, y el mensaje de excepción no me dice cuál es nulo.
Zarkonnen
10
Scala también tiene sus verrugas. Sin embargo, es magníficamente mejor que Java.
wheaties
10
+1 para la proliferación de marcos, etc.
Erich Kitzmueller
66
@Valentin, solo imagina la diversión de la NullPointerException en un gigantesco archivo de registro de una ejecución nocturna y necesitas descubrir qué sucedió ... La depuración no es una opción.
Thorbjørn Ravn Andersen
216

Wow, me sorprende que SQL aún no haya llegado hasta aquí. Supongo que eso significa que a nadie le encanta :)

  • Sintaxis inconsistente entre implementaciones
  • Las diferencias sutiles de código pueden tener ramificaciones de rendimiento masivas por razones aparentemente oscuras
  • Mal soporte para la manipulación de texto
  • Costo de entrada fácil pero curva de aprendizaje empinada para dominar el idioma
  • Estandarización mínima en toda la comunidad para mejores prácticas, esto incluye estilo de sintaxis.

... Y algunas razones adicionales para odiarlo, sin cargo adicional

  • la cláusula WHERE es la última, lo que facilita la ejecución prematura de una ACTUALIZACIÓN o ELIMINACIÓN, destruyendo toda la tabla. En cambio, el DÓNDE debería ir a algún lugar por adelantado.
  • Es difícil implementar la división relacional.
  • Puedo establecer un valor en NULL, pero no puedo probar la igualdad con NULL. Puedo verificar IS NULL, pero eso solo complica el código, innecesariamente, en mi opinión.
  • ¿Por qué necesitamos respetar completamente la fórmula para una columna GRUPADA, en lugar de establecer un alias en la columna y luego GRUPO POR el alias (o índice de columna como con SORT)?
Jeremiah Peschka
fuente
77
Tal vez nadie pueda aprender a amarlo hasta que dejen de pensarlo como un idioma. :)
Alan Moore
44
+1 por todo. Y sin embargo, la gente se pregunta por qué soportaré los dolores de cabeza de ORM ...
James Schek
2
@ Alan M ... ¿no es eso lo que representa la L? :)
Kev
29
No puedo entender por qué la sintaxis de INSERT es tan diferente de ACTUALIZAR. Y MERGE es incomprensible.
LaJmOn
3
La necesidad de IS NULL debe ser clara, si considera que NULL es un tercer resultado posible, justo después de TRUE y FALSE. Dado que su significado es "desconocido", no se puede saber si algo desconocido coincide con otra cosa desconocida también. Otro ejemplo: si NULL es igual a NULL, esto significaría que todo el concepto de hacer JOIN sería imposible, ya que cualquier valor NULL podría coincidir con otro valor NULL. Si comprende esto (lo que también se llama lógica ternaria), entonces podría entender la razón por la que se introduce el operador "IS" para realizar pruebas contra NULL.
Alex
159

JavaScript :

  1. Todas las cosas más geniales son increíblemente complejas, pero luego, toda la genialidad también está envuelta en una cantidad tan pequeña de código que te sientes estúpido por luchar para seguirlo.

  2. '+' es una elección absurda de operador para la concatenación en un lenguaje de tipo débil. ¿Estaban tratando de asustar a los novatos?

  3. Es un campo minado de compatibilidad entre navegadores (no importa si está activado o no)

  4. Por lo general, no es de confianza: está asociado con la escoria, como bloquear el botón Atrás, ventanas emergentes que nunca mueren, etc.

  5. Es casi imposible depurar porque solo hay unos pocos mensajes de error diferentes y unos pocos tipos diferentes (Número, Cadena, Objeto, etc.)

Si no fuera por jQuery, probablemente todavía lo odiaría tanto como solía hacerlo :)

jTresidder
fuente
15
Estoy de acuerdo con mausch. El ECMAscript en sí mismo es un lenguaje hermoso y poderoso. Son los molestos navegadores (: tos: IE) los que confunden su nombre.
TJ L
32
@Mausch: ¿dónde vive javascript en la gran mayoría de los casos? Estás diciendo que el equivalente a "los automóviles no contribuyen al calentamiento global, lo que lo hace es conducir automóviles", es cierto, por supuesto, pero se pierde el punto, ¿qué más haces con un automóvil?
jTresidder
20
@Chris: Sí, "+" es un buen operador para la concatenación en un lenguaje fuertemente tipado (como Python). En un lenguaje débilmente escrito (como Javascript o C) es terrible; decide (en silencio) que 'sum:' + 2 + 3 no es 'sum: 5' sino 'sum: 23'. Alguien con más experiencia en Javascript puede dar mejores ejemplos.
ShreevatsaR
55
Sí, C se escribe débilmente, en comparación con, por ejemplo, Python (por ejemplo, puede asignar números enteros a chars, convertir cualquier cosa a través de punteros nulos *, etc.) Se escribe de forma estática en lugar de escribir dinámicamente , y también requiere una escritura explícita en lugar de inferencia de tipos, pero no están relacionadas con la escritura débil de v / s fuerte. [Ejemplos aleatorios: Python tiene una tipificación fuerte dinámica implícita, Haskell tiene una tipificación fuerte estática (opcionalmente explícita), Java tiene una tipificación fuerte explícita (en su mayoría estática), C tiene una tipificación estática explícita (relativamente débil).] "Fuertemente escrita" y "débilmente escrita "en realidad no están bien definidos.
ShreevatsaR
55
@ShreevatsaR El ejemplo clásico es: '3'+'2'='32', '3'-'2'=1.
Thomas Ahle
148

PHP:

1) Me obliga a hacer variables innecesarias:

$parts = explode('|', $string);
$first = $parts[0];

2) Una implementación de lambdas tan lamentable es más o menos equivalente a usar eval()y tan horriblemente mal que nunca la he usado (ver http://www.php.net/create_function ).

3) Un sistema try / catch que solo puede detectar alrededor del 80% de los errores que pueden ocurrir.

4) El soporte de Regex es tan aburrido como el soporte de lambda porque tiene que estar escrito dentro de cadenas regulares, lo que hace que una de las herramientas de programación más difíciles de aprender sea tres veces más difícil. ¿Y se supone que PHP es un lenguaje "fácil"?!?!?

5) No hay forma de extraer cosas de $ _POST de manera segura sin escribirlo dos veces o crear su propia función, o usar el operador '@':

$x = isset($_POST['foo']['bar']) ? $_POST['foo']['bar'] : null;

6) Respuesta adicional: '@'. Si no puede molestarse en escribir su código correctamente, simplemente agregue '@', y lástima que cualquiera que deba depurar su código más tarde.

demasiado php
fuente
44
¿Qué pasa con la lista ($ first) = explotar ('|', $ string); ?
mlarsen
44
Idealmente, me gustaría usar alguna_función (explotar ('|', $ cadena) [0]);
demasiado php
8
¿Qué extraño alcance variable? Es una buena idea tener todo lo local y obligarlo a declarar cuándo desea usar un global, ya que evita que los novatos realicen funciones que solo usan globales, en lugar de usar argumentos y devolver valores como deberían hacerlo.
scragar
24
te olvidaste de funciones con el fin de cambiar el parámetro de forma aleatoria
dusoft
39
Te olvidaste de verbNoun, verb_noun, noun_verb, nounverb, verbnoun, nounVerb, etc> _>
Warty
135

C ++

  • Demasiado fácil para corromper la memoria al azar y crear errores casi imposibles de encontrar (aunque, Valgrind hace un largo camino para solucionar esto).
  • Mensajes de error de plantilla.
  • Cuando se usan plantillas, es fácil terminar teniendo que incluir todo en un archivo y luego obtener tiempos de compilación estúpidos.
  • La biblioteca estándar es una broma en la era moderna (¿todavía no hay hilos o red por defecto?)
  • Un montón de pequeños fragmentos desagradables de C que se asoman (en particular, todas las conversiones entre short / int / unsigned / etc.)
Chris Jefferson
fuente
13
Estoy de acuerdo con el STL, pero diré que lo que hay es bastante bueno.
Bernard
22
Unicode. Respeto la simplicidad de Ascii, pero por el amor de Dios, ahora estamos en el siglo XXI.
wilhelmtell
29
@Kieveli const correctness es en realidad una de las cosas que más extraño cuando programo en otros idiomas. particularmente los de tipo dinámico. raii es una gran característica que a menudo extraño también.
wilhelmtell
66
La mayoría de los problemas de C ++ provienen de ser un estándar ISO y estar bloqueados durante 10 años.
graham.reeds
77
+1 "Mensajes de error de plantilla".
João Portela
129

C # / .NET:

  • Las clases deben estar selladas por defecto
  • No debe haber ninguna lockdeclaración; en su lugar, debe tener objetos de bloqueo específicos, y debe haber métodos como los Acquireque devuelven tokens de bloqueo desechables. Corolario: no debería haber un monitor para cada objeto.
  • GetHashCode()y Equals()no debería estar adentro System.Object, no todo es adecuado para el hash. En su lugar, tener una IdentityComparer, que hace lo mismo, y mantener a los IComparer<T>, IComparable<T>, IEqualityComparer<T>y IEquatable<T>las interfaces personalizados para las comparaciones.
  • Mal soporte para la inmutabilidad
  • Mala forma de descubrir métodos de extensión: debería ser una decisión mucho más consciente que el hecho de que estoy usando un espacio de nombres.

Esos estaban fuera de mi cabeza, pregúntame mañana y obtendré 5 diferentes :)

Jon Skeet
fuente
22
Sellado por defecto: la herencia debe estar diseñada en una clase (lo que lleva tiempo y limita las opciones futuras) o prohibida. hashCode / equals: también apesta en Java. Algún día escribiré una larga publicación de blog al respecto. Lea Java efectivo para obtener detalles sobre por qué es igual a igual es difícil en las cadenas de herencia.
Jon Skeet
88
Sellar por defecto significa que has pensado en todas las posibles razones que alguien puede querer heredar de tu clase y no crees que ninguna de ellas tenga sentido. Lo siento, pero ninguno de nosotros es tan inteligente.
Ed S.
69
En ese caso, no soy lo suficientemente inteligente como para que pueda derivar de mi código: porque no puedo predecir qué cambios futuros podría hacer que podrían romper su código. Ese es un problema muy significativo, OMI. Sellar el código es más restrictivo, pero conduce a una mayor libertad de implementación y robustez.
Jon Skeet el
11
No puedo creer que nadie haya mencionado la sintaxis del "caso goto", ¡odio esa!
Aistina
20
Es una buena cosa que Jon Skeet no haya diseñado C #, o mi lista se vería como "1. las clases están selladas de forma predeterminada; 2. el bloqueo es demasiado complicado; 3. ¡la mayoría de los objetos no son hashaable"!
Gabe
113

C

  • manipulación de cuerdas.

Tener que lidiar manualmente con los buffers de cadena es un dolor propenso a errores. Debido a que mucha computación realmente se mueve y modifica las cadenas (las computadoras no se usan tanto para cosas de gran número de números como la gente pensaba que volverían hace mucho tiempo), es realmente bueno poder usar lenguajes administrados o la cadena de C ++ objetos para tratar con estos. Cuando tengo que hacerlo en C recta, se siente como nadar en arenas movedizas.

Michael Burr
fuente
50
Convenido. La manipulación de cuerdas es el elemento 1 a 5 de las cosas que odio de C.
BoltBait
1
Simplemente use la biblioteca segura de cadenas de DJB o algo así. La manipulación de XML es difícil en la mayoría de los lenguajes, y muchos programas hacen manipulación de XML, pero no ve muchas publicaciones que digan "Perl está totalmente roto porque no admite nodos DOM como un tipo de datos primitivo". Ellos usan una biblioteca.
Steve Jessop
55
La manipulación de la cadena C apesta, pero en lo que respecta a los problemas de lenguaje, no es lo peor.
Chris Lutz
3
strcat para concatenar, pero espera ... ¿el destino tiene suficiente espacio ... ok, debe insertar la instrucción if para verificar ... pero espera, ¿y si mi cadena está en el montón? Ok, debe mantener una variable en torno a mantener un registro de tamaño ... Y esto puede seguir y seguir y seguir ...
blwy10
44
Necesitamos un hilo para cinco cosas que no odiamos de C ...
L̲̳o̲̳̳n̲̳̳g̲̳̳p̲̳o̲̳̳k̲̳̳e̲̳̳
94

¿Qué tal cinco cosas que odio de las listas de "Cosas que odio de algún idioma"? :RE

5- Pintar un rojo anaranjado no lo convierte en una manzana.

Cuando se diseña un lenguaje, los diseñadores suelen tener en cuenta para qué es útil. Usarlo para algo completamente diferente puede funcionar, pero quejarse cuando no es simplemente tonto. Toma Python. Estoy seguro de que alguien lo ha hecho o alguien algún día hará una utilidad para crear exe's a partir del código Python. ¿Por qué demonios querrías hacer eso? Sería genial, no me malinterpreten, pero no sirve de nada. ¡Así que deja de quejarte!

Un proyecto bien diseñado probablemente contenga código de varios idiomas. Eso no quiere decir que no pueda completar un proyecto con un solo idioma. Algunos proyectos pueden estar dentro de las capacidades de cualquier idioma que esté utilizando.

4- ¿Estás parado sobre patas de madera?

La plataforma puede ser una gran influencia de lo que puede hacer el lenguaje. Con los recolectores de basura de hoy en día, o incluso los intentos pascales tempranos de "recolección de basura", pueden ayudar en el desvanecimiento de la memoria (¿quizás malloc más ram?). Las computadoras son más rápidas y, por supuesto, esperamos más de nuestros idiomas. Y francamente, probablemente deberíamos. Sin embargo, hay un gran precio a pagar por la conveniencia del compilador para crear tablas o cadenas hash o una variedad de otros conceptos. Es posible que estas cosas no se hereden a la plataforma en la que se usan. Decir que son fáciles de incluir en un idioma solo me dice que es posible que no tengas una pierna para pararte.

3- ¿De quién es la culpa?

Loco. Ya sabes. Me encantan los bichos. ¿Por qué amo los insectos? Porque significa que puedo mantener mi trabajo. Sin errores, habría muchas pizzerías cerradas. Sin embargo, los usuarios odian los errores. Pero aquí hay un poco de agua fría. Cada error es culpa de los programadores. No es el idioma. Un lenguaje con una sintaxis tan estricta que reduciría significativamente la cantidad de errores que se podrían generar sería un lenguaje completamente inútil. Sus habilidades probablemente podrían contarse con una mano. ¿Quieres flexibilidad o poder? Tienes bichos. ¿Por qué? Porque no eres perfecto y cometes errores. Tome un ejemplo realmente identificable en C:

int a[10];
for (int idx = 0; idx < 15; idx++) a[idx] = 10;

Todos sabemos lo que va a hacer. Sin embargo, lo que quizás algunos de nosotros no nos demos cuenta es ... que la funcionalidad puede ser muy beneficiosa. Dependiendo de lo que estés haciendo. Los desbordamientos de búfer son el costo de esa funcionalidad. Ese código de arriba. Si realmente lo lancé al público. Eso es otra vez ... dilo conmigo ... "Mi culpa". No C's por permitirme hacerlo.

2- ¿No deberíamos poner eso en la papelera de reciclaje?

Es muy fácil señalar una característica en un idioma que no entendemos porque no la usamos a menudo y la llamamos estúpida. Quejarse de que está allí, etc. Goto siempre me entretiene. La gente siempre se queja de que goto está en un idioma. Sin embargo, apuesto a que su último programa incluyó un tipo de goto. Si alguna vez has usado un descanso o una continuación, has usado un goto. Eso es lo que es. De acuerdo, es un goto "seguro", pero es lo que es. Los Goto tienen sus usos. Si se usan gotos "implícitos" como continue o break o gotos explícitos (usando la palabra clave "goto" para cualquier idioma). No es que los desarrolladores de idiomas sean perfectos, pero generalmente ... si la funcionalidad ha existido desde el principio de los tiempos (para ese idioma). Probablemente ese aspecto es una cualidad definitoria de ese lenguaje. Lo que significa ... es s está siendo utilizado y probablemente no esté dando vueltas debido a la compatibilidad con versiones anteriores. Se está utilizando hoy. Como en hace 5 minutos. Y usado correctamente. Bueno ... podría decirse que alguien también lo está usando incorrectamente, pero eso se relaciona con el # 3 en mi lista.

1.- Todo es un objeto.

Ok .. este es realmente un subconjunto de # 2. Pero esta es, con mucho, la queja más molesta que veo en las listas de odio. No todo es un objeto. Hay muchos conceptos que no pertenecen o necesitan ser objetos. Poner cosas donde no pertenecen es simplemente feo y puede disminuir la eficiencia de un programa. Por supuesto. Quizás no mucho dependiendo del idioma. Esto también se relaciona con el n. ° 5. Esto significa ... si. Global está bien. Las funciones de los métodos estáticos están bien. Combinar la programación OO con funciones globales está bien. Ahora ... eso no significa que todos deberíamos salir y "liberar" nuestro código de sus modelos de objetos tampoco. Al diseñar una sección de código o un proyecto completo, lo que sucede detrás de escena deberíaser considerado al armarlo No solo dónde vive ese concepto y muchos otros factores. ¿Por qué incluir funciones globales dentro de clases o conceptos de espacio de nombres si no sirve para nada? Tomar variables miembro estáticas. Eso me divierte mucho porque ... bueno ... Dependiendo del idioma y la implementación, por supuesto, pero en general, usted acaba de declarar un global. Sí, hay algunas razones para envolver estos conceptos que no son OO en contenedores OO. Uno, por supuesto, es el código autodocumentado. Eso puede tener sentido. Entonces ... como digo. No salgas y "liberes" tu código. Pero cualquier buen lenguaje moderno tendrá un concepto global fuera de su modelado OO. Sí, quiero señalar específicamente que un lenguaje de programación OO sin un concepto global probablemente tenga un serio defecto de diseño. De nuevo, aunque ... depende de la intención y el diseño del lenguaje, por lo que no estoy tratando de elegir ningún idioma específico y hay demasiados para analizar aquí. De todos modos, considere dónde debería vivir el código y ser el más efectivo. Agregar un montón de destellos a algo que no agrega funcionalidad o soporte simplemente desgasta el teclado más rápido. A nadie le sirve de nada. Bueno ... a menos que te gusten los puntos brownie de la persona que probablemente te enseñó incorrectamente que todo es un objeto.

En resumen, la programación no es simplemente tocar el teclado sin pensar. Hay muchas consideraciones de diseño para cualquier proyecto. Sé que es un cliché, pero hay que mirarlo desde todos los ángulos. Incluso con los idiomas de hoy en día de tipo seguro. No solo saca el código y espera que funcione bien. Claro ... puede funcionar, pero puede que no sea la forma correcta de hacerlo. En general, elija el idioma y el formato más adecuados para el trabajo específico y el entorno. Pero ningún lenguaje quita el pensamiento detrás de él. Si no estás pensando ... solo estás escribiendo.

desconocido
fuente
19
Los idiomas no son perfectos, y si haces una lista de cosas que odias de un idioma, puedes obtener algunos comentarios e ideas interesantes. Primero, permite que otros te den soluciones que no sabías que existían (mira las publicaciones, verás que se aprendieron algunas cosas). En segundo lugar, constituye comentarios de los usuarios para los desarrolladores del lenguaje (¿no le interesaría si a sus usuarios se les ocurriera una lista de las 5 cosas que más odian de su software?), Y tercero, es un poco interesante reflexionar sobre los defectos de tus herramientas
Sylverdrag
44
Si lo ve en ese nivel, no solo romper y continuar son gotos, sino que los bucles son gotos (salte el comienzo del bucle si se cumple la condición), si es goto (si la condición no se cumple salte sobre el bloque, las llamadas a funciones are goto (salta al comienzo de la función y luego salta hacia atrás), ...
helio
17
¿Crear archivos ejecutables a partir del código fuente "no tiene uso"? ¿Qué?
desvío
44
Perl podría crear un ejecutable a partir de un archivo Perl desde finales de los años 80. Una cosa para distribuir es útil. No es necesario a) instalar Perl, b) instalar componentes del programa, c) tal vez escribir un script para establecer rutas y ejecutarlo todo ... Sí, realmente inútil.
xcramps
1
Pero, si no puede crear archivos .exe desde la fuente, los usuarios de Windows no podrán ejecutarlo. ;)
Evan Plaice
88

Cinco cosas que odio de Java (que, actualmente, es mi lenguaje favorito) sin ningún orden en particular.

  1. Por mucho que soy fanático de Java Generics, hay muchas rarezas que surgen de la forma en que fue diseñado. Como tal, existe una miríada de limitaciones molestas con los genéricos (algunos de los cuales son el resultado de la eliminación de tipos).
  2. La forma en que funcionan Object.clone () y las interfaces clonables está totalmente dañada.
  3. En lugar de tomar el camino y convertir todo en un objeto (por ejemplo, SmallTalk), Sun creó dos categorías distintas de tipos de datos: objetos y primitivas. Como resultado, ahora hay dos representaciones para tipos de datos fundamentales y curiosidades extrañas como el boxeo / unboxing y no poder poner primitivas en una Colección.
  4. El swing es demasiado complejo. No me malinterpreten: hay muchas cosas geniales que uno puede hacer con Swing, pero es un gran ejemplo de ingeniería excesiva.
  5. Esta queja final es igualmente culpa de Sun y de quienes han escrito bibliotecas XML para Java. Las bibliotecas XML de Java son demasiado complicadas. Para poder simplemente leer en un archivo XML, a menudo tengo que preocuparme sobre qué analizador estoy usando: ¿DOM o SAX? Las API para cada uno son igualmente confusas. El soporte nativo en el lenguaje para analizar / escribir fácilmente XML sería muy bueno.
  6. java.util.Date apesta. No solo es innecesariamente complicado, sino que todos los métodos útiles han quedado en desuso (y reemplazados por otros que aumentan la complejidad).
Ryan Delucchi
fuente
32
Te olvidaste de java.util.Date!
TM.
3
Además: la interfaz "Cloneable" no tiene un método "clone ()". Esto hace que la interfaz de Cloneable sea un oxímoron. Y dado que clone () devuelve un Objeto, la seguridad de tipos está fuera de la ventana (no parece haber ningún intento de rectificar esto incluso después de que se hayan introducido Generics en J2SE 5.0).
Ryan Delucchi
2
Siempre y cuando estemos en cloneable, también podríamos incluir la llamada "interfaz" serializable. Cada vez que lo uso, siempre quiero apuñalarme.
wds
12
Es difícil hacer cosas simples como abrir un archivo y leerlo.
Eric Johnson el
3
@Ryan clone () no necesariamente debe devolver "Object". Con J2SE 5.0, Java introdujo tipos de retorno covariantes, lo que significa que puede devolver cualquier subtipo de una clase base. ¡Entonces el clon público MyType () ES posible!
método de ayuda
73

Ruby tiene muchos defectos relacionados con su velocidad, pero no los odio. También tiene fallas con el evangelismo comunitario que se va por la borda, pero eso realmente no me molesta. Esto es lo que odio:

  • Los cierres (bloques) tienen 4 sintaxis de creación diferentes, y ninguno de ellos es óptimo. La sintaxis elegante es incompleta y ambigua con los hashes, y la sintaxis completa es fea.
  • La comunidad tiende a estar en contra de la documentación real, favoreciendo 'leer el código'. Esto me parece infantil y vago.
  • El abuso de la metaprogramación, particularmente en las bibliotecas, hace que los errores sean una pesadilla para rastrear.
  • En una nota relacionada, la metaprogramación generalizada hace que un IDE integral sea difícil, si no imposible, de hacer.
  • La forma en que el bloque pasa a las funciones es tonta. No hay ningún motivo por el que los bloques se deban pasar fuera de la lista de parámetros o tengan una sintaxis especial impar para acceder (rendimiento). Soy de la opinión de que los bloques deberían haber recibido una sintaxis menos ambigua (o los hashes podrían haber usado diferentes delimitadores; quizás <> en lugar de {}), y pasar como parámetros a los métodos debería haber sido como todos los demás parámetros.

    object.method(1, {|a| a.bar}, "blah")
    

    Estas rarezas, como el bloque debe ser el último parámetro pasado y pasar más de un bloque es diferente con una sintaxis más larga, realmente me molesta.

Myrddin Emrys
fuente
2
m17n subóptimo y soporte unicode, aunque está mejorando. 1.9 sigue siendo complicado ...
Keltia
37
Pensé que el abuso de metaprogramación se llama "rubí idiomático" :)
Slartibartfast
2
akway: Las otras dos sintaxis son lambda y Proc.new .
Myrddin Emrys
2
En cuanto a la documentación, una vez escuché una charla de alguien que trabajaba en la editorial Pragmatic Programmers, quien dijo que cuando se fundó la compañía, querían un libro Ruby porque el único que estaba disponible estaba en japonés. Entonces podrían haber tenido ese libro traducido y publicado por su compañía. Pero lo que hicieron en lugar de leer el código fuente :-) El libro de Ruby fue aparentemente uno de los libros que lanzó Pragmatic Programmers.
Arthur Reutenauer
13
Me parece interesante que 3 de estos tengan que ver con personas y no con el lenguaje en sí. Ruby sigue siendo el idioma que menos odio.
Toby Hede el
72

Perl

  • Uso mixto de sigilos

    my @array = ( 1, 2, 3 );
    my $array = [ 4, 5, 6 ];
    
    my $one  = $array[0]; # not @array[0], you would get the length instead
    my $four = $array->[0]; # definitely not $array[0]
    
    my( $two,  $three ) = @array[1,2];
    my( $five, $six   ) = @$array[1,2]; # coerce to array first
    
    my $length_a = @array;
    my $length_s = @$array;
    
    my $ref_a = \@array;
    my $ref_s = $array;
    
    • Por ejemplo, ninguno de estos es igual:

      $array[0]   # First element of @array
      @array[0]   # Slice of only the First element of @array
      %array[0]   # Syntax error
      $array->[0] # First element of an array referenced by $array
      @array->[0] # Deprecated first element of @array
      %array->[0] # Invalid reference
      $array{0}   # Element of %array referenced by string '0'
      @array{0}   # Slice of only one element of %array referenced by string '0'
      %array{0}   # Syntax error
      $array->{0} # Element of a hash referenced by $array
      @array->{0} # Invalid reference
      %array->{0} # Deprecated Element of %array referenced by string '0'
      

    En Perl6ella está escrito :

    my @array = ( 1, 2, 3 );
    my $array = [ 4, 5, 6 ];
    
    my $one  = @array[0];
    my $four = $array[0]; # $array.[0]
    
    my( $two,  $three ) = @array[1,2];
    my( $five, $six   ) = $array[1,2];
    
    my $length_a = @array.length;
    my $length_s = $array.length;
    
    my $ref_a = @array;
    my $ref_s = $array;
    
  • Falta de verdadera OO

    package my_object;
    # fake constructor
    sub new{ bless {}, $_[0] }
    # fake properties/attributes
    sub var_a{
      my $self = shift @_;
      $self->{'var_a'} = $_[0] if @_;
      $self->{'var_a'}
    }
    

    En Perl6ella está escrito :

    class Dog is Mammal {
        has $.name = "fido";
        has $.tail is rw;
        has @.legs;
        has $!brain;
        method doit ($a, $b, $c) { ... }
        ...
    }
    
  • Características de expresiones regulares mal diseñadas

    /(?=regexp)/;           # look ahead
    /(?<=fixed-regexp)/;    # look behind
    /(?!regexp)/;           # negative look ahead
    /(?<!fixed-regexp)/;    # negative look behind
    /(?>regexp)/;           # independent sub expression
    /(capture)/;            # simple capture
    /(?:don't capture)/;    # non-capturing group
    /(?<name>regexp)/;      # named capture
    /[A-Z]/;                # character class
    /[^A-Z]/;               # inverted character class
    # '-' would have to be the first or last element in
    # the character class to include it in the match
    # without escaping it
    /(?(condition)yes-regexp)/;
    /(?(condition)yes-regexp|no-regexp)/;
    /\b\s*\b/;              # almost matches Perl6's <ws>
    /(?{ print "hi\n" })/;  # run perl code
    

    En Perl6ella está escrito :

    / <?before pattern>  /;   # lookahead
    / <?after pattern>   /;   # lookbehind
    / regexp :: pattern  /;   # backtracking control
    / ( capture )        /;   # simple capture
    / $<name>=[ regexp ] /;   # named capture
    / [ don't capture ]  /;   # non-capturing group
    / <[A..Z]>           /;   # character class
    / <-[A..Z]>          /;   # inverted character class
    # you don't generally use '.' in a character class anyway
    / <ws>               /;   # Smart whitespace match
    / { say 'hi' }       /;   # run perl code
    
  • Falta de despacho múltiple

    sub f(   int $i ){ ... }  # err
    sub f( float $i ){ ... }  # err
    sub f($){ ... } # occasionally useful
    

    En Perl6ella está escrito :

    multi sub f( int $i ){ ... }
    multi sub f( num $i ){ ... }
    multi sub f( $i where $i == 0 ){ ... }
    multi sub f(     $i ){ ... } # everything else
    
  • Mala sobrecarga del operador

    package my_object;
    use overload
      '+' => \&add,
      ...
    ;
    

    En Perl6ella está escrito :

    multi sub infix:<+> (Us $us, Them $them) |
                        (Them $them, Us $us) { ... }
    
Brad Gilbert
fuente
55
No veo la falta de verdadero OO como algo tan malo como tú. A veces, es un salvador, especialmente cuando el módulo CPAN que está utilizando no pensó en exponer lo que necesita. Y la falta de despacho múltiple podría ser peor: Perl podría haber sido fuertemente tipado ;-)
Tanktalus
3
Me gusta que Perl no esté fuertemente tipeado, pero sería útil agregar alguna información de tipo.
Brad Gilbert
13
Parece que elegiste criticar un idioma que no es tu favorito (deberías haber criticado a perl6)
Frew Schmidt
55
¿Cuál es el punto de comparar con perl 6? ¿Está sugiriendo que perl 6 solucione sus problemas o los continúe?
Robert P
2
Dudo que necesite decir más que: ozonehouse.com/mark/periodic
Arafangion
57

Haré PHP como me gusta a veces y Python se hará demasiado.

  • Sin espacio de nombres; todo está en una especie de espacio de nombres muy grande que es un infierno en entornos más grandes

  • Falta de estándares cuando se trata de funciones: las funciones de matriz toman una aguja como primer argumento, el pajar como segundo (ver array_search ). Las funciones de cadena a menudo toman el pajar primero, la aguja en segundo lugar (ver strpos ). Otras funciones solo usan diferentes esquemas de nombres: bin2hex , strtolower , cal_to_jd

    Algunas funciones tienen valores de retorno extraños, fuera de lo normal: esto lo obliga a tener una tercera variable declarada de la nada, mientras que PHP podría interpretar eficientemente una matriz vacía como falsa con su tipo de malabarismo. Casi no hay otras funciones que hagan lo mismo.

    $var = preg_match_all('/regexp/', $str, $ret);
    echo $var; //outputs the number of matches 
    print_r($ret); //outputs the matches as an array
    
  • El lenguaje (hasta PHP6) hace todo lo posible para respetar una compatibilidad hacia atrás casi retardada, por lo que lleva malas prácticas y funciones cuando no es necesario (ver mysql_escape_string vs. mysql_real_escape_string ).

  • El lenguaje evolucionó de un lenguaje de plantillas a uno completo. Esto significa que cualquiera puede generar cualquier cosa cuando lo desee, y se abusa de ella. Terminas con motores de plantillas para un lenguaje de plantillas ...

  • Apesta al importar archivos. Tiene 4 formas diferentes de hacerlo (include, include_once, require, require_once), todos son lentos, muy lentos. De hecho, todo el lenguaje es lento. Al menos, bastante más lento que Python (incluso con un marco) y RoR de lo que yo deduzco.

Sin embargo, todavía me gusta PHP. Es la motosierra del desarrollo web: ¿desea un sitio pequeño a mediano hecho realmente rápido y asegúrese de que cualquiera pueda alojarlo (aunque las configuraciones pueden diferir)? PHP está ahí, y es tan omnipresente que solo lleva 5 minutos instalar una pila LAMP o WAMP completa. Bueno, ahora voy a volver a trabajar con Python ...

DOY TERRIBLE ASESORAMIENTO
fuente
44
Supongo que el punto 1 se implementa en 5.3 :) Si bien el orden de los parámetros está mejorando, la asignación de nombres sigue siendo deficiente. Sin embargo, estoy de acuerdo con la compatibilidad hacia atrás.
Ross
44
Tengo que amar # 4. Esa es una de las cosas que más me molestó todo el tiempo, también.
Franz el
1
Creo que el argumento de la velocidad es bastante subjetivo. La velocidad depende mucho más de la eficacia del código que del lenguaje en sí. El código PHP deficiente es probablemente más lento que el código Python de alta calidad, pero un PHP bueno también puede funcionar mejor que Python pobre.
selfawaresoup
17
no_really_now_mysql_escape_the_string_im_serious ()
Salario
2
espacios de nombres schmamespaces. PHP está en la red mundial, por lo que todo debería ser global
Evan Plaice
50

Aquí hay algunas cosas que no me gustan de Java (que no es mi idioma favorito):

  • Borrado de tipo genérico (es decir, sin genéricos reificados)
  • Incapacidad para capturar múltiples excepciones (de diferentes tipos) en un solo bloque de captura
  • Falta de destructores (finalize () es un sustituto muy pobre)
  • No se admiten cierres o funciones de tratamiento como datos (las clases internas anónimas son un sustituto muy detallado)
  • Excepciones marcadas en general, o más específicamente, haciendo que las excepciones irrecuperables estén marcadas (por ejemplo, SQLException)
  • No hay soporte a nivel de idioma para colecciones literales
  • No hay inferencia de tipos cuando se llaman constructores de clases genéricas, es decir, los parámetros de tipo deben repetirse en ambos lados del '='
Don
fuente
1
@Svish: creo que el punto es que solo usarías esta construcción cuando no te importa con qué tipo de excepción estás lidiando. En otras palabras, cuando quieres manejarlos todos de manera idéntica
Dónal
3
No diría que la falta de destructores es un defecto cuando el lenguaje tiene un GC, y un GC que ha mejorado cada vez más. Se perdieron los destructores en java 1.1.8 pero no en java 6 porque gc ha mejorado enormemente.
Mike Reedell
77
C # corrige todos estos, excepto la captura de múltiples excepciones. Los genéricos se reifican, los destructores se reemplazan usando / IDisposable, los cierres se implementan por métodos anon y lambdas, las excepciones no están marcadas, hay literales de colección y hay 'var' para evitar especificar el tipo construido dos veces.
Daniel Earwicker
1
Java definitivamente tiene cierres. Una clase interna anónima se cierra sobre variables finales locales en su alcance. Estoy de acuerdo en que las clases internas anónimas no son un sustituto adecuado de las funciones anónimas, pero son cierres.
Adam Jaskiewicz 05 de
2
Las clases internas de Anon NO son cierres: intente crear una devolución de llamada de visitante con algo como "sum + = current.amount ()", donde "sum" es una variable no final del ámbito de inclusión. Cerca, pero sin cigarro.
Roboprog
40

C ++

  1. Sintaxis de plantilla
  2. Problemas de herencia de diamantes
  3. La gran cantidad / falta de bibliotecas estándar que tienen los lenguajes modernos (aunque el impulso se acerca).
  4. IOStreams
  5. La sintaxis utilizada alrededor de IOStreams

Pitón

  1. Los espacios son significativos (a veces)
  2. palabras clave subrayadas
  3. Soporte de hilo limitado (al menos actualmente)
  4. "self" en lugar de "this"
  5. Los espacios son significativos (a veces)
afligirse
fuente
80
Puede referirse a "uno mismo" como "esto" si realmente lo desea (aunque puede ser difícil para otros seguirlo). "Self" no es una palabra clave, y puede nombrar la variable como desee.
mipadi
36
Ahí tienes, en realidad enumeraría la importancia del espacio en blanco (especialmente la sangría) en Python como una de sus mayores ventajas ...;)
Oliver Giesen
22
¡"los espacios son significativos" es una de las mejores características de python! ps intente ejecutar esto en un intérprete "desde futuras llaves de importación"
hasen
44
No estoy de acuerdo con casi toda su lista de Python, excepto el soporte de hilos. El espacio en blanco no es significativo, la sangría es significativa; Hay una gran diferencia.
Christian Oudard
3
Guau. Es como si nadie hubiera inventado un editor de texto que resalte / muestre espacios en blanco / pestañas como caracteres especiales (¿Qué, está codificando en el bloc de notas?). Además, si expande las pestañas a los espacios, vaya a morir en un incendio.
Nombre falso el
37

C objetivo

1) Sin espacios de nombres, solo convenciones de nomenclatura manual: no me importa eso en términos de separación de clases, pero extraño poder importar todas las definiciones de clase en un espacio de nombres en una sola línea (como import com.me.somelibrary. *)

2) Las bibliotecas todavía tienen algunos agujeros en áreas importantes como el soporte de RegEx.

3) La sintaxis de la propiedad es un poco torpe y requiere tres líneas (en dos archivos separados) para declarar una propiedad.

4) Me gusta el modelo de retención / liberación, pero es más fácil de lo que debería ser liberar una referencia y luego usarla accidentalmente más tarde.

5) Aunque en realidad no es una característica del lenguaje, Xcode está tan entrelazado con el uso de Objective-C que no puedo evitar pensar en ese aspecto ... básicamente el autocompletado, es muy dudoso. Es más como un sistema que lo recompensa por encontrar algo que desea, y luego lo presenta como una opción. Pero supongo que nunca me han gustado los motores de autocompletado.

Kendall Helmstetter Gelner
fuente
2
De acuerdo sobre los espacios de nombres, prefijar las clases con códigos de letras es tonto. Y agregaría el soporte faltante para las variables de clase real, no me gusta fingirlas con estadísticas de archivos.
zoul
2
Propiedades de Objective-C. En serio, son impactantes, no puedo entender la exageración, especialmente viendo lo bien que C # los hace.
Justicle
66
En realidad, me gustó mucho ese aspecto de Lisp y ObjC: solo necesitas un editor con una buena combinación de llaves, como Emacs o XCode. Por lo general, escribo llaves en pares antes de escribir algo en ellas, por lo que realmente no tengo problemas con la coincidencia ... y XCode también puede resaltar la región encerrada por una llave con solo hacer doble clic en cualquiera de las llaves.
Kendall Helmstetter Gelner
1
@ Chris S: ¿Estás diciendo que YES/NOpara los booleanos es algo malo? Y lo más importante, ¿estás diciendo que los parámetros con nombre son algo malo? Puedo entender los bools, pero los parámetros con nombre son posiblemente una de las mejores características de ObjC (en términos de legibilidad).
jbrennan
3
Tal vez soy masoquista, pero me gustan los nombres de clase prefijados. Hace que las búsquedas en Google y en la documentación sean claras, nunca hay confusión sobre qué tipo de cadena estás usando si la clase se llama NSString.
kubi
36

C ++

  • Instrumentos de cuerda.
    No son interoperables con cadenas de plataforma, por lo que terminas usando std :: vector la mitad del tiempo. La política de copia (copia en escritura o copia profunda) no está definida, por lo que no se pueden dar garantías de rendimiento para una sintaxis directa. A veces se basan en algoritmos STL que no son muy intuitivos de usar. Demasiadas bibliotecas utilizan las suyas, que desafortunadamente son mucho más cómodas de usar. A menos que tengas que combinarlos.

  • Variedad de representaciones de cadenas
    Ahora, este es un pequeño problema de plataforma, pero todavía espero que hubiera sido mejor cuando una clase de cadena estándar menos obstinada hubiera estado disponible antes. Las siguientes representaciones de cadenas que uso con frecuencia:

    • LPCTSTR genérico,
    • LPC (W) STR asignado por CoTaskMemAlloc,
    • BSTR, _bstr _t
    • (w) cadena,
    • Cuerda C,
    • std :: vector
    • una clase roll-my-own ( suspiro ) que agrega verificación de rango y operaciones básicas a un búfer (w) char * de longitud conocida
  • Construir modelo.
    Estoy harto de todo el tiempo dedicado a confundir con quién incluye qué, declaraciones de avance, optimización de encabezados precompilados e incluye mantener soportables al menos los tiempos de construcción incrementales, etc. Fue genial en los años ochenta, ¿pero ahora? Hay tantos obstáculos para empacar un código para que se pueda reutilizar que incluso las mamás se aburren de escucharme.

  • Difícil de analizar
    Esto hace que las herramientas externas sean especialmente difíciles de escribir y que sean correctas. Y hoy, los chicos de C ++ nos faltan principalmente en la cadena de herramientas. Me encanta mi reflejo de C # y mis delegados, pero puedo vivir sin ellos. Sin una gran refactorización, no puedo.

  • Enhebrar es demasiado difícil El
    lenguaje ni siquiera lo reconoce (por ahora), y las libertades del compilador, aunque excelentes, son demasiado dolorosas.

  • Inicialización estática y bajo demanda Técnicamente, hago trampa aquí: esta es otra pieza del rompecabezas en el "código de cierre para su reutilización": es una pesadilla obtener algo inicializado solo cuando es necesario. La mejor solución para todos los demás problemas de redist es lanzar todo a los encabezados, este problema dice "neeener - you can not".


Por supuesto, mucho de eso está más allá del alcance estricto del lenguaje, pero en mi opinión, toda la cadena de herramientas debe ser juzgada y debe evolucionar.

peterchen
fuente
Buscar documentación en el STL es como buscar manuales sobre cómo construir una tarjeta gráfica desde cero.
aviraldg
Francamente, la mayoría de estos puntos suenan como si nunca se hubiera molestado en aprender C ++ correctamente ... esto se vuelve bastante obvio en el n. ° 3, ya que los protectores de inclusión son algo que todo programador de C ++ debería saber. Tampoco estoy seguro de cómo entender el punto 1, ¿estás confundido std::string? quizás leer una buena documentación y / o tutorial sobre std::vector(y por qué se supone que no debes usarlo std::stringen lugares donde nunca fue diseñado) podría aclararte eso.
@nebukadnezzar: Encontré a Meyers iluminando el STL, pero no resuelve los problemas fundamentales. Francamente, esto parece que nunca tuvo que mantener un proyecto grande, nunca tuvo que buscar una dependencia circular en una jerarquía de inclusión de docenas de profundidad. Sé que incluyen guardias, pero ¿por qué tenemos que molestarnos con ellos? Por cierto. No solucionan todos los problemas. ¿Qué tan "estándar" es std::stringsi no puedo usarlo la mitad del tiempo? (C ++ 0x al menos corrige eso, pero todavía estoy atascado con docenas de bibliotecas que usan diferentes representaciones de cadenas).
peterchen
but why do we have to bother with them (inclusion guards)- porque C ++ no tiene módulos. How "standard" is a std::string if I can't use it half of the time?- Creo que eso depende de la forma en que lo uses std::string. La clase de cadena le permite acceder a los datos de cadena como const char*vía std::string::c_str, lo que ya lo hace std::stringperfectamente compatible con cada clase / función que también toma const char*argumentos.
porque C ++ no tiene módulos , exactamente mi queja: el modelo de compilación es antiguo (también aceptaría cualquier otra solución que no sean módulos). ----- perfectamente compatible , pero perfectamente incompatible con muchos otros escenarios. han sido adoptados como LA clase de cadena hace 10 años, pero no fue la otra queja.
peterchen
35

JavaScript :

  • El Objectprototipo puede ser modificado. Cada objeto en su programa obtiene nuevas propiedades, y algo probablemente se rompe.

  • Todos los objetos son mapas hash, pero es difícil usarlos de forma segura como tal. En particular, si una de tus claves es __proto__, estás en problemas.

  • Sin cierre de objeto en el tiempo de referencia de la función. De hecho, no se cierra ningún objeto; en su lugar, thisse establece cada vez que se llama a una función con notación de objeto o el newoperador. Resulta una gran confusión, particularmente cuando se crean devoluciones de llamadas de eventos, porque thisno está configurado según lo que el programador espera.

    • Corolario: llamar a una función sin notación de objeto o el newoperador da como resultado que thisse establezca igual al objeto global, lo que resulta en una gran ruptura.
  • El operador de adición está sobrecargado para realizar también la concatenación de cadenas, a pesar de que las dos operaciones son fundamentalmente diferentes. Resulta doloroso cuando un valor que espera que sea un número es, de hecho, una cadena.

  • ==y los !=operadores realizan coerción de tipo. Las comparaciones entre diferentes tipos implican una lista de reglas que ningún mortal puede recordar en su totalidad. Esto se ve mitigado por la existencia de ===y !==operadores.

  • Ambos nully undefinedexisten, con significados sutilmente diferentes, pero redundantes. ¿Por qué?

  • Sintaxis extraña para configurar cadenas de prototipos.

  • parseInt(s)espera un número de estilo C, por lo que trata los valores con ceros a la izquierda como octales, etc. Al menos puede, parseInt(s, 10)pero el comportamiento predeterminado es confuso.

  • Sin alcance de bloque.

  • Puede declarar la misma variable más de una vez.

  • Puede usar una variable sin declararla, en cuyo caso es global y probablemente interrumpe su programa.

  • with { }.

  • Muy difícil de documentar con JavaDoc como herramientas.

Daniel Cassidy
fuente
3
Para nully undefined: a veces realmente desea saber si a la variable se le ha asignado un valor o no. Como nulo es un valor, indefinido es la única forma de saberlo. De acuerdo, la única vez que he encontrado esto útil fue para crear funciones getter / setter.
Zach
1
"si una de tus claves es proto ", bueno, es una palabra reservada con un significado especial. Es como quejarse de que no se puede usar forcomo nombre de variable.
nickf
55
@nickf: la clave para un hash es una cadena. Las cadenas pueden tener cualquier valor, incluidas las palabras reservadas. En particular, el valor "for"es válido como una clave hash. __proto__No es una palabra reservada. Los valores de cadena especiales que no funcionan como se esperaba cuando se usan como claves hash violan expectativas razonables sobre cómo funcionan las matrices asociativas en cualquier idioma. También violan la especificación EcmaScript.
Daniel Cassidy
2
Thomas: Newline no siempre termina una declaración. Por lo tanto, los codificadores sensibles terminan cada declaración con un punto y coma para que el código sea más claro.
Daniel Cassidy
2
newline may or may not end a statement depending on contextes uno en mi lista de los 5 principales
reinierpost
34

Pitón:

  • Falta de tipeo estático
  • Manejo de argumentos por defecto (¡específicamente el hecho de que puede cambiar el argumento por defecto para las futuras llamadas!)
  • Demasiados guiones bajos necesarios (se deben llamar a los constructores __init__)
  • Falta de miembros y funciones privados adecuados (la convención solo dice que la mayoría de las cosas que comienzan con guiones bajos son privadas, excepto por todo lo __getattr__que no es así)
  • Sintaxis divertida para printir a un archivo (pero están arreglando eso en Python 3)
Greg Hewgill
fuente
10
Lo que me gustaría es una opción para usar tipos estáticos.
Greg Hewgill
44
Por cierto: init no es realmente el constructor, el objeto ya estaba creado, cuando ingresas allí (adivina qué es ...). El constructor es muy nuevo donde tienes acceso a la clase que se instanciará.
André
90
Si prefiere la escritura estática, ¿por qué Python es su idioma favorito?
finnw
99
finnw: La escritura estática es excelente para algunos tipos de programas, y no es realmente necesaria para otros tipos. Por lo general, no me importa la falta de tipeo estático, pero cuando lo necesita, es realmente bueno tener al menos la opción.
Greg Hewgill
8
Yo diría que la falta de tipificación estática es una característica, sin perder funcionalidad ...
arnorhs
32

C#

  • Ojalá pudiera switch()en cualquier tipo, y esa casepodría ser cualquier expresión.

  • No se puede usar la sintaxis del inicializador de objetos con campos / private setautoprops 'de solo lectura' . En general, quiero ayuda con el lenguaje para hacer tipos inmutables.

  • Uso de espacios{} de nombres y clases y métodos y bloques de propiedades / indexadores y bloques de múltiples instrucciones e inicializadores de matrices . Hace que sea difícil saber dónde estás cuando están muy separados o no coinciden.

  • Odio escribir (from x in y ... select).Z(). No quiero tener que recurrir a la sintaxis de llamada al método porque a la sintaxis de la consulta le falta algo.

  • Quiero una docláusula sobre la sintaxis de consulta, que es como foreach. Pero no es realmente una consulta entonces.

Realmente estoy llegando aquí. Creo que C # es fantástico, y es difícil encontrar mucho que esté roto.

revs Jay Bazuzi
fuente
14
+1 para encender cualquier tipo
oɔɯǝɹ
+1 para problemas de cambio, y {} problemas, que realmente no había pensado hasta ahora
Maslow
Odio {}. Se parecen demasiado a (). La falta de coincidencia nunca ha sido un gran problema para mí porque siempre los pongo al mismo nivel a menos que sean básicamente una frase.
Loren Pechtel el
2
+1 para la consulta linq. Especialmente cuando solo quieres que se devuelva un objeto. En lugar de (from x in y select) .first (), ¿por qué no a (from x in y select top 1) o algo que se ajuste más a la sintaxis sql real?
AdmSteck
si lo desea, podría cambiar () en cualquier tipo, y ese caso podría ser cualquier expresión, consulte la coincidencia de patrones F #. c-sharpcorner.com/UploadFile/mgold/…
gradbot
26

PHP

  1. No hay funciones de depuración si no controlas el servidor, e incluso entonces son un poco desagradables
  2. La cantidad extrema de mal código PHP flotando da a todos los programadores PHP un mal nombre
  3. Nombramiento de funciones inconsistentes
  4. Incapacidad de tener una variable de tipo estática si quiero una (soy un gran admirador de la escritura dinámica el 90% del tiempo)
  5. REGISTER_GLOBALS es el diablo
MattBelanger
fuente
25
REGISTER_GLOBALS una vez se comió a mi perro :(
Pim Jager
2
1: Recomiendo xdebug y un cliente GUI como MacGDBp. Eso realmente alivia un poco el dolor ... Estoy de acuerdo con los otros puntos.
Jonas Due Vesterheden
55
# 2: Oh dios, no me hagas empezar con eso. Siempre tengo que defenderme como desarrollador de PHP contra personas que solo han visto el desastre que muchas personas crean con PHP.
selfawaresoup
1
+1 para el n. ° 2 He pasado demasiado tiempo defendiéndome como desarrollador de PHP.
UnkwnTech
+1 para el n. ° 2: también resulta en un mal sueldo :(
Shiki
25

C (OK, no es mi favorito, pero aún no se había hecho).

  • Sintaxis de la biblioteca de sockets.
  • No hay sobrecarga de funciones.
  • Cuerdas de estilo C.
  • El búfer se desborda.
  • Sintaxis críptica. No sé cuántas veces busqué cosas como atoi, me golpeé la frente y grité "¡Por supuesto!"

EDITAR: Probablemente podría encontrar más si recurriera a más código de biblioteca (como hice con los sockets, pero esos son particularmente malos), pero ya sentía que estaba haciendo trampa para elegir C. Muchos idiomas existen solo para tomar las partes buenas de C y reemplazan las malas que es como golpear a un caballo muerto.

Bill el lagarto
fuente
22
¿Qué sintaxis de socket? C no tiene concepto de enchufes.
Ferruccio
3
¡Ay, vamos! Puedes llegar con cinco. ¿La aritmética de puntero no apesta? :)
brian d foy
8
+1 Me reí de las "cuerdas estilo C". Y @brain_d_foy: la aritmética del puntero solo es una mierda si no la entiendes.
Chris Lutz
1
@ Chris Luts: Incluso cuando estaba aprendiendo C simple (antes de conocer C ++ o cualquier otro lenguaje OO), sabía que había algo mal en los arrays de caracteres. :)
Bill the Lizard
2
puntero aritmético es una sierra eléctrica - muy eficiente, pero se arriesga a tomar toda su pierna
Thorbjørn Ravn Andersen
24

Lisp común:

  1. Las palabras clave suelen ser demasiado verbales.
  2. El apoyo de la biblioteca es lamentable.
  3. No funciona bien en sistemas operativos que desean manejar la memoria de manera más estricta.
  4. No tiene buenas instalaciones para interactuar con el sistema operativo.
  5. La función de "bucle" no está bien definida, y seguro que no se ve Lispy.
David Thornley
fuente
2
'loop' podría no ser lispy, pero ¿qué hay de mal definido al respecto?
Daniel Cassidy
2
No he leído el estándar yo mismo, voy sobre todo en "On Lisp" de Paul Graham. Él dice que el estándar es en su mayoría ejemplos, y no define bien los casos de esquina.
David Thornley
3
¿no te refieres a las palabras clave son demasiado verbales?
GClaramunt
Estoy de acuerdo en que no es "lispy", pero CLtLv2 pasa mucho tiempo en ello. Simplemente creo que fue diseñado para hacer demasiado. sunsite.univie.ac.at/textbooks/cltl/clm/…
Hans Van Slooten
Además de "bucle", "formato" tampoco es muy Lisplike. Odio el "formato" y el "bucle", a pesar de que Lisp es mi idioma favorito.
Paul Reiners
24

BrainF * ck

  • ¡Lo más destacado es que estás completando Turing ? ¡Puedo hacer más en expresiones regulares de Perl!

  • La falta de objetos. ¡Vamos, gente! Es como, hola ...

  • No hay bibliotecas de redes. Todo lo que quiero es raspar una página web, GOSH.

  • No hay funciones de primera clase. Felicidades, puedes compadecerte de tus amigos de Java.

  • Una cinta infinita para almacenamiento y nada más. Esto es tan analíticamente pretencioso que bien podríamos estar escribiendo Lisp.

un nerd pagado
fuente
66
No hay espacio de nombres o soporte de módulo dinámico. ¿Cómo se puede esperar que escribamos sistemas de control de plantas químicas sin estos conceptos básicos?
Donal Fellows
Sin azúcar sintáctica, como> 10 (mover 10 veces), 0 (insertar cero), +5 (agregar 5).
Squall
23

JavaScript

  1. números como cadenas: las matemáticas pueden ser frustrantes cuando los números se interpretan como cadenas. 5 + 2 = 52? Grrr ...
  2. permisos: ¡todo lo mejor requiere permiso del usuario!
  3. actualizaciones de pantalla: el navegador debe estar en estado estable para actualizar la pantalla. No parece haber una manera de forzar la actualización de la pantalla en medio de un script.
  4. Lento, aunque el Chrome de Google es bueno ...
  5. Las diferencias del navegador hacen que el uso del idioma sea [censurado].
BoltBait
fuente
44
Los números como cadenas se arreglan fácilmente. Si alguna vez tienes una cadena, debes analizarla (x, 10). El fallo gigante es cuando dejas de lado el 10 e interpreta '017' como OCTAL
Orion Edwards
3
falso == 0 == [] == "" pero nulo y NaN no lo son. NaN! = NaN. nulo == nulo.
Jimmy
77
typeof "a string" == "string". typeof new String ("another string") == "object. new String ('a'). constructor ==" a ".constructor. typeof new Array () == 'object'
Jimmy
1
para (x en objeto) devuelve funciones
Jimmy
14
-1, esta lista trata principalmente de problemas del navegador, no del idioma en sí.
Mauricio Scheffer
20

PHP:

  • Nunca se puede estar seguro de que ciertas extensiones casi comunes están disponibles en todos los servidores web.
  • intenta ser todo en el futuro (goto, cierres, ...)
  • muchos riesgos de seguridad para usuarios sin experiencia
  • más sobrecarga del operador sería bueno
  • todos los programadores pobres que no aprenden cómo hacer que funcione correctamente, y le dan un mal nombre

Sin embargo, PHP es el lenguaje (scripting). ;-)

okoman
fuente
OK, ¡solo queda una cosa más!
brian d foy
44
Totalmente de acuerdo con el punto 5: también estaría en una lista de Javascript.
Steve Claridge
No estoy de acuerdo con "todos los programadores pobres que no aprenden a hacer que funcione correctamente y le dan un mal nombre". Lo reemplazaría con "opciones masivas de configuración de lenguaje de tiempo de ejecución".
L̲̳o̲̳̳n̲̳̳g̲̳̳p̲̳o̲̳̳k̲̳̳e̲̳̳
18

VB6

  1. Solo Windows
  2. Ya no es compatible.
  3. Las matrices pueden comenzar en cualquier número, en lugar de normalizarse a 0.
  4. las aplicaciones compiladas dependen de muchos dll para ejecutarse correctamente.
  5. Muchos controles complicados, como un control de navegador o piezas de código complicadas, tienden a romper el IDE cuando ejecuta código sin compilar, pero funcionan bien cuando se compilan.
Asrrin29
fuente
13
VB es el idioma favorito de alguien? O_o. ¿Por qué no es "syntaz que es completamente diferente e incompatible con otros idiomas" y "da malos hábitos con respecto a otros idiomas" aquí?
Jonta
3
De hecho, encuentro que # 3 es una característica muy poderosa, no un error, realmente me encantaría que VB.NET tuviera esto. AWK lo tiene, en cierto sentido, pero luego en las matrices AWK hay realmente disfraces disfrazados :(
Joe Pineda
3
En 1 y 4, y .NET C # no requiere un MARCO COMPLETO y un sistema operativo ??? (hey, escuché que eres mono fanático ... sigue siendo un "marco completo" para ti, y dudo que un debian dist lo coma alguna vez). Con respecto a 5, sin programador VB6 mente recta (en su día) mantiene la "Compilar On Demand" opción por defecto EN ...
jpinto3912
2
Todavía tengo que soportar vb6 ocasionalmente. Pieves de mascotas: no se puede inicializar una variable en la declaración, no hay construcciones parametrizadas, una clase por archivo, etc. Si solucionaran estos problemas, el lenguaje podría continuar por otros 10 años más fácilmente.
AngryHacker
14
¿Qué pasa con "On Error Resume Next" ... es como decir "este código es F ** KED, pero
sigamos
18

Ruby es mi idioma favorito, esto es lo que no me gusta:

  • Hilos verdes + bloqueo de bibliotecas C = falla gigante
  • TAN DOLORAMENTE LENTO
  • ¡La biblioteca estándar en sí es inconsistente con su uso de bang! métodos
  • El módulo include + extend es desordenado.
  • Las "clases abiertas" no se pueden definir: quiero agregar una cadena # dostuff, pero no quiero que se filtre en todas las bibliotecas de terceros
  • Sin solución de empaquetado de implementación binaria.
Orion Edwards
fuente
3
¿Has probado Ruby 1.9.1? Ofrece una gran aceleración en comparación con Ruby 1.8.6
Christian Stade-Schuldt
Prueba jrubyc. JVM JIT FTW!
KitsuneYMG
+1 por incluir problemas razonables, en oposición a los "odios" de la respuesta Ruby mejor calificada
Phrogz
17

Delphi:

  • IDE es un poco inestable.
  • El conocimiento del código a veces se confunde.
  • La depuración a veces tiene errores.
  • Actualizar varios archivos de proyecto puede ser engorroso.
  • Si se inicia cuando uno o más paquetes no están disponibles, el mensaje de error aparece varias veces.
Toon Krijthe
fuente
55
Todo esto parece ser una queja sobre Delphi el IDE en lugar de Delphi el lenguaje (AKA Object Pascal)
Dónal
11
Presumiblemente eso se debe a que Object Pascal es perfecto ;-)
Mark Bessey
3
Llego un poco tarde a la fiesta, pero de todos modos: - tener que anotar las firmas del método dos veces (interfaz + implementación) - SE REQUIERE que el nombre de la unidad sea idéntico al nombre del archivo. WTF?!?
Martijn
1
Creo que el comienzo ... termina siendo superior: son mucho más claros que {}. Pasas mucho más tiempo leyendo códigos que escribiéndolo. Sin embargo, para una queja, no puede usar subrangos definidos de tipos enumerados en un caso, aunque es perfectamente legal si declara el rango allí mismo en el caso. Además, no hay referencias directas entre unidades.
Loren Pechtel el
1
@AlexanderN: No, nunca ha estado más vivo, popular o genial.
Andreas Rejbrand
16

JavaScript

  • Cada secuencia de comandos se ejecuta en un solo 'espacio de nombres' global ... algo que debe tener en cuenta al trabajar con secuencias de comandos de diferentes fuentes

  • Si se usa una variable pero no se ha definido de antemano, se considera una variable global

  • Los proveedores de navegadores crean estándares a su gusto, lo que hace que la codificación para nosotros los desarrolladores que utilicen un lenguaje tan hermoso sea más difícil de lo que debería ser

  • Sensibilidad a mayúsculas y minúsculas: teniendo en cuenta que no hay un IDE decente para desarrollar js con comprobación en tiempo de compilación

  • Soluciones (como el uso del hasOwnPropertymétodo) para realizar algunas operaciones que de otra forma serían simples.

Andreas Grech
fuente
AFAIK, todas las extensiones al lenguaje JS (no el DOM) por parte de los proveedores de navegadores al menos han sido impulsadas para la adopción estándar, incluso si el proceso de estándares no ha logrado eso. hasOwnProperty / soluciones alternativas: espada de doble filo. Para forzar la "simplicidad", perdemos mucho poder y flexibilidad. Esa queja siempre me molesta. ¡Escriba sus bucles correctamente (y compruebe también los miembros de su objeto)
párpado
15

Haskell

  1. El espacio se escapa de la evaluación perezosa.
  2. Jerarquía numérica no construida con respecto a las abstracciones matemáticas.
  3. La IO monádica estricta puede dificultar la depuración.
  4. Las grandes implementaciones manejan E / S de maneras que no parecen ser bastante compatibles con el estándar. (En particular, la salida de caracteres solo genera los 8 bits bajos, y luego se genera un código que utiliza esta suposición para hacer E / S binarias. Ick).
  5. La asociatividad del ($)operador podría cambiarse para hacer algunas expresiones más bonitas.

La mayoría de estos no alcanzan el nivel de odio, y hay personas que intentan arreglar o construir soluciones sólidas para cada uno de estos.

Editar: Ha habido cierta confusión sobre el punto 5. En particular, algunas personas parecen pensar que me refería al orden de los argumentos, lo cual no hago. En lugar de explicar lo que quise decir, solo dirijo a las personas al siguiente enlace, http://hackage.haskell.org/trac/haskell-prime/wiki/ChangeDollarAssociativity , que lo expresa bien.

wnoise
fuente
3
¿Por qué querrías cambiar la asociatividad de ($)? Corchetes 'fghx' como '((fg) h) x' y 'f $ g $ h $ x' corchetes como 'f (g (hx))' ...
Erik Hesselink
1
Yo <3 Haskell. La biblioteca estándar debe incluir montañas de abstracciones matemáticas, incluidos espacios vectoriales y otros. El preludio también necesita un operador que se encadene como ($) pero de izquierda a derecha {source |> func1 |> filter func2 |> map (func3 10)}.
yfeldblum
10
Te perdiste el realmente malo: la tendencia de los programadores de Haskell a usar nombres de variables de una letra.
Benjamin Confino
1
Un operador asociativo a la izquierda ($) es solo una aplicación de función, que en Haskell está representada por el carácter de espacio. @ Justicia: pruebe la función de volteo. (|>) = voltear ($)
Apocalisp
1
¿Alguien puede explicar el punto del n. ° 5? Pensé que la asociatividad correcta era el objetivo de ($).
Tim Matthews