Característica más extraña del lenguaje


974

¿Cuál es, en su opinión, la característica de lenguaje más sorprendente, extraña, extraña o realmente "WTF" que ha encontrado?

Por favor, solo una función por respuesta.


55
@gablin Creo que si combinara delimitadores LISP con expresiones regulares PERL utilizando el análisis de JavaScript, cubriría el 90% del WTF ...
Talvi Watia

Respuestas:


1859

En C, las matrices se pueden indexar así:

a[10]

Lo cual es muy común.

Sin embargo, la forma menos conocida (¡que realmente funciona!) Es:

10[a]

lo que significa lo mismo que el anterior.


758
eso es porque un [10] significa * (a + 10) ... y 10 [a] significa * (10 + a) :)
Michel Gokan

77
No olvides "Hola Mundo" [i]. O yo ["Hello World"]
Richard Pennington

167
O, más útil, "0123456789abcdef" [x y 0xf]
Varilla de nivel

17
@frunsi: Siempre funciona como se esperaba. La suma de punteros no es lo mismo que la suma de enteros simples en las direcciones. Es conmutativo, sin importar el tamaño del tipo en cuestión.
R. Martinho Fernandes

12
@mcv: a [10] es lo mismo que "* (a + 10)", donde la expresión "a + 10" es aritmética de puntero (y como a es un corto, en su ejemplo, a + 10 significa 'comenzar en dirección de a, y mover 10 cortos, es decir, 20 bytes '). La expresión 10 [a] se interpreta como "* (10 + a)", donde "10 + a" también es aritmética de puntero y se trata exactamente de la misma manera.
Edan Maor

1292

En JavaScript:

 '5' + 3 gives '53'

Mientras

 '5' - 3 gives 2

81
Recuerdo cuando comencé a usar JavaScript usando este tipo de técnica para agregar números en cadenas: "111" - - "222" da 333 mientras que "111" + "222" da "111222".
Callum Rogers

112
+para la concatenación de cuerdas es horrible
Matteo Riva

416
+ para concat no es el problema. Mecanografía débil es.
FogleBird

270
@FogleBird Ninguno de los dos es realmente el problema. Es solo la combinación de los dos con reglas de coerción inconsistentes.
TM.

70
Básicamente, + es concat cuando hay una cadena involucrada. ¿Por qué no pueden codificar algo como '123456' - 456 = '123'? Eso puede ser interesante.
Jimmie Lin

872

En JavaScript, la siguiente construcción

return
{
    id : 1234,
    title : 'Tony the Pony'
};

retornosundefined es un error de sintaxis debido a la inserción punto y coma implícita disimulado en la nueva línea después return. Sin embargo, lo siguiente funciona como es de esperar:

return {
    id : 1234,
    title : 'Tony the Pony'
};

Peor aún, este también funciona (al menos en Chrome):

return /*
*/{
    id : 1234,
    title : 'Tony the Pony'
};

Aquí hay una variante del mismo problema que no produce un error de sintaxis, simplemente falla en silencio:

return
    2 + 2;

225
La inserción de punto y coma es una de las partes más malvadas de JavaScript.

230
Siempre tiene problemas cuando diseña funciones de lenguaje en el supuesto de que sus usuarios serán en su mayoría idiotas.
Rob Van Dam

8
De hecho, tuve ese problema, al ser desarrollador de C #, puse la llave en una nueva línea. Me tomó horas darme cuenta de cuál era el problema. ¡Incluso cuando resolví el problema, no supe cuál era el problema hasta que leí tu respuesta!
Fedor Hajdu

24
Nick Retallack: Debido a que, debido a la sintaxis de punto y coma y comillas tipo R de JavaScript, no es evidente en absoluto que las nuevas líneas sean significativas.
Tamas Czinege

19
Si se supone que no debe usar el estilo C al programar en JavaScript, entonces fue bastante perverso de los diseñadores del lenguaje JavaScript elegir una sintaxis de estilo C.
Ryan Lundy

795

Tabla de verdad de JavaScript:

''        ==   '0'           // false
0         ==   ''            // true
0         ==   '0'           // true
false     ==   'false'       // false
false     ==   '0'           // true
false     ==   undefined     // false
false     ==   null          // false
null      ==   undefined     // true
" \t\r\n" ==   0             // true

Fuente: Doug Crockford


237
Lo bueno es que Javascript tiene el operador ===, entonces.
Anónimo el

65
Entonces, ¿para qué ==sirve a los ojos del diseñador de idiomas?
Chris S

137
Gente confusa
Javier

123
Sería bueno ==tener el significado de ===, y luego había otro operador, algo así ~=permitía la coerción de tipo.
TM.

18
@Otto En realidad, dado que nos estamos escapando, su ejemplo muestra que == no es simétrico. Por el momento, no he visto cómo se especificaría la conmutatividad para una relación binaria.
PeterAllenWebb

660

Trígrafos en C y C ++.

int main() {
   printf("LOL??!");
}

Esto se imprimirá LOL|porque el trigrafo ??!se convierte a |.


71
¡Rápido! ¡Cuéntales a todos los programadores de C / b!
Esteban Küber

235
Los trigraphs son increíbles, porque puedes estar seguro de que nadie, nunca, sabrá qué. significará de Google sin saber el nombre ya.
zaratustra

56
Los trígrafos están deshabilitados por defecto en GCC.
Sastanin

360
Estos le permiten usar el "operador WTF": (foo ()! = ERROR) ??! ??! cerr << "Se produjo un error" << endl;
user168715

