it-swarm-es.com

¿Qué elemento de sintaxis odias más en un lenguaje de programación que usas con frecuencia?

No importa cuánto te guste un lenguaje de programación, siempre hay algunos detalles que no son tan buenos como podrían ser.

En esta pregunta, me gustaría centrarme específicamente en elementos de sintaxis En un lenguaje de programación que usa con frecuencia (tal vez su lenguaje de programación favorito, o quizás el que está obligado a usar en el trabajo), que ¿El elemento de sintaxis le resulta más ilegible, poco claro, inconveniente o desagradable?

26
Timwi

Inserción de punto y coma en JavaScript.

Realmente no me ha mordido a menudo, pero es una idea tan fenomenalmente mala que me da vueltas la cabeza.


Aquí están las reglas (de ECMA-262 Sección 7.9)

  1. Cuando el programa contiene un token que no está permitido por la gramática formal, se inserta un punto y coma si (a) hay un salto de línea en ese punto, o (b) el token inesperado era una llave de cierre.
  2. Cuando se alcanza el final de un archivo, si el programa no se puede analizar de otra manera, se inserta un punto y coma.
  3. Cuando se encuentra una "producción restringida" y contiene un terminador de línea en un lugar donde la gramática contiene la anotación "[no hay LineTerminator aquí]", se inserta un punto y coma.

Ejemplo:

return 1; // returns 1

return
1; // returns undefined
39
Tim Goodman

Sintaxis de Java-Bean debido a la falta de propiedades de C #

/**
 * Name of user
 */
private String name;

/**
 * Gets name of user
 * @return Name of user
 */
public String getName() {
    return this.name;
}

/**
 * Sets name of user. 
 * @param name
 */
public void setName(final String name) {
    this.name = name;
}

GAH !!!

Problemas que tengo con esto

  • Demasiado código : tenga un campo documentado, un método getter documentado y un método setter documentado. Este ejemplo extremadamente básico tiene 20 líneas de código para una propiedad single
  • Listas de métodos de desorden - "Déjame encontrar ese método, mano: getX, getY, getZ, getAnotherAnnoyingField, getWhyIHateJavaBeans, getThisIsVerbose, getGAH... ah ahí está, hashCode.
  • Múltiples áreas de documentación conducen a documentación deficiente, desactualizada o faltante - Molesto cuando se trata de entender qué hace el código
  • Tan molesto que un tercero tuvo que crear un complemento para hacerlo fácilmente - Spoon , Shark , entre otros.
39
TheLQ

Sensibilidad de espacios en blanco.

Python me molesta a este respecto. Quiero decir, sangro correctamente de todos modos, pero me molesta que debería tener a. Hacer que la presentación sea parte de la sintaxis me irrita.

32
Fishtoaster

