Recurso de idioma mais estranho

974

Qual é, na sua opinião, o recurso de linguagem mais surpreendente, estranho, estranho ou realmente "WTF" que você encontrou?

Por favor, apenas um recurso por resposta.

Robert Harvey
fonte
5
@gablin Eu acho que se você combinou delimitadores LISP com PERL regex usando javascript analisar você iria cobrir 90% da WTF ...
Talvi Watia

Respostas:

1859

Em C, matrizes podem ser indexadas da seguinte forma:

a[10]

o que é muito comum.

No entanto, a forma menos conhecida (que realmente funciona!) É:

10[a]

o que significa o mesmo que o acima.

Edan Maor
fonte
758
Isso porque a [10] meios * (a + 10) ... e 10 [a] significa * (10 + a) :)
Michel Gokan
77
Não se esqueça de "Hello World" [i]. Ou eu ["Olá Mundo"]
Richard Pennington
167
Ou, mais útil, "0123456789abcdef" [x & 0xf]
Dipstick
17
@frunsi: Funciona sempre como esperado. A adição de ponteiro não é igual à adição simples de números inteiros nos endereços. É comutativo, independentemente do tamanho do tipo em questão.
R. Martinho Fernandes
12
@mcv - a [10] é igual a "* (a + 10)", onde a expressão "a + 10" é aritmética de ponteiro (e como a é um pequeno, no seu exemplo, a + 10 significa 'começar em a e mova 10 shorts, ou seja, 20 bytes '). A expressão 10 [a] é interpretada como "* (10 + a)", onde "10 + a" também é aritmética de ponteiro e é tratada exatamente da mesma maneira.
Edan Maor
1292

Em JavaScript:

 '5' + 3 gives '53'

Enquanto que

 '5' - 3 gives 2
vareta
fonte
81
Lembro-me de quando comecei a usar javascript usando esse tipo de técnica para adicionar números nas strings: "111" - - "222" fornece 333, enquanto "111" + "222" fornece "111222".
Callum Rogers
112
+para concatenação é horrível
Matteo Riva
416
+ para concat não é o problema. Digitação fraca é.
FogleBird
270
@FogleBird Nenhum dos dois é realmente o problema. É apenas a combinação dos dois com regras de coerção inconsistentes.
TM.
70
Então, basicamente, + é concat quando uma string está envolvida. Por que eles não podem codificar algo como '123456' - 456 = '123'? Isso seria interessante.
precisa saber é o seguinte
872

Em JavaScript, a construção a seguir

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

retornaundefined é um erro de sintaxe devido à inserção de ponto e vírgula implícita furtiva na nova linha posterior return. O seguinte funciona como seria de esperar:

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

Pior ainda, este também funciona (no Chrome, pelo menos):

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

Aqui está uma variante do mesmo problema que não gera um erro de sintaxe, mas falha silenciosamente:

return
    2 + 2;
DrJokepu
fonte
225
A inserção de ponto e vírgula é uma das partes mais malignas do JavaScript.
230
Você sempre enfrenta problemas ao projetar recursos de linguagem com base na suposição de que seus usuários serão principalmente idiotas.
Rob Van Dam
8
Na verdade, eu tive esse problema, sendo desenvolvedor do c #, coloquei a chave em uma nova linha. Levei horas para perceber qual era o problema. Mesmo quando resolvi o problema, não sabia qual era o problema até ler sua resposta!
Fedor Hajdu
24
Nick Retallack: porque, devido à sintaxe do tipo C entre parênteses e ponto e vírgula do JavaScript, não é aparente que as novas linhas sejam significativas.
Tamas Czinege
19
Se você não deveria usar o estilo C ao programar em JavaScript, era bastante perverso dos designers da linguagem JavaScript escolher uma sintaxe no estilo C.
precisa saber é o seguinte
795

Tabela de verdade do 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

Fonte: Doug Crockford

Chandra Patni
fonte
237
Ainda bem que o Javascript possui o operador ===.
Anônimo
65
Então, que propósito ==serve aos olhos do designer de idiomas?
Chris S
137
Pessoas confusas.
Javier
123
Seria bom se ==tivesse o significado de ===, e então houvesse outro operador, algo assim ~=permitido coerção de tipo.
TM.
18
@Otto Na verdade, já que estamos saindo, o exemplo dele mostra que == não é simétrico. No momento, não vi como a comutatividade seria especificada para uma relação binária.
PeterAllenWebb
660

Trígrafos em C e C ++.

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

Isso será impresso LOL|, porque o trigrafo ??!é convertido em |.

Andreas Bonini
fonte
71
Rápido! Diga a todos os programadores C / b /!
Esteban Küber
235
Os trígrafos são incríveis, porque você pode ter certeza de que ninguém nunca descobrirá o que ?! significará do Google sem saber o nome já.
Zaratustra
56
Os trigramas estão desativados por padrão no GCC.
precisa saber é o seguinte
360
Isso permite que você use o "operador WTF": (foo ()! = ERRO) ??! ??! cerr << "Ocorreu um erro" << endl;
precisa saber é o seguinte
57
Os trígrafos eram um mal necessário quando foram introduzidos. Algumas plataformas simplesmente não incluíam certos caracteres-chave no idioma; portanto, eram "trigraphs" ou "você não pode ter um final de instrução do período do compilador C; portanto, use assembler". Confira a descrição do Stroustrup em "A linguagem de programação C ++".
Euro Micelli
573