57
Los trigrafos eran un mal necesario cuando se introdujeron. Algunas plataformas simplemente no incluían ciertos caracteres clave para el lenguaje, por lo que se trataba de "trigrafos" o "no se puede tener un compilador de C período-fin-de-declaración, así que use el ensamblador". Consulte la descripción de Stroustrup en "El lenguaje de programación C ++".
Euro Micelli

573

Diversión con el boxeo automático y el caché de enteros en Java:

Integer foo = 1000;
Integer bar = 1000;

foo <= bar; // true
foo >= bar; // true
foo == bar; // false

//However, if the values of foo and bar are between 127 and -128 (inclusive)
//the behaviour changes:

Integer foo = 42;
Integer bar = 42;

foo <= bar; // true
foo >= bar; // true
foo == bar; // true

Explicación

Un vistazo rápido al código fuente de Java mostrará lo siguiente:

/**
 * Returns a <tt>Integer</tt> instance representing the specified
 * <tt>int</tt> value.
 * If a new <tt>Integer</tt> instance is not required, this method
 * should generally be used in preference to the constructor
 * {@link #Integer(int)}, as this method is likely to yield
 * significantly better space and time performance by caching
 * frequently requested values.
 *
 * @param  i an <code>int</code> value.
 * @return a <tt>Integer</tt> instance representing <tt>i</tt>.
 * @since  1.5
 */
public static Integer valueOf(int i) {
    if (i >= -128 && i <= IntegerCache.high)
        return IntegerCache.cache[i + 128];
    else
        return new Integer(i);
}

Nota: el valor IntegerCache.high predeterminado es a 127menos que lo establezca una propiedad.

Lo que sucede con el auto boxing es que tanto foo como bar el mismo objeto entero recuperado de la memoria caché a menos que se cree explícitamente: por ejemplo foo = new Integer(42), al comparar la igualdad de referencia, serán verdaderas en lugar de falsas. La forma correcta de comparar el valor entero es usar.equals;


31
Me tomó un par de segundos para ver por qué ... Java debe mantener un conjunto de instancias de Integer para valores entre -128 y 128, de lo contrario, asigna un nuevo Integer, ¿verdad?
Mike Akers

18
sin embargo, tenga en cuenta que si especifica un nuevo número entero (42) no utilizará la instancia del grupo, por lo que foo == bar se evaluará como falso
z -

10
Si es posible, siempre uso ints en lugar de Integers, pero si tuviera que usar Integers por alguna razón, ¿debería usar .equals () en lugar de ==?
MatrixFrog

246
Estoy tan contento de ser un programador de C #.

87
@Will: C # tiene algunas trampas muy similares. Ver blogs.msdn.com/jmstall/archive/2005/03/06/386064.aspx
spookylukey

373

Citando a Neil Fraser (mira al final de esa página),

try {
    return true;
} finally {
    return false;
}

(en Java, pero el comportamiento es aparentemente el mismo en JavaScript y Python). El resultado se deja como ejercicio para el lector.

EDITADO: Mientras estemos en el tema, considere también esto:

try {
    throw new AssertionError();
} finally {
    return false;
}

42
+1. Por alguna razón, me parece hilarante y no puedo dejar de reír.
outis

153
Afortunadamente, C # no permite tanta locura ...Control cannot leave the body of a finally clause
Richard Ev

64
Esto vuelve, falso, ¿verdad? Puede parecer un WTF (y posiblemente sea uno), pero vivo según la regla: finalmente siempre gana, a menos que bloquee la máquina antes.
Michael Stum

28
Para ser justos, culpo a la agradable explicación de TDWTF de recordar que finalmente siempre gana a menos que tire del cable de alimentación: thedailywtf.com/Articles/My-Tales.aspx
Michael Stum

22
No estoy seguro de qué debería devolver el código en este caso. Pero estoy absolutamente seguro de que no se debe poner returnen la finallycláusula.
jfs

325

APL (aparte de TODO), la capacidad de escribir cualquier programa en una sola línea.

Ej . Juego de la vida de Conway en una línea en APL :

texto alternativo http://catpad.net/michael/APLLife.gif

Si esa línea no es WTF, ¡entonces nada lo es!

Y aqui hay un video


19
Amo el APL. ¡Ah, las alegrías de pasar una tarde entera escribiendo media línea de código! Lo primero que haré cuando obtenga un teclado donde pueda programar qué letras se muestran es volver a familiarizarme con APL.
Daniel C. Sobral

24
Parece un idioma para los griegos.
Esko

45
@Erik: Hay alegría de escribir código que se trata únicamente de lo que quieres y no de cómo llegar allí. De expresar su código como una sola expresión. Es como el último corte de katana perfecto. Por supuesto, en una pelea real preferiría tener un arma.
Daniel C. Sobral

77
@Daniel: Pasas una tarde entera para escribir una línea de código ... y una semana entera para leer una línea de código. ;-)
Jürgen A. Erhard

93
APL sería increíble de ver en una película de acción de ciencia ficción. Me imagino a alguien sentado en un terminal de tres colores murmurando "Cambie la forma del vector de misiles enemigos ... transponga ... logaritmo pi veces ... ¡suba de nivel y ejecute!" seguido de explosiones y vítores.
Joey Adams

321

Las cosas extrañas para las plantillas C ++ se pueden usar, lo que se demuestra mejor con "Literales analógicos multidimensionales" que usan plantillas para calcular el área de formas "dibujadas". El siguiente código es válido en C ++ para un rectángulo de 3x3

#include"analogliterals.hpp"
using namespace analog_literals::symbols;

          unsigned int c = ( o-----o
                             |     !
                             !     !
                             !     !
                             o-----o ).area;