La declaración switch (en C, C++, C #, Java, etc.)

Aquí hay un ejemplo de por qué me resulta muy inconveniente:

switch (someVariable)
{
    case 1:
        int i = something();
        doSomething(i);
        break;

    case 2:
        int i = somethingElse();
        doSomethingElse(i);
        break;
}

Esto no se compila porque la variable i se vuelve a declarar en el mismo ámbito. Esto parece un detalle menor, pero me muerde muy a menudo. Puedo agregar llaves para mitigarlo, pero hubiera sido bueno si las llaves hubieran sido parte obligatoria de la sintaxis, y no hubiera un nivel de sangría adicional redundante. También odio tener que escribir el break extra. Esto sería mucho mejor:

switch (someVariable)
case 1
{
    int i = something();
    doSomething(i);
}
case 2
{
    int i = somethingElse();
    doSomethingElse(i);
}
default
{
    ...
}

Esto hace que se parezca más a una cadena if/else, lo cual es bueno porque también es semánticamente similar. Sin embargo, al menos en C # todavía no sería lo mismo, porque en una declaración switch el orden de las etiquetas de caso no importa, pero en una if/else lo hace.

32
Timwi

Declaraciones de matriz en VB.NET

Siempre logro olvidar que al inicializar arreglos fijos en VB.NET, está especificando el límite superior del arreglo y no el número de elementos como en C/C++, PHP o Java. Además de VB6 (no iremos allí ...), no puedo pensar en otro idioma que lo haga de esta manera:

Dim myArray(20) as Integer  '# Creates an array with 21 elements,
                            '# indexed from 0 to 20
27
user95

VB6 - Declaración y asignación de variables separadas

La mayoría de los idiomas le permiten declarar una variable y asignarla en una línea de código; VB6, por otro lado, te obliga a usar dos.

Dim i as Integer
i = 0

Dim derpderp as Collection
Set derpderp = new Collection

Puede usar dos puntos para colocar dos comandos en una línea, pero rápidamente se vuelve desordenado en el código real.

Dim i as Integer: i = 0
Dim derpderp as Collection: Set derpderp = new Collection
24
derekerdmann

Comentando en CSS

// no comenta líneas de código como lo hace en muchos otros idiomas, como PHP y Javascript. Aunque /* this is commented out */ funciona, prefiero usar //.

Es una molestia, porque la mitad del tiempo me olvido de que estoy editando CSS y luego tengo que volver y corregir el error.

24
Talvi Watia

PHP - ordenamiento consistente de argumentos

PHP tiene una serie de funciones útiles para realizar prácticamente todas las operaciones que pueda imaginar en una matriz o cadena. Muchas de estas operaciones requieren el uso de un $needle y a $haystack, pero diferentes funciones las toman en diferentes órdenes. ¡Qué función requiere qué argumentos es uno de esos hechos que mi cerebro se niega a absorber, sin importar con qué frecuencia los encuentre!

Tome las funciones in_array y strstr :

// Check whether $needle occurs in array $haystack
bool in_array (mixed $needle, array $haystack [, bool $strict])

// Check whether $needle is a substring of $haystack
string strstr (string $haystack, mixed $needle [, bool $before_needle=false])

Curiosamente, PHP parece ser internamente consistente con estos ordenamientos en que todas las funciones de cadena parecen usar $haystack, $needle mientras que las funciones de matriz son al revés, pero esto puede llevar un poco de tiempo acostumbrarse a alguien nuevo en PHP. Hay un buen publique en ExpressionEngine hablando sobre esta peculiaridad en particular con más detalle, así como un discusión sobre la PHP lista de errores , que presenta una respuesta muy corta del PHP equipo!

[email protected]
Use un decente IDE entonces.
20
ConroyP

Python

self parámetro en definiciones de métodos de instancia

19
Goran Peroš

Java

Período. Punto final. Fin de la historia.

¿Donde empezar? Oh, sé por dónde empezar: Java es increíblemente complicado, feo, estúpido y inherentemente rotogenéricos. ¿Necesito decir mas? :( Ok bien, entonces: tipo borrado.

Luego está la gestión de recursos no determinista. Kewl Piescher!

¿Qué sigue? Ah, sí: las expresiones estúpidas de Java son mi carne más irritante y bulliciosa. No puedo contar cuántas veces he sido manguera por no tener suficientes barras invertidas. Esto es aún peor que no tener acceso a ninguna propiedad Unicode de este milenio, que es un toro completo. ¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡Diez años malditos desactualizados !!!Completamente inútil. Basura que.

Luego está el error de que los atajos de clase de caracteres no funcionan en no ASCII. ¡Qué dolor real! ¡Y ni siquiera considere usar \p{javaWhiteSpace}; no hace lo correcto con varios puntos de código de espacio en blanco Unicode muy comunes.

¿Sabía que hay una propiedad \p{javaJavaIdentifierStart}? ¿En qué estado estaban pensando? Estoy tan contento de que hayan conseguido espías tan inteligentes trabajando duro.

¿Alguna vez trató de usar la bandera Canon_EQ? ¿Sabes que realmentehace, y lo que no hacehace? ¿Qué tal el llamado "caso Unicode"? Un montón de cosas normales de la carcasa simplemente no funcionan en absoluto.

Luego hacen que sea difícil escribir expresiones regulares mantenibles. Java todavía no ha descubierto cómo escribir cadenas de varias líneas, por lo que terminas escribiendo cosas como esta:

    "(?= ^ [A-Z] [A-Za-z0-9\\-] + $)      \n"
  + "(?! ^ .*                             \n"
  + "    (?: ^     \\d+      $            \n"
  + "      | ^ [A-Z] - [A-Z] $            \n"
  + "      | Invitrogen                   \n"
  + "      | Clontech                     \n"
  + "      | L-L-X-X                      \n"
  + "      | Sarstedt                     \n"
  + "      | Roche                        \n"
  + "      | Beckman                      \n"
  + "      | Bayer                        \n"
  + "    )      # end alternatives        \n"
  + ")          # end negated lookahead   \n" 

¿Cuáles son todas esas líneas nuevas? Oh, solo Java estupidez. Usaron comentarios de Perl, no Java comentarios ( idiotas!) Que van hasta fin de línea. Entonces, si no pones esos \n ahí, cortarás el resto de tu patrón. ¡Duh y doble duh!

No uses expresiones regulares en Java: simplemente terminarás queriendo romper cosas, todo es muy doloroso y roto. No puedo creer que la gente aguante esto. Algunos no .

Entonces podemos comenzar a hablar sobre las tonterías idiotas de Java con codificaciones. Primero, está el hecho de que la codificación de plataforma predeterminada siempre es una codificación poco convincente de 8 bits a pesar de que los caracteres de Java son Unicode. Luego está cómo no generan una excepción en un error de codificación. Te garantizamos que obtendrás basura. O qué tal esto:

OutputStreamWriter(OutputStream out) 
          Creates an OutputStreamWriter that uses the default character encoding.
OutputStreamWriter(OutputStream out, Charset cs) 
          Creates an OutputStreamWriter that uses the given charset.
OutputStreamWriter(OutputStream out, CharsetEncoder enc) 
          Creates an OutputStreamWriter that uses the given charset encoder.
OutputStreamWriter(OutputStream out, String charsetName) 
          Creates an OutputStreamWriter that uses the named charset.

¿Cual es la diferencia? ¿Sabía que solo uno de esos generará una excepción si tiene un error de codificación? El resto solo les hace bozal.

Luego está la idiotez de Java ¡los caracteres no son suficientes para contener un personaje! ¿Qué demonios están pensando? Por eso los llamo charchars. Tienes que escribir un código como este si esperas que funcione Derecha:

private static void say_physical(String s) { 
    System.out.print("U+");
    for (int i = 0; i < s.length(); i++) {
        System.out.printf("%X", s.codePointAt(i));
        if (s.codePointAt(i) > Character.MAX_VALUE) { i++; }  // UG!
        if (i+1 < s.length()) { System.out.printf("."); }
    }
}

Y quién ¿alguna vez piensa hacer eso? Al lado de nadie.

¿Cuántos caracteres hay en "\uD83D\uDCA9"? ¿Uno o dos? Depende de cómo los cuentes. El motor de expresiones regulares, por supuesto, trata con caracteres lógicos, por lo que un patrón ^.$ Tendrá éxito y un patrón ^..$ Fallará. Esta locura se demuestra aquí:

String { U+61, "\u0061", "a" }  =~ /^.$/ => matched.
String { U+61, "\u0061", "a" }  =~ /^..$/ => failed.
String { U+61.61, "\u0061\u0061", "aa" }  =~ /^.$/ => failed.
String { U+61.61, "\u0061\u0061", "aa" }  =~ /^..$/ => matched.
String { U+DF, "\u00DF", "ß" }  =~ /^.$/ => matched.
String { U+DF, "\u00DF", "ß" }  =~ /^..$/ => failed.
String { U+DF.DF, "\u00DF\u00DF", "ßß" }  =~ /^.$/ => failed.
String { U+DF.DF, "\u00DF\u00DF", "ßß" }  =~ /^..$/ => matched.
String { U+3C3, "\u03C3", "σ" }  =~ /^.$/ => matched.
String { U+3C3, "\u03C3", "σ" }  =~ /^..$/ => failed.
String { U+3C3.3C3, "\u03C3\u03C3", "σσ" }  =~ /^.$/ => failed.
String { U+3C3.3C3, "\u03C3\u03C3", "σσ" }  =~ /^..$/ => matched.
String { U+1F4A9, "\uD83D\uDCA9", "????" }  =~ /^.$/ => matched.
String { U+1F4A9, "\uD83D\uDCA9", "????" }  =~ /^..$/ => failed.
String { U+1F4A9.1F4A9, "\uD83D\uDCA9\uD83D\uDCA9", "????????" }  =~ /^.$/ => failed.
String { U+1F4A9.1F4A9, "\uD83D\uDCA9\uD83D\uDCA9", "????????" }  =~ /^..$/ => matched.

Esa idiotez se debe a que no puede escribir el \u1F4A9 Perfectamente razonable, ni, por supuesto, recibe ninguna advertencia de que no puede hacerlo. Simplemente hace lo incorrecto.

Stoooopid.

Mientras lo hacemos, toda la notación \uXXXX Está congénitamente con muerte cerebral. El preprocesador Java ( sí, me escuchaste) llega antes que Java lo hace, así que estás prohibido de escribir cosas perfectamente razonables como "\u0022", porque para el momento Java ve eso, su preprocesador lo ha convertido en """, por lo que pierde. Oh, espera, notif is in a regex! Así que puedes usar "\\u0022" bien.

Riiiiiiiight!

¿Sabía que no hay manera en Java para hacer una llamada isatty(0)? Ni siquiera se le permite pensar tales pensamientos. No sería bueno para usted.

Y luego está toda la abominación classpath.

¿O el hecho de que no hay forma de especificar la codificación de su Java archivo fuente en ese mismo archivo fuentepara que no lo pierda? Una vez Una vez más, exijo saber: QUÉ DEMONIOS PENSARON‽‽‽

¡Detén la locura! No puedo creer que la gente aguante esta basura. Es una broma completa. Prefiero ser un saludador de Walmart que sufrir las hondas y flechas de indignante Java locura. Todo está roto, y no solo no pueden arreglarlo, sino que ganaron 'tarreglarlo.

Esto por las mismas personas astutas que se enorgullecían de un lenguaje que hacía ilegal tener una función printf(). Gee, esoseguro funcionó muy bien, ¿no fue así?

Puros numbskulls. Los golpes de perra son demasiado amables para ellos. Si quisiera programar en ensamblador, lo haría. Este no es un lenguaje rescatable. El emperador no tiene ropa.

Lo odiamos Lo odiamos para siempre. Déjalo morir morir morir!

18
tchrist

Sintaxis de la declaración del puntero de función en C y C++:

(int)(*f)(int, int);

Eso declara un puntero de función llamado f cuyo puntero puede tomar dos ints y devolver un int.

Preferiría una sintaxis como esta:

f: (int, int) => int

Digamos que desea declarar un puntero de función g cuyo puntero puede tomar dos ints y una función de int y int a int, y devuelve un int.

Con notación C o C++, lo declararías como:

(int)(*g)(int, int, int(int, int));

Con la notación propuesta anteriormente, se puede declarar lo mismo que:

g: (int, int, (int, int) => int) => int

Último es mucho más intuitivo IMO.


Aparte: el lenguaje de programación llamado OOC corrige esta sintaxis (y varios otros problemas sintácticos en C y C++). Consulte su página de inicio aquí .

16
missingfaktor

Verbosidad en Java.

es decir:

public static final int 
14
OscarRyz

\ we\wouldnt\fix\our\parser sintaxis de espacio de nombres en PHP

La sintaxis no solo es fea, sino que genera confusión cuando los desarrolladores más nuevos tienen que pensar en los espacios de nombres en las cadenas. (PHP interpola barras invertidas en cadenas de comillas dobles como secuencias de escape. Intentando representar un espacio de nombres como \you\should\never\do\that en una cadena de comillas dobles en lugar de una cadena de comillas simples dará lugar a nuevas líneas, pestañas y desastres).

12
mario

VBScript no tiene operadores lógicos

A diferencia de casi todos los lenguajes sensibles, VBScript utiliza operadores bit a bit en lugar de operadores lógicos. ¿Qué significa esto en la práctica? Bueno, como Eric Lippert señala :

If Blah = True Then Print "True!" Else Print "False!"

y

If Blah Then Print "True!" Else Print "False!"

nO son lo mismo en VBScript!

Sin embargo, lo que es peor, esto significa que no hay una evaluación de cortocircuito en VBScript, por lo que la siguiente declaración bloqueará su programa si Blah es Nothing

If (Not Blah Is Nothing) And (Blah.Frob = 123) Then
...

Así es, VBScript evaluará ambas partes de la comparación AND, ¡incluso si la primera es falsa! Deja que se hunda...

9
Dan Diplo

Desprecio el hecho de que las llaves pueden ser opcionales después de una declaración if/while/for.

Especialmente cuando veo código como,

if (...)
    for(...)
        ... One line of stuff ...

Por favor, solo ponga los frenos y termine con eso.

9
Jim A

EDITAR: Después de la discusión en los comentarios, decidí actualizar esta respuesta para explicarme mejor.

Realmente odio el aspecto de los punteros de función en C. Por lo general, cualquier declaración de variable parece una Tupla de: type varname; Por otro lado, las declaraciones de puntero de función se parecen a una declaración de la función con * antes del nombre de la función. Puedo aceptar esto como una descripción de un tipo de puntero, pero en C esto declara tanto el tipo como el nombre de una variable de ese tipo. Esto me parece inconsistente porque las declaraciones de tipo son distintas de las declaraciones de variables. struct myStruct{int X; int Y;} solo define un tipo, no define una variable llamada myStruct. Del mismo modo, no veo ninguna razón para que las declaraciones de tipo y las declaraciones de variables se agrupen en una declaración atómica en punteros de función, ni aprecio la desviación de la type varname; estructura.

Alguien señaló que es consistente con alguna regla espiral, y ese puede ser el caso, pero la marca de una buena sintaxis es que se explica por sí misma y su lógica interna es obvia. La regla espiral no es obvia de ninguna manera.

7
EpsilonVector

Argumentos de entrada/salida. Estoy a favor de los argumentos (bueno que soy), los argumentos también están bien, pero un argumento que debe transmitir estos dos estados me molesta.

Lo que apunto aquí son funciones que toman la entrada de un parámetro y luego sobrescriben esa entrada con alguna salida. Está bien pasar un objeto por referencia para actualizarlo. Pero, principalmente para los tipos primitivos, tomar un objeto, usarlo y luego cambiarlo por completo, no es correcto para mí. No debe cambiar el significado del argumento a través de un inout.

6
zneak

Semicolones en VBScript - o la falta de ellos

Paso todo el día trabajando en idiomas que esperan punto y coma al final de cada línea. Agregue uno al final de la línea en VBScript y su código ya no se ejecutará.

6
Nathan Taylor

Declaraciones de matriz en C y C++.

Normalmente, una declaración de variable tiene el formato type variable_name. Puede leer fácilmente esas declaraciones de izquierda a derecha. Pero int foo[size] al principio parece que está declarando foo como int, y luego lees más y ves ese tipo de "conjunto de enteros". int[size] foo lee mucho mejor.

Y también odio cuando los programadores declaran punteros como este por una razón similar: int *foo. Por alguna razón que no he descubierto, esa es la forma típica que está escrita.

6
Jacob

Parametrización redundante en Java:

HashMap<String,HashMap<String,String>> foo = new HashMap<String, HashMap<String, String>>();

¿Qué otro tipo de parametrización puede tener el compilador thinkfoo?

5
Hoa Long Tam

Como la gente ya se ha quejado de = vs. ==, permítanme señalar una alternativa mucho peor. PL/tuve ambos := y =, pero cuando algo era "obviamente" una tarea, te permitiría usar = para hacerlo. Utilizando := le permite forzar que algo sea una tarea en una situación en la que el compilador lo interpretaría como una comparación.

Desafortunadamente, el compilador no siempre decidió las cosas de la manera que cabría esperar. Considere solo un ejemplo obvio:

A = B = 0;

Ahora, para la mayoría de las personas familiarizadas con la mayoría de los lenguajes "ordinarios", el significado de esto es bastante obvio: asignar 0 a A y B. PL/I es solo un poco ... diferente. Por razones conocidas solo por los diseñadores (locos) del lenguaje, el primer = se interpreta como una asignación, pero la segunda = se interpreta como una comparación. Por lo tanto, esto compara B con 0, y luego asigna el resultado de esa comparación a A (siguiendo la convención de estilo C que "falso" da como resultado 0 y "verdadero" en 1).

Entonces, si B era 0, entonces A se convierte en 1. De lo contrario, A se convierte en 0. En otras palabras, en lugar de asignar el mismo valor a A y B, esto realmente garantiza que A no puede tener el mismo valor como B.

En pocas palabras: aunque el estilo C/C++/PHP inicialmente parece como un dolor, la alternativa es mucho peor1.

1Bueno, técnicamente, hay otra alternativa: estilo Pascal, donde = siempre significa comparación y asignación siempre requiere :=. Después de usar eso por un tiempo, es bastante obvio (al menos para mí) que la asignación es bastante más común que la comparación que si va a requerir "cosas" adicionales para desambiguar a los dos, definitivamente debe mantener las tareas limpias y simples y requieren el "grunge" adicional en las comparaciones, no al revés.

5
Jerry Coffin

La construcción for ... in en JavaScript y la construcción foreach en PHP cuando se repite sobre matrices. Ambas hacen que sea más fácil escribir errores que el código correcto.

3
Joeri Sebrechts

Perl

  1. Deseo que Perl me deje escribir if($x < 10) do_something();. Por el momento, debe escribir eso como do_something() if($x < 10); o como if($x < 10) { do_something(); }.
3
Gaurav

reinterpret_cast<unsigned long> en c ++. Esta operación es útil para tratar con API extranjeras y garantizar la precisión numérica, ¿por qué debería ser tan difícil de escribir y tan feo de ver?

3
AShelly

Punteros de matrices o matrices de punteros en C/C++. Todavía estoy confundido acerca de estos.

2
Casebash

El hecho de que Python se basa en el formato de texto.

2
Ashalynd

Verbosidad en Java clases anónimas. Con suerte se solucionará pronto.

1
alex

structPointer->member en C/C++. Puede ser bueno para leer el código de otra persona, pero no me gusta. Dos personajes en lugar de uno ... ¡qué desperdicio de espacio!

0

Sé que esta es una pregunta anterior, pero ¿cómo es que nadie mencionó?.

CÓDIGO NUGGETS

<% %> <- Regular

<%= %> <- Estilo Buffalo

<%:%> <- extra crujiente

0
MVCylon

REGEX/preg_match() en PHP

En primer lugar, su sintaxis completamente diferente de la que utiliza PHP. Mientras que la función preg_match() emula la expresión regular de manera excelente, tengo que cambiar completamente mi modo de pensar para trabajar con ella.

En segundo lugar, es simplemente una obscurificación la mitad del tiempo. Por lo general, tengo que sacar literalmente un bloc de notas y descubrir que WTF está haciendo la mitad del tiempo.

Además, programo en PHP, no en Perl. Si me gustara Perl, programaría en Perl. (no, señor, no me gusta)

Para empeorar las cosas, con el nuevo formato delimitador PCRE, prácticamente puede usar cualquier carácter, lo que incluye tener que escapar de ese mismo carácter anidado, haciendo que el patrón aún más oscuro.

Claro, es genial si quieres ser críptico ... o incluso eficiente ... pero demonios la cantidad de tiempo que normalmente se pierde para realizar tareas simples.

0
Talvi Watia

Código multilínea Scala entre paréntesis

Por ejemplo:

class Foo(
         val bar: String,
         val baz: Int,
         val bing: String,
         val bong: Boolean
 ) extends Model {
   // body here
 }

Lo que realmente obtienes de él es excelente. Genera el constructor y los captadores y establecedores para usted. Pero seguro que es feo y rompe todos mis modelos mentales sobre cómo sangrar código y básicamente me hace sentir como si estuviera en una especie de sándwich extraño con Java por un lado y LISP por el otro (Oh, espera ... ese es más bien el punto de Scala.)

0
Tom Morris