Diversão com o boxe automático e o cache inteiro em 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

Explicação

Uma rápida olhada no código-fonte Java exibirá o seguinte:

/**
 * 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: o IntegerCache.high padrão é a 127menos que definido por uma propriedade.

O que acontece com o boxing automático é que foo e bar o mesmo objeto inteiro recuperado do cache, a menos que seja explicitamente criado: por exemplo foo = new Integer(42), portanto, ao comparar a igualdade de referência, elas serão verdadeiras e não falsas. A maneira correta de comparar o valor inteiro é usando.equals;

yx.
fonte
31
Levei alguns segundos para ver por que ... o java deve manter um conjunto de instâncias de número inteiro para valores entre -128 e 128, caso contrário, ele aloca um novo número inteiro, certo?
quer
18
no entanto, lembre-se de que, se você especificar o novo número inteiro (42), ele não usará a instância do pool, portanto foo == bar será avaliada como falsa
z -
10
Eu sempre uso ints em vez de números inteiros, se possível, mas se eu tivesse que usar números inteiros por algum motivo, devo usar apenas .equals () em vez de ==?
precisa saber é o seguinte
246
Tão feliz que eu sou um programador de C #.
87
@ Will: C # tem algumas dicas muito semelhantes. Veja blogs.msdn.com/jmstall/archive/2005/03/06/386064.aspx
spookylukey
373

Citando Neil Fraser (veja o final dessa página),

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

(em Java, mas o comportamento é aparentemente o mesmo em JavaScript e Python). O resultado é deixado como um exercício para o leitor.

EDITADO: Enquanto estivermos no assunto, considere também o seguinte:

try {
    throw new AssertionError();
} finally {
    return false;
}
lorenzog
fonte
42
+1. Por alguma razão, acho isso hilário e não consigo parar de rir.
outis
153
Felizmente C # não permite tal loucura ...Control cannot leave the body of a finally clause
Richard Ev
64
Isso retorna, falso, não é? Pode parecer um WTF (e possivelmente é um), mas eu vivo de acordo com a regra: Finalmente sempre vence, a menos que você trate a máquina antes.
Michael Stum
28
Para ser justo, culpo a boa explicação do TDWTF por lembrar que finalmente sempre vence, a menos que você puxe o cabo de força: thedailywtf.com/Articles/My-Tales.aspx
Michael Stum
22
Não sei ao certo qual código deve retornar neste caso. Mas estou absolutamente certo de que você não deve colocar returnna finallycláusula.
JFS
325

APL (exceto ALL), a capacidade de escrever qualquer programa em apenas uma linha.

por exemplo , Jogo da Vida de Conway em uma linha no APL :

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

Se essa linha não for WTF, nada será!

E aqui está um vídeo

lkessler
fonte
19
Eu amo APL. Ah, as alegrias de passar uma tarde inteira escrevendo meia linha de código! A primeira coisa que farei quando tiver um teclado onde possa programar quais letras são exibidas é me familiarizar novamente com o APL.
Daniel C. Sobral
24
Parece um idioma para os gregos.
Esko
45
@Erik: Há muita alegria em escrever código que é apenas sobre o que você deseja, e não sobre como chegar lá. De expressar seu código como uma única expressão. É como o melhor corte de katana perfeito. Claro, em uma luta real, eu prefiro ter uma arma.
Daniel C. Sobral
7
@ Daniel: Você passa uma tarde inteira para escrever uma linha de código ... e uma semana inteira para ler uma linha de código. ;-)
Jürgen A. Erhard
93
A APL seria incrível de ver em um filme de ação de ficção científica. Eu posso imaginar alguém sentado em um terminal tricolor murmurando "Remodelar o vetor de míssil inimigo ... transpor ... pi vezes logaritmo ... classificar - e - executar!" seguido de explosões e aplausos.
Joey Adams
321

As coisas estranhas que os modelos C ++ podem ser usados, melhor demonstradas pelos "Literais analógicos multidimensionais", que usam modelos para calcular a área de formas "desenhadas". O código a seguir é válido em C ++ para um retângulo 3x3

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

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

Ou outro exemplo com um 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) );
josefx
fonte
18
Embora os literais analógicos da Eelis sejam ótimos, eles são um recurso de linguagem estranho ou apenas uma maneira estranha de usar um recurso?
85
O WTF real será o erro do compilador gerado por um daqueles que está malformado.
Andrew McGregor
6
Quão doente é isso ... me acorde de novo quando houver uma versão dos AnalogLiterals que suporta girar o literal em torno dos eixos X, Y e Z no Eclipse ... agora isso daria à "programação visual" um novo significado real.
TheBlastOne 17/08/10
2
A ordenação dos O's e dos Ls | | é importante?
Ming-Tang
4
A ordem é importante, uma vez que os modelos fazem uso criativo da sobrecarga do operador (não faça isso com código real, o uso indevido de operadores dificulta a leitura)
josefx
292

Muitas variáveis ​​internas do Perl:

  • $#- não é um comentário!
  • $0,, $$e $?- assim como as variáveis ​​de shell com o mesmo nome
  • , $&E $'- variáveis de captura estranhas
  • $"e $,- variáveis ​​estranhas para separadores de campos de lista e saída
  • $!- como errnoum número, mas strerror(errno)como uma string
  • $_- a variável stealth, sempre usada e nunca vista
  • $#_ - número do índice do último argumento da sub-rotina ... talvez
  • @_ - os nomes (não) da função atual ... talvez
  • $@ - a última exceção levantada
  • %:: - a tabela de símbolos
  • $:, $^, $~, $-, E $=- algo a ver com formatos de saída
  • $.e $%- número da linha de entrada, número da página de saída
  • $/e $\- separadores de registros de entrada e saída
  • $| - controlador de buffer de saída
  • $[- mude sua base de array de 0 para 1 e 42: WHEEE!
  • $}- nada, curiosamente!
  • $<, $>, $(, $)- UIDs e GIDs reais e efetivos
  • @ISA - nomes das superclasses diretas do pacote atual
  • $^T - tempo de inicialização do script em segundos
  • $^O - nome atual do sistema operacional
  • $^V - qual é a versão do Perl

Há muito mais de onde eles vieram. Leia a lista completa aqui .

Chris S
fonte
83
A $[variável é a mais má de todas.
Brad Gilbert
24
Definitivamente apreciaria se Perl 6 fosse algo que eu pudesse codificar sem ter que verificar a perldoc perlvarcada cinco segundos. (Embora eu confesso que metade do tempo eu verificá-lo pensando: "Eu sei que há uma variável especial que pode fazer isso por mim, eu não lembro qual ..." = P)
Chris Lutz
17
O problema use English;é que isso afeta o desempenho do RegExp. Eu não estou inventando isso. perldoc.perl.org/English.html#PERFORMANCE
Dave Webb
13
@ Dave: não é um problema por causa da opção -no_match_vars na página que você vinculou. @ Brad: $ [é tão mau. A intenção por trás disso é má, sim, mas também nem funciona! @Artem: from perlvar "Os identificadores Perl que começam com dígitos, caracteres de controle ou caracteres de pontuação são isentos dos efeitos da declaração do pacote e são sempre forçados a estar no pacote principal; eles também são isentos de erros estritos de 'vars'". Isso significa que @ $ seria criado e atribuído sem erro, mesmo sob restrição. Ugh!
Rjh
4
@Brian: Como você propõe aprender a sintaxe quando a própria documentação oficial afirma que há circunstâncias em que o interpretador Perl adivinha heuristicamente o que significa uma sequência de caracteres? Por exemplo /$foo[bar]/, em , a [bar]parte é uma classe de caracteres ou um subscrito para a matriz @foo? Grep perldata pela resposta terrível.
Jrandom_hacker
289

Manipulação do PHP de valores numéricos em strings . Veja esta resposta anterior a uma pergunta diferente para obter detalhes completos, mas, resumindo:

"01a4" != "001a4"

Se você tiver duas cadeias que contêm um número diferente de caracteres, elas não poderão ser consideradas iguais. Os zeros à esquerda são importantes porque são cadeias e não números.

"01e4" == "001e4"

PHP não gosta de strings. Ele está procurando qualquer desculpa que possa encontrar para tratar seus valores como números. Altere os caracteres hexadecimais nessas cadeias um pouco e de repente o PHP decide que não são mais cadeias, são números em notação científica (o PHP não se importa que você tenha usado aspas) e são equivalentes porque zeros à esquerda são ignorados por números. Para reforçar esse ponto, você descobrirá que o PHP também é avaliado "01e4" == "10000"como verdadeiro porque esses são números com valores equivalentes. Esse é um comportamento documentado, mas não é muito sensato.

Dan Dyer
fonte
56
Basta usar === e! ==. Que deve ser usado de qualquer maneira, a menos que seja necessária uma comparação de tipos soltos.
Dykam
14
@ Tykam, se você seguir o link para a resposta mais completa, verá que eu falei sobre o uso do operador ===.
Dan Dyer
18
Digitação fraca ataca novamente!
gillonba
43
Eu sempre soube que o PHP era um pecado. Até agora eu não sabia que era um pecado imperdoável: D
Thomas Eding
2
Eles devem usar os técnicos em qualquer livro ou tutorial de programação. Nota adicionada: em um aplicativo PHP mal escrito, pude fornecer como senha qualquer coisa que fosse analisada como o mesmo número.
Pepijn 21/07
282

Vamos votar em todos os idiomas (como PL / I) que tentaram eliminar as palavras reservadas.

Onde mais você poderia legalmente escrever expressões divertidas como:

IF IF THEN THEN = ELSE ELSE ELSE = THEN

( IF, THEN, ELSESão nomes de variáveis)

ou

IF IF THEN THEN ELSE ELSE

( IFé uma variável THENe ELSEsão sub-rotinas)

MZB
fonte
1
@ark: essa é uma resposta separada para isso! ;) ... (e sim, você pode programar com Inglês, apenas implantá-lo como .ppt para outros desenvolvedores;).
Macke
28
@RoadieRich Um grupo de búfalos não é explicitamente do Buffalo, eles são apenas búfalos indefinidos.
Jürgen A. Erhard
18
John, onde James teve, teve, teve, teve, teve um efeito melhor sobre o professor.
GameFreak 21/07
4
Eu vi alguns fabricantes de placas do lado de fora de uma fábrica de sorvetes Ben e Jerrys outro dia. Critiquei o trabalho deles, disse a eles que não havia espaço suficiente entre ben e and and and jerrys.
Tom Gullen
9
Talvez seja necessário para futuros programas temporais. SE ENTÃO = AGORA && ONDE = AQUI = QUANDO = ENTÃO AGORA = EM OUTRO LUGAR
Kelly S. French
282

O 'recurso' de conversão octal do JavaScript é bom para saber sobre:

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

Mais detalhes aqui .

Brian Deterling
fonte
60
Ficou preso em um bug que todos os números funcionavam, exceto 8 e 9 !! Estava ficando louco !!! Obrigado Brian!
Faruz
10
@Yada Você não quer dizer octal? Hexadecimal é 0x.
luiscubal
48
E é por isso que parseInt usa um argumento extra (opcional) :).
LiraNuna
10
0 inicial significa número octal. como 8 não é um dígito octal válido, o resultado deve ser 0.
devio
22
... e parseInt ('010') -> 8 apenas para confundir você.
Richard Gadsden
213

O dispositivo de Duff em C!

Em C, pode-se entrelaçar um fazer / enquanto com uma instrução switch. Aqui está um exemplo de um 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);
    }
}
Frunsi
fonte
9
O dispositivo de Duff é provavelmente um bom motivo para a instrução switch não ter uma interrupção por padrão ;-) No entanto, ainda não vi outro bom uso do switch e loop entrelaçados - mas provavelmente existe um. Oh, espere, sim, há outro uso: corotinas e prototreads.
Frunsi 7/01/10
16
@frunsi: "O dispositivo de Duff provavelmente é um bom motivo para a instrução switch não ter uma interrupção por padrão" - Sempre torne o caso comum o padrão. Eu não diria exatamente que este é o caso comum .. #
BlueRaja # Danny Pflughoeft 19/01/10
6
O @mcv provavelmente é mais fácil se você tentar lê-lo como código de montagem, ou seja while, o final é um JMPretorno (condicional) para o do, o que explica por que você pode pular o arquivo doe ainda assim acabar no loop.
Wd
14
Lembre-se de que o dispositivo de Duff geralmente produz código pior que a instrução de loop normal para compiladores modernos, que sabem como (melhor) desenrolar o loop do que você pode fazer manualmente.
Billy ONeal
37
@frunsi: O próprio Duff, publicando-o, afirmou algo como isto: "Isso definitivamente fornece um argumento na discussão sobre se a opção deve passar por padrão, mas não tenho certeza se o argumento é a favor ou contra."
SF.
204

Passe Algol por nome (ilustrado usando a sintaxe 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]);
}
Richard Pennington
fonte
33
Se você pensar sobre isso, ele realmente faz algum tipo de sentido torcida
RCIX
90
Este é o último "passe por referência".
Dykam
3
No entanto, é possível em Scala ( def f(j : => int))
Dario
10
Então isso é algo como ... 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]; } }); }?
precisa saber é o seguinte
2
Na verdade, é bem direto: você gera um pequeno pedaço de código (geralmente chamado de "thunk", daí o meu trocadilho acima) que calcula o endereço resultante da expressão, neste caso & a [i]. Um ponteiro para esta função é passado para a função chamada, que a utiliza para calcular o endereço atual toda vez que o parâmetro é acessado.
Richard Pennington
189

Em Python:

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

Não é um WTF, mas um recurso útil.

MAK
fonte
176
Eu desejo que todos os outros idiomas
possuam
32
Como em quase todos os recursos interessantes do Python, parece que o Guido acabou de modificar a sintaxe do recurso interessante do Lisp. :-)
Ken
4
Geoffrey, é um recurso, e (10 > 5 > 1) != ((10 > 5) > 1)em Python.
sastanin
18
Além disso, ele avalia apenas uma vez, portanto, (funct_a(5)+5 > b > funct_a(5))apenas chama funct_a(5)uma vez. É um ótimo recurso!
Khelben
57
@ Khelben: Não, funct_aserá chamado duas vezes nesse exemplo. Em b > funct_a(5) > cela só vai ser chamado uma vez que, ao contrário b > funct_a(5) and funct_a(5) > c.
Baffe Boyois
189

Em Java:

int[] numbers() {
  return null;
}

Pode ser escrito como:

int numbers() [] {
  return null;
}
Chandra Patni
fonte
23
Uau! Eu gostaria de poder ser uma mosca na parede quando essa sintaxe de matriz foi projetada!
precisa saber é o seguinte
29
Detesto dizer isso, mas o WTF é uma extensão consistente do sistema do tipo C. Se as funções C tivessem permissão para retornar matrizes, seria assim. O melhor é uma violação de consistência para torná-lo mais legível. Muito parecido com "const char * var" vs "char const * var".
Gordon Wrigley
15
@ Adam - Na verdade, faz sentido quando você considera que a declaração de variável permite similarmente "int stuff []" e "int [] stuff". Eles apenas permitem que as mesmas regras funcionem para a declaração do método.
precisa
2
@ lImbus: Na verdade, const T*e T const*são equivalentes, é isso T* constque consome o ponteiro. Além disso, eu odeio fontes sem.
precisa saber é o seguinte
3
Afinal, numbers()[2]é uma declaração legal.
96010 badp
184

INTERCAL é provavelmente o melhor compêndio de recursos linguísticos mais estranhos. Meu favorito pessoal é a declaração COMEFROM , que é (quase) o oposto do GOTO.

COMEFROM é aproximadamente o oposto de GOTO, pois ele pode levar o estado de execução de qualquer ponto arbitrário no código para uma instrução COMEFROM. O ponto no código em que a transferência de estado ocorre geralmente é fornecido como parâmetro para o COMEFROM. Se a transferência ocorre antes ou depois da instrução no ponto de transferência especificado depende do idioma usado. Dependendo do idioma usado, vários COMEFROMs que referenciam o mesmo ponto de partida podem ser inválidos, não determinísticos, executados em algum tipo de prioridade definida ou até induzir a execução paralela ou simultânea, como visto no Threaded Intercal. Um exemplo simples de uma instrução "COMEFROM x" é um rótulo x (que não precisa estar fisicamente localizado em qualquer lugar próximo ao COMEFROM correspondente) que atua como um "alçapão". Quando a execução do código atinge o rótulo, o controle é passado para a instrução após o COMEFROM. O efeito disso é principalmente tornar a depuração (e entender o fluxo de controle do programa) extremamente difícil, pois não há indicação perto do rótulo de que o controle vá misteriosamente para outro ponto do programa.

Jeff Foster
fonte
16
Bastante mal - transforma rótulos em GOTOs. Soa como um recurso de linguagem hackers iria implorar para ...
RCIX
114
Ok, mas INTERCAL deve ser engraçado - isso não é realmente uma "pegadinha" surpreendente. O compilador INTERCAL pode realmente se recusar a compilar o programa se você não usar o PLEASEmodificador com bastante frequência!
Groo
10
Soa como AOP :)
akuhn
6
O que mais me surpreende é que, na análise de requisitos do sistema no "World of Commercial TI", os COMEFROMs são realmente usados ​​em arquivos de texto que descrevem Casos de Uso. (sério: alguns analistas aqui adiada uma migração larga corporativa para OpenOffice em vez do Office da MS porque o primeiro não poderia referenciar corretamente um "comefrom" com a granularidade necessária em um link)
jsbueno
5
Groo: É pior. Use POR FAVOR com muita frequência e ele se recusa a compilar seu programa porque você está groveling (C-INTERCAL requer entre 33% e 66% das instruções para ter modificadores POR FAVOR).
Vatine
160

Não é realmente um recurso de linguagem, mas uma falha de implementação: alguns compiladores anteriores do Fortran implementaram constantes usando um pool constante. Todos os parâmetros foram passados ​​por referência. Se você chamou uma função, por exemplo

f(1)

O compilador passaria o endereço da constante 1 no pool constante para a função. Se você atribuiu um valor ao parâmetro na função, alteraria o valor (neste caso, o valor de 1) globalmente no programa. Causou algum coçar a cabeça.

Richard Pennington
fonte
124
Ooh. Então 2+2 pode ser igual 5(para valores muito grandes, é 2claro!).
Alok Singhal
12
hum, que valor de 2 tornaria "2 + 2" == "5"? Não sei se qualquer valor inteiro 2 pode assumir para que isso seja verdade.
Aaron
36
@earlz: Eu suspeito que acabaria como um valor integral, de qualquer padrão de bits. Por outro lado, você provavelmente pode definir de 5 a 4 dessa maneira (isso 2+2seria igual 5para valores pequenos de 5).
David Thornley
18
Com licença, Alok, mas estamos falando do FORTRAN inicial. Não será verdade isso 2 + 2 = 5; isso será um erro de sintaxe. O que será verdade é 2 + 2 .EQ. 5.
David Thornley
3
Em Haskell, o seguinte trecho é avaliado como 5: "let 2 + 2 = 5 in 2 + 2" :)
Tirpen
153

Não sei se ele pode ser considerado um recurso de linguagem, mas em C ++ quase qualquer erro de compilador relacionado a modelos fornece uma quantidade razoável de WTF para muitos programadores de C ++ diariamente em todo o mundo :)

Dmitry
fonte
15
Tudo bem, a maioria dos códigos relacionados aos modelos já cria muitos WTFs em todo o mundo.
Joris Timmermans
43
Oh venha agora. referência 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 *) 'É perfeitamente legível!
Matt Greer
10
Certa vez, tive um erro de compilador relacionado ao modelo com cinco linhas, a menor delas com dezessete mil caracteres (o erro clássico 'sem correspondência para x', em um programa profundamente modelado). Esse é o WTF, não o recurso em primeiro lugar, os modelos são maravilhosos.
Andrew McGregor
111
Mesmo se não houver erro, tente descobrir quais funções demoram mais com seu criador de perfil. Veja bem, éstd::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
Acho que isso se encaixa aqui: Confira o STLFilt em bdsoft.com/tools/stlfilt.html para tornar a saída legível.
06/01/10
150

Os muitos espaços de nomes de C:

typedef int i;

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

Ou com caracteres:

typedef char c;

void foo()
{
    struct c {c c;} c;
    c: c.c = 'c';
    printf( "%c\n", c.c);
}
Victor Hurdugaci
fonte
Como diabos isso compila sem ambiguidade !?
Earlz
13
Os identificadores de tags +1 para enumerações e estruturas são a parte mais confusa do C imho. Poucas pessoas entendem por que o idioma para digitar um ponteiro para uma estrutura se parece com o que é.
Tadeusz A. Kadłubowski
11
Ele é compilado porque cada um desses i's possui um espaço para nome inequívoco devido ao contexto.
Andrew McGregor
149

Eu diria que todo o espaço em branco do Python é o meu maior recurso WTF. É verdade que você se acostuma mais ou menos com isso depois de um tempo e os editores modernos facilitam o tratamento, mas mesmo depois do desenvolvimento de python em tempo integral no ano passado, ainda estou convencido de que foi uma má ideia. Eu li todo o raciocínio por trás disso, mas honestamente, isso atrapalha minha produtividade. Não muito, mas ainda é uma rebarba debaixo da sela.

editar: a julgar pelos comentários, algumas pessoas parecem pensar que eu não gosto de recuar meu código. Essa é uma avaliação incorreta. Eu sempre recuei meu código, não importa qual idioma e se sou forçado ou não. O que eu não gosto é que é o recuo que define em que bloco uma linha de código está. Prefiro delimitadores explícitos para isso. Entre outras razões, acho que delimitadores explícitos facilitam a recortar e colar o código.

Por exemplo, se eu tiver um bloco com quatro espaços recuados e colá-lo no final de um bloco com oito espaços recuados, meu editor (todos os editores?) Não faz ideia se o código colado pertence ao bloco de 8 espaços ou ao espaço externo quadra. OTOH, se eu tenho delimitadores explícitos, é óbvio a qual bloco o código pertence e como deve ser (re) indentado - ele o faz procurando inteligentemente por delimitadores de bloco.

edit 2: algumas pessoas que fazem comentários parecem pensar que esse é um recurso que odeio ou que faz do python uma linguagem ruim. Novamente, não é verdade. Embora eu não goste muito, isso não vem ao caso. A questão é sobre o recurso de idioma mais estranho , e acho isso estranho, por ser algo que muito, muito poucas (mas> 0) as linguagens usam.

Bryan Oakley
fonte
63
se ele fica no caminho de sua produtividade, em seguida, seu código não-python não pode ser muito legível ...
Tor Valamo
27
Qual idioma você usou antes do Python? Como você foi capaz de trabalhar com outras pessoas e não recuar esse idioma? Como alguém poderia suportar código não recuado em qualquer idioma? Você trabalhou em uma sala cheia de gênios que não precisavam de pistas visuais no código-fonte?
precisa saber é
53
+1 Não poderia concordar mais, se o meu editor (Emacs) não puder recuar meu código com base em algo distinto (como chaves / começo, fim / nome dele) automaticamente, é seriamente bobo. Praticamente qualquer refatoração que você faria em uma função "maior" pode ser uma experiência muito ruim.
Dmitry
83
Aqui está o trato - com qualquer outro idioma, posso destacar um bloco de código e identá-lo adequadamente por qualquer editor. Mas como o espaço em branco É, por definição, o recuo adequado, você perde essa capacidade no Python. Portanto, é mais difícil mover o código ou refatorar as coisas. E para a pessoa que afirma que o OP é a "primeira pessoa a afirmar que foi um problema", bem, eu tive que manter algum código python por um tempo e agora vou usar qualquer linguagem sobre python por esse motivo.
Kendall Helmstetter Gelner
38
Eu não me importo com o espaço em branco no Python. O WTF é que não é aplicado de forma consistente. Você pode misturar níveis e tabulações de recuo, desde que sejam consistentes com os irmãos. Portanto, o primeiro nível de recuo pode ser um espaço e o segundo pode ser duas TABs, e isso não é um erro de sintaxe.
ieure
138

Eu lutei um pouco sobre isso:

1;

No perl, os módulos precisam retornar algo verdadeiro .

miku
fonte
29
Alguns módulos podem retornar valores com base nas operações de tempo de execução. Se você sempre retorna verdadeiro, ainda não precisa ser criativo: returnvalues.useperl.at
Anônimo
8
Se minha memória Perl me servir corretamente, retornar true de um módulo indicou que o módulo foi carregado com êxito. Retornar um valor falso significa que algo deu errado e impediria a execução do programa (se não for capturado).
Barry Brown
Esta é uma instrução C válida também, apenas nada é retornado.
sigjuice
24
Mark Dominus escreveu: "Eu muito raramente usei o 'Cogito ergo sum';que, como todos sabem, é evidentemente verdadeiro em todos os universos possíveis. Isso garante a máxima portabilidade".
Greg Bacon
PHP <?=1;?>retorna 1. <?=true;?>retorna 1. <?=false;?>retorna nulo.
Talvi Watia
135

Estou surpreso que ninguém tenha mencionado as construções de loop de 7 do 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 furando um! na frente de sua condicional é maneira muito complicado!

Jeff Atwood
fonte
47
Deveriam ter escrito " Whilee Whend", já que algumas pessoas pronunciam a palavra "enquanto" com o velar labializado sem voz aproximadamente. E é claro que ele se alinha melhor, e o código que se alinha é bom.
dreamlax
43
Por que você está agindo tão terceiro?
Erik Forbes
48
Uau. Fico meio nostálgico quando penso nisso. A primeira vez que usei VB estava de volta aos 9 anos de idade. Eu sou da Suécia e naquela época não sabia muito inglês. Agora, há uma palavra sueca chamada "vänd", que basicamente significa "voltar" e que é pronunciada de forma semelhante a "wend". Por causa disso eu pensei que fez um monte de sentido ... :)
Emil H
61
! não está no VB, é "não". Ou é? Sim, não é não!, Mas não.
Brianary
7
Sim, "Wend" é uma palavra em inglês que significa seguir ou prosseguir em algum curso ou caminho ( google.com/search?q=define%3A+wend ). Não tenho certeza se isso ajuda ou machuca.
Michael Myers
134

Para quem não sabe, bcé uma "linguagem arbitrária da calculadora de precisão", e eu a uso com frequência para cálculos rápidos, principalmente quando os números envolvidos são grandes ( $é o prompt):

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

bctem sido um comando padrão do Unix há muito tempo.

Agora, para o "recurso WTF". Isto é de man bc(ênfase minha):

quit : Quando a instrução quit é lida, o processador bc é finalizado, independentemente de onde a instrução quit foi encontrada. Por exemplo, "se (0 == 1) sair" fará com que bc seja finalizado.

parada : a instrução de parada (uma extensão) é uma instrução executada que faz com que o processador bc seja encerrado somente quando é executado. Por exemplo, "if (0 == 1) halt" não fará com que bc termine porque a parada não é executada.

Alok
fonte
41
Eu uso Haskell para essas coisas.
Thomas Eding
8
Calculadora do Google?
precisa saber é o seguinte
7
Comecei a usar o Python, e a calculadora do Google é legal se você estiver online. Mas eu costumava usar bcantes disso e queria escrever bcno meu post por causa das ótimas citações da página de manual.
Alok Singhal
6
@ Brian, então você vai gostar: echo '[q]sa[ln0=aln256%Pln256/snlbx]sb3135071790101768542287578439snlbxq'|dc(embora você já deva saber disso).
Alok Singhal
2
Eu uso o irb (shell interativo Ruby). Mas, naquela época, eu sempre procurava o dc - like bc, mas usa polimento reverso. Geektastic!
Tragomaskhalos
134

Eu sempre me perguntei por que o programa mais simples era:

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

Considerando que poderia ser:

print "Hello World!"

Talvez isso seja para assustar os estudantes de ciência da computação em primeiro lugar ...

Didier Trosset
fonte
34
Em alguns idiomas, "Olá, mundo!" é um programa válido.
precisa saber é o seguinte
31
@SoMoS: nas linguagens mais dinâmicas, como Python, Ruby ou Perl, imprima "Hello World!" ou alguma variação menor (por exemplo, coloca em vez de imprimir) é um programa válido e completo.
Dave Kirby
36
@ Loadmaster: a implicação era que "todo o código pertence a uma classe" ou "todo o código pertence a uma função" são restrições desnecessárias
Jimmy
19
Só porque uma linguagem reforça o uso de objetos, não significa que está sendo usada para uma programação orientada a objetos adequada. É perfeitamente possível programar proceduralmente em Java ou C #. É para isso que servem os métodos estáticos.
precisa saber é o seguinte
68
Eu amo pessoas que pensam que OOP significa que tudo deve ser um objeto.
Tor Valamo
132

JavaScript é orientado a objetos, certo? Portanto, os métodos em execução em strings e números literais devem funcionar. Como "hello".toUpperCase()e 3.toString(). Acontece que o segundo é um erro de sintaxe, por quê? Como o analisador espera que um número seguido de um ponto seja um literal de ponto flutuante. Esse não é o WTF, o WTF é que você só precisa adicionar outro ponto para fazê-lo funcionar:

3..toString()

A razão é que o literal 3.é interpretado como 3.0e 3.0.toString()funciona bem.

Theo
fonte
8
Também funciona dessa maneira em Python (tente 3..__add__(4)). Então, novamente eu acho que (3).__add__(4)é uma forma menos muito cérebro danificado para fazê-lo :)
badp
49
Você pode apenas fazer (3) .toString ()
Joseph Montanez
13
@ Gorilla3D: sim, mas isso não é um recurso de idioma estranho, é?
Theo
25
3.0.toString()faz meus olhos coçarem.
Ben Blank
18
127.0.0.1.toInt ()
Berkus
130

Em JavaScript:

2 == [2]

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

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

Felizmente, o pessoal do stackoverflow.com me explicou tudo: Por que 2 == [2] em JavaScript?

Xavi
fonte
6
É por isso que você deve usar ===.
Gumbo
10
Isso é útil, se você tem uma função que retorna um número e deseja retornar alguns metadados adicionais, pode retornar [number] com alguns campos adicionais adicionados. O código simples nunca saberá que não é um número real e outro código pode obter os metadados necessários.
Andrey Shchekin
36
@ Andy, exceto que se eu tiver que manter um código que faça o que você sugere, muito em breve desejarei a morte de seu autor.
Breton
@ Andy, é uma ótima idéia! Você também pode usar Number(n)para fazer algo semelhante. Infelizmente, em ambas as nossas soluções, as ===quebras = (.
Xavi
5
+1: Eu me considero um programador js experiente e nunca soube disso: D
Thomas Eding 13/02/10
126

Meu maior recurso mais odiado é qualquer sintaxe de arquivo de configuração que inclua lógica condicional. Esse tipo de coisa é comum no mundo Java (Ant, Maven, etc. Você sabe quem é!).

Você acaba programando em linguagem AC ** P, com depuração limitada e suporte limitado ao editor.

Se você precisar de lógica em sua configuração, a abordagem "Pythonic" de codificar a configuração em uma linguagem real é muito melhor.

James Anderson
fonte
24
O Tcl reinventou isso muito antes do Python nascer e o Lisp o inventou antes disso. Então não vamos chamá-lo de Pythonic, vamos chamá-lo de Emacs-ish.
slebetman
46
Vamos chamar de certo.
precisa saber é o seguinte
30
AMÉM. Se sua configuração ou idioma de compilação estiver completo, você estará fazendo errado. Estou olhando para você CMake / autotools.
Joseph Garvin
16
Este é exatamente o que Lua foi projetado para, originalmente
Cogwheel
1
Bem, se o seu código estiver em Python, é uma ótima idéia fazer com que seu arquivo de configuração seja um arquivo Python, porque você apenas importa o arquivo e lê os atributos do módulo. E você obtém o poder 100% completo de Turing do Python no seu arquivo de configuração.
asmeurer
113

O powerbasic (www.powerbasic.com) inclui a diretiva do compilador:

# BLOAT {bloatsize}

isso aumenta o tamanho do executável compilado em <bloatsize>bytes. isso foi colocado no compilador caso as pessoas que criam o executável não gostem do tamanho pequeno do executável gerado. faz o EXE parecer maior para competir com as linguagens de programação inchadas :)

Don Dickinson
fonte
9
Haha yuk. Eu ouvi falar sobre desenvolvedores desacelerando deliberadamente algumas operações (por exemplo, uma pesquisa) porque ajuda as pessoas a acreditar que realmente está fazendo algo. Coisa semelhante, eu acho.
David
42
Isso me lembra algo que li recentemente. Eles estavam testando um FPS e decidiram aumentar o número de pontos de vida que os bandidos tinham. Então eles perguntaram aos testadores como eles eram a IA e juraram que era muito mais inteligente. Mas a IA não mudou, apenas os pontos de vida. As pessoas têm uma certa narrativa sobre o mundo em suas cabeças, e se você entender e corresponder às expectativas delas, elas simplesmente assumirão que valida a narrativa.
Nate CK
5
Eu costumava adicionar muito mais lentidão aos meus programas para fazê-los parecer que estavam fazendo algo complicado. De volta à escola primária, isso é.
Matti Virkkunen
3
De volta à escola, tínhamos 80286 máquinas e, na verdade, tive que escrever algumas rotinas de saída de tela em montagem para obter uma velocidade razoável (ou seja, não rastrear).
Berkus
7
@Nate CK, se a IA viver o tempo suficiente para exibi-la, ela pode ser realmente mais inteligente, enquanto antes poderia ter morrido rápido demais para provar isso.
precisa saber é o seguinte