O, otro ejemplo con un cubo 3D:

  assert( ( o-------------o
            |L             \
            | L             \
            |  L             \
            |   o-------------o
            |   !             !
            !   !             !
            o   |             !
             L  |             !
              L |             !
               L|             !
                o-------------o ).volume == ( o-------------o
                                              |             !
                                              !             !
                                              !             !
                                              o-------------o ).area * int(I-------------I) );

18
Si bien los literales analógicos de Eelis son geniales, ¿son una característica extraña del lenguaje , o simplemente una forma extraña de usar una característica?

85
El verdadero WTF será el error del compilador generado por uno de los que está mal formado.
Andrew McGregor

66
Qué enfermo es eso ... despertarme nuevamente cuando hay una versión de AnalogLiterals que admite girar el literal alrededor del eje X, Y y Z en Eclipse ... ahora eso le daría a la "programación visual" un nuevo significado real.
TheBlastOne

2
¿Importa el orden de las o y las L y |?
Ming-Tang

44
El orden es importante, ya que las plantillas hacen un uso creativo de la sobrecarga del operador. (No haga esto con código real, el mal uso de los operadores hace que el código sea difícil de leer)
josefx

292

Las muchas variables incorporadas de Perl:

  • $#- No es un comentario!
  • $0, $$y $?- al igual que las variables de shell con el mismo nombre
  • , $&y $'- variables de coincidencia extrañas
  • $"y $,- variables extrañas para separadores de campo de lista y salida
  • $!- errnocomo un número pero strerror(errno)como una cadena
  • $_- la variable sigilo, siempre utilizada y nunca vista
  • $#_ - número de índice del último argumento de subrutina ... tal vez
  • @_ - los (no) nombres de la función actual ... tal vez
  • $@ - la última excepción planteada
  • %:: - la tabla de símbolos
  • $:, $^, $~, $-, Y $=- algo que ver con los formatos de salida
  • $.y $%- número de línea de entrada, número de página de salida
  • $/y $\- separadores de registros de entrada y salida
  • $| - controlador de buffer de salida
  • $[- cambie su base de matriz de 0 a 1 a 42: ¡WHEEE!
  • $}- Nada en absoluto, ¡curiosamente!
  • $<, $>, $(, $)- UID y GID reales y efectivos
  • @ISA - nombres de las superclases directas del paquete actual
  • $^T - tiempo de inicio del script en segundos de época
  • $^O - nombre del sistema operativo actual
  • $^V - ¿Qué versión de Perl es esta?

Hay mucho más de donde vinieron esos. Lea la lista completa aquí .


83
La $[variable es la más malvada de todas.
Brad Gilbert el

24
Definitivamente lo agradecería si Perl 6 fuera algo que pudiera codificar sin tener que verificar perldoc perlvarcada cinco segundos. (Aunque confieso que la mitad del tiempo lo reviso pensando "Sé que hay una variable especial que puede hacer esto por mí, simplemente no recuerdo cuál ..." = P)
Chris Lutz

17
El problema use English;es que afecta el rendimiento de RegExp. No estoy inventando esto. perldoc.perl.org/English.html#PERFORMANCE
Dave Webb

13
@Dave: no es un problema debido a la opción -no_match_vars en la página que ha vinculado. @Brad: $ [es TAN malvado. La intención detrás de esto es malvada, sí, ¡pero tampoco funciona! @Artem: from perlvar "Los identificadores de Perl que comienzan con dígitos, caracteres de control o signos de puntuación están exentos de los efectos de la declaración del paquete y siempre están obligados a estar en el paquete principal; también están exentos de errores estrictos 'vars'". Entonces eso significa que @ $ se crearía y se asignaría sin error incluso bajo restricción. Ugh!
rjh

44
@Brian: ¿Cómo propones aprender la sintaxis cuando la documentación oficial en sí misma establece que hay circunstancias en las que el intérprete de Perl adivina heurísticamente lo que significa una secuencia de caracteres? Por ejemplo /$foo[bar]/, en , ¿es la [bar]parte una clase de caracteres o un subíndice de la matriz @foo? Grep perldata por la aterradora respuesta.
j_random_hacker

289

Manejo de PHP de valores numéricos en cadenas . Vea esta respuesta anterior a una pregunta diferente para obtener detalles completos pero, en resumen:

"01a4" != "001a4"

Si tiene dos cadenas que contienen un número diferente de caracteres, no pueden considerarse iguales. Los ceros a la izquierda son importantes porque son cadenas y no números.

"01e4" == "001e4"

PHP no le gustan las cadenas. Está buscando cualquier excusa que pueda encontrar para tratar sus valores como números. Cambie ligeramente los caracteres hexadecimales en esas cadenas y de repente PHP decide que ya no son cadenas, son números en notación científica (a PHP no le importa que use comillas) y son equivalentes porque los ceros iniciales se ignoran para los números. Para reforzar este punto, encontrará que PHP también se evalúa "01e4" == "10000"como verdadero porque estos son números con valores equivalentes. Este es un comportamiento documentado, simplemente no es muy sensato.


56
Solo usa === y! ==. Que debe usarse de todos modos, a menos que se necesite una comparación de tipos sueltos.
Dykam

14
@Dykam, si sigues el enlace a la respuesta completa, verás que he abordado el uso del operador ===.
Dan Dyer

18
¡Golpes débiles de mecanografía nuevamente!
gillonba

43
Siempre supe que PHP era un pecado. Hasta ahora no me daba cuenta de que era un pecado imperdonable: D
Thomas Eding

2
Deben usar personas tecnológicas para usar === en cualquier libro de programación o tutorial. Nota agregada: en una aplicación PHP mal escrita pude proporcionar como contraseña todo lo que se analizó como el mismo número.
Pepijn

282

Vamos a votar por todos los idiomas (como PL / I) que intentaron eliminar las palabras reservadas.

¿Dónde más podrías escribir legalmente expresiones tan divertidas como:

IF IF THEN THEN = ELSE ELSE ELSE = THEN

( IF, THEN, ELSESon nombres de variables)

o

IF IF THEN THEN ELSE ELSE

( IFes una variable THENy ELSEson subrutinas)


1
@quark: esa es una respuesta separada a esto! ;) ... (y sí, puede programar con inglés, simplemente impleméntelo como .ppt para otros desarrolladores.;)
Macke

28
@RoadieRich un grupo de búfalos no es explícitamente de Buffalo, son búfalos indescriptibles.
Jürgen A. Erhard

18
John, donde James había tenido, había tenido, había tenido, había tenido un mejor efecto en el maestro.
GameFreak

44
El otro día vi algunos fabricantes de letreros afuera de una fábrica de helados Ben and Jerrys. Critiqué su trabajo, les dije que no había suficiente espacio entre ben y and y and y jerrys.
Tom Gullen

99
Tal vez sea necesario para futuros programas temporales. SI ENTONCES = AHORA && DONDE = AQUÍ ENTONCES CUANDO = LUEGO AHORA MÁS = EN OTRA PARTE
Kelly S. French

282

Es bueno conocer la 'característica' de conversión octal de JavaScript:

parseInt('06') // 6
parseInt('07') // 7
parseInt('08') // 0
parseInt('09') // 0
parseInt('10') // 10

Más detalles aquí .


6060
¡Me quedé atrapado en un error que todos los números funcionaron excepto 8 y 9! Se estaba volviendo loco! Gracias Brian!
Faruz

10
@Yada ¿No te refieres a octal? Hexadecimal es 0x.
luiscubal

48
Y es por eso que parseInt toma un argumento adicional (opcional) :).
LiraNuna

10
el 0 inicial significa número octal. como 8 no es un dígito octal válido, el resultado debe ser 0.
devio

22
... y parseInt ('010') -> 8 solo para confundirte.
Richard Gadsden

213

El dispositivo de Duff en C!

En C uno puede entrelazar un do / while con una instrucción switch. Aquí un ejemplo de una memcpy usando este método:

void duff_memcpy( char* to, char* from, size_t count ) {
    size_t n = (count+7)/8;
    switch( count%8 ) {
    case 0: do{ *to++ = *from++;
    case 7:     *to++ = *from++;
    case 6:     *to++ = *from++;
    case 5:     *to++ = *from++;
    case 4:     *to++ = *from++;
    case 3:     *to++ = *from++;
    case 2:     *to++ = *from++;
    case 1:     *to++ = *from++;
            }while(--n>0);
    }
}

99
El dispositivo de Duff es probablemente una buena razón para que la declaración de cambio no tenga una interrupción por defecto ;-) Sin embargo, todavía no vi ningún otro buen uso del interruptor y el bucle entrelazados, pero probablemente haya uno. Oh, espera, sí, hay otro uso: corutinas y prototipos.
Frunsi

16
@frunsi: "El dispositivo de Duff es probablemente una buena razón para que la declaración de cambio no tenga una interrupción por defecto" - Siempre haga que el caso común sea el predeterminado. No diría exactamente que este es el caso común ...
BlueRaja - Danny Pflughoeft

66
@mcv probablemente sea más fácil si intenta leerlo como código de ensamblaje, es decir, whileal final es un (condicional) de JMPregreso al do, lo que explica por qué puede omitirlo doy aún terminar en el bucle.
wds

14
Tenga en cuenta que el dispositivo de Duff generalmente produce un código PEOR que la declaración de bucle normal para los compiladores modernos, que saben cómo (mejor) desenrollar el bucle de lo que puede hacer a mano.
Billy ONeal

37
@frunsi: Duff mismo, al publicarlo, afirmó algo como esto: "Esto definitivamente proporciona un argumento en la discusión sobre si el cambio debería fallar por defecto, pero no estoy seguro de si el argumento es a favor o en contra".
SF.

204

Algol pasa por nombre (ilustrado usando la sintaxis C):

int a[3] = { 1, 2, 3 };
int i = 1;

void f(int j)
{
    int k;
    k = j;  // k = 2
    i = 0;
    k = j;  // k = 1 (!?!)    
}

int main()
{
    f(a[i]);
}

33
Si lo piensas, en realidad tiene algún tipo de sentido retorcido
RCIX el

90
Este es el último "pase por referencia".
Dykam

3
Sin embargo, es posible en Scala ( def f(j : => int))
Dario

10
¿Entonces esto es algo así ... template<typename T> struct by_name { virtual operator T&() = 0; }; void f(by_name<int> j) { ... } int main() { f(struct : by_name<int> { operator int&() { return a[i]; } }); }?
Simon Buchan

2
En realidad es bastante sencillo: genera un pequeño fragmento de código (generalmente llamado "thunk", de ahí mi juego de palabras anterior) que calcula la dirección resultante de la expresión, en este caso & a [i]. Se pasa un puntero a esta función a la función llamada, que luego la usa para calcular la dirección actual cada vez que se accede al parámetro.
Richard Pennington el

189

En Python:

>>> x=5
>>> 1<x<10
True
>>> 1<x<3
False

No es un WTF, sino una característica útil.


176
Ojalá todos los demás idiomas tengan esta característica
vava

32
Al igual que con casi todas las características interesantes de Python, parece que Guido acaba de ALGOLIZAR la sintaxis de una característica genial de Lisp. :-)
Ken

44
Geoffrey, es una característica, y (10 > 5 > 1) != ((10 > 5) > 1)en Python.
sastanin

18
Además, evalúa solo una vez, por lo que (funct_a(5)+5 > b > funct_a(5))solo llama funct_a(5)una vez. ¡Es una GRAN característica!
Khelben

57
@Khelben: No, funct_ase llamará dos veces en ese ejemplo. Sin b > funct_a(5) > cembargo, solo se llamará una vez, a diferencia de b > funct_a(5) and funct_a(5) > c.
Baffe Boyois

189

En Java:

int[] numbers() {
  return null;
}

Se puede escribir como:

int numbers() [] {
  return null;
}

23
¡Guauu! ¡Ojalá pudiera ser una mosca en la pared cuando se diseñó esa sintaxis de matriz!
Adam Paynter el

29
Odio decir esto, pero el WTF es una extensión consistente del sistema de tipo C. Si se permitiera a las funciones de C devolver matrices, así sería. El más agradable es una violación de consistencia para hacerlo más legible. Al igual que "const char * var" vs "char const * var".
Gordon Wrigley

15
@ Adam - En realidad, tiene sentido cuando consideras que la declaración de variable permite de manera similar tanto "int stuff []" como "int [] stuff". Simplemente dejan que las mismas reglas funcionen para la declaración del método.
Brandon Yarbrough

2
@lImbus: En realidad, const T*y T const*son equivalentes, es lo T* constque contrasta el puntero. Además, odio sin fuentes.
Simon Buchan

3
Después de todo, numbers()[2]es una declaración legal.
badp

184

INTERCAL es probablemente el mejor compendio de características de lenguaje más extrañas. Mi favorito personal es la declaración COMEFROM que es (casi) lo opuesto a GOTO.

COMEFROM es aproximadamente lo opuesto a GOTO en que puede llevar el estado de ejecución desde cualquier punto arbitrario del código a una declaración COMEFROM. El punto en el código donde ocurre la transferencia de estado generalmente se da como un parámetro para COMEFROM. Si la transferencia se realiza antes o después de la instrucción en el punto de transferencia especificado depende del idioma utilizado. Dependiendo del lenguaje utilizado, varios COMEFROM que hacen referencia al mismo punto de partida pueden ser inválidos, no deterministas, ejecutarse en algún tipo de prioridad definida, o incluso inducir una ejecución paralela o concurrente de otro modo como se ve en la Intercal roscada. Un ejemplo simple de una declaración "COMEFROM x" es una etiqueta x (que no necesita estar físicamente ubicada cerca de su correspondiente COMEFROM) que actúa como una "puerta trampa". Cuando la ejecución del código alcanza la etiqueta, el control se pasa a la instrucción que sigue al COMEFROM. El efecto de esto es principalmente hacer que la depuración (y la comprensión del flujo de control del programa) sea extremadamente difícil, ya que no hay indicación cerca de la etiqueta de que el control saltará misteriosamente a otro punto del programa.


16
Absolutamente malvado: convierte las etiquetas en GOTO. Suena como una característica de lenguaje que los hackers
rogarían

114
Ok, pero se supone que INTERCAL es divertido, esto no es realmente un "truco" sorprendente. ¡El compilador INTERCAL puede negarse a compilar el programa si no utiliza el PLEASEmodificador con la frecuencia suficiente!
Groo

10
Suena como AOP :)
akuhn

66
Lo que más me sorprende es que en el análisis de requisitos del sistema en el "Mundo de TI comercial", los COMEFROM en realidad se usan en archivos de texto que describen casos de uso. (en serio: algunos analistas aquí retrasaron una migración a toda la empresa a OpenOffice en lugar de a la Oficina de MS porque el primero no pudo hacer referencia a un "resultado" con la granularidad requerida en un enlace)
jsbueno

55
Groo: es peor. Use POR FAVOR con demasiada frecuencia y se niega a compilar su programa porque se está arrastrando (C-INTERCAL requiere que entre el 33% y el 66% de las declaraciones tengan modificadores POR FAVOR).
Vatine

160

No es realmente una característica del lenguaje, sino una falla de implementación: algunos compiladores de Fortran implementaron constantes mediante el uso de un grupo constante. Todos los parámetros fueron pasados ​​por referencia. Si llamó a una función, por ejemplo

f(1)

El compilador pasaría la dirección de la constante 1 en el grupo constante a la función. Si asignó un valor al parámetro en la función, cambiaría el valor (en este caso el valor de 1) globalmente en el programa. Causó un poco de rascarse la cabeza.


124
Oh. Entonces 2+2 puede ser igual 5(¡para valores muy grandes, 2por supuesto!).
Alok Singhal

12
um, ¿qué valor de 2 haría "2 + 2" == "5"? No sé ningún valor entero 2 puede asumir para que eso sea cierto.
Aaron

36
@earlz: sospecho que terminaría como un valor integral, de cualquier patrón de bits. Por otro lado, probablemente podría establecer 5 a 4 de esa manera (por 2+2lo que sería igual 5para valores pequeños de 5).
David Thornley

18
Disculpe, Alok, pero estamos hablando de FORTRAN temprano. No será cierto eso 2 + 2 = 5; eso será un error de sintaxis. Lo que será cierto es 2 + 2 .EQ. 5.
David Thornley

3
En Haskell, el siguiente fragmento se evalúa como 5: "let 2 + 2 = 5 in 2 + 2" :)
Tirpen

153

No sé si se puede considerar una función de lenguaje, pero, en C ++, casi cualquier error de compilación relacionado con las plantillas ofrece una buena cantidad de WTF a muchos programadores de C ++ en todo el mundo a diario :)


15
Está bien, la mayoría del código relacionado con las plantillas ya crea muchos WTF en todo el mundo.
Joris Timmermans

43
Oh ven ahora referencia indefinida a `std :: basic_ostream <char, std :: char_traits <char>> & std :: operator << <std :: char_traits <char>> (std :: basic_ostream <char, std :: char_traits <char> > &, char const *) '¡Es perfectamente legible!
Matt Greer

10
Una vez tuve un error de compilación relacionado con la plantilla que tenía cinco líneas, la más corta de las cuales tenía diecisiete mil caracteres (el clásico error 'no coincide para x', en un programa profundamente diseñado). Esa es la WTF, no la característica en primer lugar, las plantillas son maravillosas.
Andrew McGregor

111
Incluso si no hay ningún error, intente encontrar qué funciones tardan más con su generador de perfiles. Oh mira, esstd::vector<std::pair<int, std::complex>, std::allocator<std::pair<int, std::complex> > >::vector< std::vector<std::pair<int, std::complex>, std::allocator<std::pair<int, std::complex> > >::iterator>(std::vector<std::pair<int, std::complex>, std::allocator<std::pair<int, std::complex> > >::iterator, std::vector<std::pair<int, std::complex>, std::allocator<std::pair<int, std::complex> > >::iterator, std::allocator<std::pair<int, std::complex> >)
rlbond

12
Creo que esto encaja aquí: echa un vistazo a STLFilt en bdsoft.com/tools/stlfilt.html para que la salida sea legible.
miedo el

150

Los muchos espacios de nombres de C:

typedef int i;

void foo()
{
    struct i {i i;} i;
    i: i.i = 3;
    printf( "%i\n", i.i);
}

O con personajes:

typedef char c;

void foo()
{
    struct c {c c;} c;
    c: c.c = 'c';
    printf( "%c\n", c.c);
}

¿Cómo diablos esto compila sin ambigüedades?
Earlz

13
Los identificadores de etiqueta +1 para enumeraciones y estructuras son la parte más confusa de C imho. Pocas personas entienden por qué el lenguaje para escribir defina un puntero a una estructura se ve de la manera que lo hace.
Tadeusz A. Kadłubowski

11
Se compila porque cada uno de esos i tiene un espacio de nombres inequívoco debido al contexto.
Andrew McGregor

149

Diría que todo el espacio en blanco de Python es mi mejor característica de WTF. Es cierto, más o menos te acostumbras después de un tiempo y los editores modernos hacen que sea fácil de tratar, pero incluso después del desarrollo de Python a tiempo completo durante el año pasado, todavía estoy convencido de que fue una mala idea. He leído todo el razonamiento detrás de esto, pero honestamente, se interpone en mi productividad. No por mucho, pero sigue siendo una rebaba debajo de la silla de montar.

editar: a juzgar por los comentarios, algunas personas parecen pensar que no me gusta sangrar mi código. Esa es una evaluación incorrecta. Siempre he sangrado mi código sin importar el idioma y si me veo obligado a hacerlo o no. Lo que no me gusta es que es la sangría la que define en qué bloque está una línea de código. Prefiero delimitadores explícitos para eso. Entre otras razones, encuentro que los delimitadores explícitos hacen que sea más fácil cortar y pegar código.

Por ejemplo, si tengo un bloque con sangría de 4 espacios y lo pego al final de un bloque con sangría de 8 espacios, mi editor (¿todos los editores?) No tengo idea si el código pegado pertenece al bloque de 8 espacios o al exterior bloquear. OTOH, si tengo delimitadores explícitos, es obvio a qué bloque pertenece el código y cómo se debe (re) sangrar; lo hace buscando inteligentemente delimitadores de bloque.

edición 2: algunas personas que proporcionan comentarios parecen pensar que esta es una característica que odio o que creo que hace que Python sea un lenguaje pobre. De nuevo, no es cierto. Si bien no me gusta tanto, eso no viene al caso. La pregunta es sobre la característica más extraña del lenguaje, y creo que esto es extraño, en virtud de que es algo que muy, muy pocos (pero> 0) usan los idiomas.


63
si se interpone en su productividad, entonces su código que no es de Python no puede ser muy legible ...
Tor Valamo

27
¿Qué idioma usaste antes de Python? ¿Cómo pudiste trabajar con otras personas y no sangrar ese idioma? ¿Cómo podría alguien soportar un código no sangrado en cualquier idioma? ¿Trabajaste en una habitación llena de genios que no necesitaban señales visuales en el código fuente?
S.Lott

53
+1 No podría estar más de acuerdo, si mi editor (Emacs) no puede sangrar mi código basado en algo distinto (como llaves / comenzar, finalizar / lo que sea) automáticamente, es realmente una tontería. Casi cualquier refactorización que haría en una función "más grande" puede ser una experiencia realmente mala.
Dmitry

83
Aquí está el trato: con cualquier otro idioma, puedo resaltar un bloque de código y que cualquier editor lo sangra correctamente. Pero debido a que el espacio en blanco ES, por definición, la sangría adecuada, pierde esa habilidad en Python. Por lo tanto, es más difícil mover el código o refactorizar las cosas. Y para la persona que afirma que el OP es la "primera persona en afirmar que fue un problema", bueno, tuve que mantener un código de Python por un tiempo y ahora usaré cualquier lenguaje sobre Python por esta misma razón.
Kendall Helmstetter Gelner

38
No me importa el espacio en blanco en Python. El WTF es que no se aplica de manera consistente. Puede mezclar niveles de sangría y pestañas, siempre que sean consistentes con sus hermanos. Entonces, el primer nivel de sangría puede ser un espacio, y el segundo puede ser dos TAB, y esto no es un error de sintaxis.
ieure

138

Luché un poco sobre esto:

1;

En perl, los módulos deben devolver algo verdadero .


29
Algunos módulos pueden devolver valores basados ​​en operaciones de tiempo de ejecución. Si siempre devuelve verdadero, aún no tiene que ser poco creativo al respecto: returnvalues.useperl.at
Anónimo el

8
Si mi memoria Perl me sirve correctamente, el retorno verdadero de un módulo indica que el módulo se cargó correctamente. Devolver un valor falso significa que algo salió mal y evitaría que el programa se ejecute (si no se detecta).
Barry Brown

Esta es una declaración C válida también, solo que no se devuelve nada.
sigjuice

24
Mark Dominus escribió: "Raramente he usado lo 'Cogito ergo sum';que, como todos saben, es evidentemente cierto en todos los universos posibles. Esto garantiza la máxima portabilidad".
Greg Bacon el

PHP <?=1;?>devuelve 1. <?=true;?>devuelve 1. <?=false;?>devuelve nulo.
Talvi Watia

135

Me sorprende que nadie haya mencionado las 7 construcciones de bucle de Visual Basic .

For i As Integer = 1 to 10 ... Next
While True ... End While
Do While True ... Loop
Do Until True ... Loop
Do ... Loop While True
Do ... Loop Until True
While True ... Wend

Porque pegar un! en frente de su condicional se forma demasiado complicado!


47
Deberían haberlo hecho " Whiley Whend", ya que hay algunas personas que pronuncian la palabra "mientras" con la aproximación velar labializada sin voz. Y, por supuesto, se alinea mejor, y el código que se alinea es agradable.
dreamlax

43
¿Por qué estás actuando tan raro?
Erik Forbes

48
Guau. Me pongo un poco nostálgico cuando lo pienso. La primera vez que usé VB fue cuando tenía 9 años. Soy de Suecia, y no era muy hábil en inglés en ese entonces. Ahora, hay una palabra sueca llamada "vänd" que básicamente significa "regresar" y que se pronuncia de manera similar a "wend". Por eso pensé que tenía mucho sentido ... :)
Emil H

61
! no está en VB, es "No". ¿O es eso? Sí, no, no lo es, pero no.
brianary

77
Sí, "Wend" es una palabra en inglés, que significa ir o continuar en algún curso o camino ( google.com/search?q=define%3A+wend ). No estoy seguro si eso ayuda o duele.
Michael Myers

134

Para aquellos que no saben, bces un "lenguaje de calculadora de precisión arbitraria", y lo uso con bastante frecuencia para cálculos rápidos, particularmente cuando los números involucrados son grandes ( $es el indicador):

$ bc -lq
12^345
20774466823273785598434446955827049735727869127052322369317059031795\
19704325276892191015329301807037794598378537132233994613616420526484\
93077727371807711237016056649272805971389591721704273857856298577322\
13812114239610682963085721433938547031679267799296826048444696211521\
30457090778409728703018428147734622401526422774317612081074841839507\
864189781700150115308454681772032

bcha sido un comando estándar de Unix durante mucho tiempo.

Ahora para la "función WTF". Esto es de man bc(énfasis mío):

salir : cuando se lee la declaración de salida, el procesador bc se termina, independientemente de dónde se encuentre la declaración de salida. Por ejemplo, "if (0 == 1) quit" hará que bc termine.

detener : la declaración de detención (una extensión) es una declaración ejecutada que hace que el procesador bc se cierre solo cuando se ejecuta. Por ejemplo, "if (0 == 1) halt" no hará que bc termine porque no se ejecuta la detención.


41
Yo uso Haskell para estas cosas.
Thomas Eding

8
Calculadora de Google?
igul222

77
Yo mismo comencé a usar Python, y la calculadora de Google es buena si estás en línea. Pero solía usar bcantes de eso, y quería escribir sobre bcmi publicación debido a las excelentes citas de la página de manual.
Alok Singhal

66
@Brian, entonces te gustará: echo '[q]sa[ln0=aln256%Pln256/snlbx]sb3135071790101768542287578439snlbxq'|dc(aunque tal vez ya lo sepas).
Alok Singhal

2
Yo uso irb (shell interactivo de Ruby). Pero en el pasado, siempre buscaba dc, como bc, pero usa el pulido inverso. Geektastic!
tragomaskhalos

134

Siempre me pregunté por qué el programa más simple era:

class HelloWorldApp {
    public static void main(String[] args) {
        System.out.println("Hello World!");
    }
}

Mientras que podría ser:

print "Hello World!"

Tal vez esto es para asustar a los estudiantes de informática en primer lugar ...


34
En algunos idiomas, "¡Hola, mundo!" Es un programa válido.
David Thornley

31
@SoMoS: en la mayoría de los lenguajes dinámicos como Python, Ruby o Perl, imprima "¡Hola mundo!" o alguna variación menor (por ejemplo, pone en lugar de imprimir) es un programa válido y completo.
Dave Kirby el

36
@Loadmaster: la implicación era que "todo el código pertenece a una clase" o "todo el código pertenece a una función" son restricciones innecesarias
Jimmy

19
El hecho de que un lenguaje imponga el uso de objetos no significa que se esté utilizando para una programación orientada a objetos adecuada. Es perfectamente posible programar de manera procesal en Java o C #. Para eso están los métodos estáticos.
jdmichal

68
Amo a las personas que piensan que OOP significa que todo debería ser un objeto.
Tor Valamo

132

JavaScript está orientado a objetos, ¿verdad? Entonces, los métodos de ejecución en cadenas literales y números deberían funcionar. Me gusta "hello".toUpperCase()y 3.toString(). Resulta que el segundo es un error de sintaxis, ¿por qué? Porque el analizador espera que un número seguido de un punto sea un literal de coma flotante. Ese no es el WTF, el WTF es que solo tienes que agregar otro punto para que funcione:

3..toString()

La razón es que el literal 3.se interpreta como 3.0y 3.0.toString()funciona bien.


8
Funciona de esta manera también en Python (prueba 3..__add__(4)). Por otra parte, creo que (3).__add__(4)es una forma mucho menos dañada de hacerlo :)
badp

49
Puedes hacer (3) .toString ()
Joseph Montanez

13
@ Gorilla3D: sí, pero esa no es una característica extraña del lenguaje, ¿verdad?
Theo

25
3.0.toString()hace que me piquen los ojos.
Ben Blank

18
127.0.0.1.toInt ()
berkus

130

En JavaScript:

2 == [2]

// Even stranger
2 == [[[2]]]

// And down-right nutty
var a = { "abc" : 1 };
a[[[["abc"]]]] === a["abc"]; // this is also true

Afortunadamente, la gente amable de stackoverflow.com me lo explicó todo: ¿por qué 2 == [2] en JavaScript?


66
Es por eso que debes usar ===en su lugar.
Gumbo

10
Esto es útil por cierto, si tiene una función que devuelve un número y desea devolver algunos metadatos adicionales, puede devolver [número] con algunos campos adicionales agregados. El código simple nunca sabrá que no es un número real, y otro código puede obtener los metadatos requeridos.
Andrey Shchekin

36
@Andrey, excepto que si alguna vez tengo que mantener un código que haga lo que sugieres, muy pronto desearía la muerte de su autor.
Breton el

@ Andrew, ¡es una gran idea! También puedes usar Number(n)para hacer algo similar. Desafortunadamente en nuestras dos soluciones se ===rompe = (.
Xavi

55
+1: Me he considerado un programador experto de js, y nunca he sabido sobre esto: D
Thomas Eding

126

Mi característica más odiada es la sintaxis de cualquier archivo de configuración que incluye lógica condicional. Este tipo de cosas abundan en el mundo de Java (Ant, Maven, etc. ¡Sabes quién eres!).

Acabas de programar en lenguaje ac ** p, con depuración limitada y soporte de editor limitado.

Si necesita lógica en su configuración, el enfoque "Pythonic" de codificar la configuración en un lenguaje real es mucho mejor.


24
Tcl reinventó eso mucho antes de que Python naciera y Lisp lo inventó antes de eso. Así que no lo llamemos Pythonic, llamémoslo Emacs-ish.
slebetman

46
Vamos a llamarlo bien.
mletterle

30
AMÉN. Si su configuración o lenguaje de compilación se está completando, lo está haciendo mal. Te estoy mirando CMake / autotools.
Joseph Garvin el

16
Esto es exactamente para lo que Lua fue diseñado originalmente
Cogwheel

1
Bueno, si su código está en Python, entonces tener su archivo de configuración en Python es una gran idea, ya que simplemente importa el archivo y lee los atributos del módulo. Y obtienes el poder 100% Turing completo de Python en tu archivo de configuración.
Asmeurer

113

powerbasic (www.powerbasic.com) incluye la directiva del compilador:

# BLOAT {bloatsize}

esto aumenta el tamaño del ejecutable compilado por <bloatsize>bytes. esto se puso en el compilador en caso de que a las personas que crean el ejecutable no les guste el pequeño tamaño del ejecutable generado. hace que el EXE parezca más grande para competir con los lenguajes de programación hinchados :)


99
Jaja yuk. He oído que los desarrolladores ralentizan deliberadamente algunas operaciones (por ejemplo, una búsqueda) porque ayuda a las personas a creer que realmente está haciendo algo. Algo similar, supongo.
David

42
Esto me recuerda algo que leí recientemente. Estaban probando un FPS y decidieron aumentar el número de puntos de golpe que tenían los malos. Luego les preguntaron a los evaluadores cómo era la IA y juraron que era mucho más inteligente. Pero la IA no había cambiado, solo los puntos de golpe. Las personas tienen una cierta narrativa sobre el mundo en sus cabezas, y si entiendes y coinciden con sus expectativas, simplemente asumirán que valida su narrativa.
Nate CK

55
Solía ​​agregar mucha desaceleración adicional a mis programas para que parecieran que estaban haciendo algo complicado. De vuelta en la escuela primaria, eso es.
Matti Virkkunen

3
De vuelta en la escuela teníamos máquinas 80286 y en realidad tuve que escribir algunas rutinas de salida de pantalla en el ensamblaje para obtener una velocidad razonable (es decir, no rastrear).
berkus

77
@Nate CK, si la IA vive lo suficiente como para mostrar su IA, en realidad puede ser más inteligente, mientras que antes podría haber muerto demasiado rápido para demostrarlo.
zzzzBov
Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.