Funzionalità linguistica più strana


974

Qual è, secondo te, la caratteristica del linguaggio più sorprendente, bizzarra, strana o davvero "WTF" che hai riscontrato?

Per favore, solo una funzione per risposta.


5
@gablin Penso che se abbinassi i delimitatori LISP al regex PERL usando l'analisi javascript,
copriresti il

Risposte:


1859

In C, le matrici possono essere indicizzate in questo modo:

a[10]

che è molto comune.

Tuttavia, la forma meno conosciuta (che funziona davvero!) È:

10[a]

il che significa lo stesso del precedente.


758
questo perché un [10] significa * (a + 10) ... e 10 [a] significa * (10 + a) :)
Michel Gokan,

77
Non dimenticare "Hello World" [i]. O io ["Hello World"]
Richard Pennington,

167
O, più utilmente, "0123456789abcdef" [x & 0xf]
Astina di livello

17
@frunsi: funziona sempre come previsto. L'aggiunta del puntatore non è la stessa aggiunta del numero intero sugli indirizzi. È commutativo, indipendentemente dalle dimensioni del tipo in questione.
R. Martinho Fernandes,

12
@mcv - a [10] è uguale a "* (a + 10)", dove l'espressione "a + 10" è aritmetica del puntatore (e poiché a è un breve, nel tuo esempio, a + 10 significa "inizia da indirizzo di a, e sposta 10 short, cioè 20 byte '). L'espressione 10 [a] viene interpretata come "* (10 + a)", dove "10 + a" è anche aritmetica del puntatore e viene trattata esattamente allo stesso modo.
Edan Maor,

1292

In JavaScript:

 '5' + 3 gives '53'

Mentre

 '5' - 3 gives 2

81
Ricordo quando ho iniziato a usare javascript usando questo tipo di tecnica per aggiungere numeri nelle stringhe: "111" - - "222" dà 333 mentre "111" + "222" dà "111222".
Callum Rogers,

112
+perché la concatenazione di archi è orribile
Matteo Riva

416
+ per concat non è il problema. Digitazione debole è.
FogleBird,

270
@FogleBird Nessuno dei due è davvero il problema. È solo la combinazione dei due con regole di coercizione incoerenti.
TM.

70
Quindi, in sostanza, + è concat quando è coinvolta una stringa. Perché non possono codificare qualcosa come "123456" - 456 = "123"? Sarebbe interessante.
Jimmie Lin,

872

In JavaScript, il seguente costrutto

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

ritornaundefined è un errore di sintassi a causa del subdolo inserimento implicito del punto e virgola sulla riga successiva dopo return. Quanto segue funziona come ci si aspetterebbe però:

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

Ancora peggio, funziona anche questo (almeno in Chrome):

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

Ecco una variante dello stesso problema che non genera un errore di sintassi, ma fallisce silenziosamente:

return
    2 + 2;

225
L'inserimento del punto e virgola è una delle parti più malvagie di JavaScript.

230
Si verificano sempre problemi quando si progettano funzionalità linguistiche in base al presupposto che gli utenti saranno per lo più idioti.
Rob Van Dam

8
In realtà ho avuto quel problema, essendo anch'io sviluppatore di c #, ho messo la coppia in una nuova linea. Mi ci sono volute ore per capire quale fosse il problema. Anche quando ho risolto il problema, non sapevo quale fosse il problema fino a quando non ho letto la tua risposta!
Fedor Hajdu,

24
Nick Retallack: Perché, a causa delle parentesi graffe simili a C e della sintassi punto e virgola, non è affatto chiaro che le nuove righe siano significative.
Tamas Czinege,

19
Se non dovresti usare lo stile C durante la programmazione in JavaScript, è stato piuttosto perverso dei progettisti del linguaggio JavaScript scegliere una sintassi in stile C.
Ryan Lundy,

795

Tabella di verità 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


237
Per fortuna Javascript ha quindi l'operatore ===.
Anonimo

65
Quindi quale scopo ==serve agli occhi del progettista del linguaggio?
Chris S,

137
Persone confuse.
Javier

123
Sarebbe bello se ==avesse il significato di ===, e poi ci fosse un altro operatore, qualcosa del genere ha ~=permesso la coercizione del tipo.
TM.

18
@Otto In realtà, dal momento che stiamo esagerando, il suo esempio mostra che == non è simmetrico. Al momento, non ho visto come sarebbe stata specificata la commutatività per una relazione binaria.
Peter Allll Webb

660

Trigrafi in C e C ++.

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

Questo verrà stampato LOL|, perché la trigrafia ??!viene convertita in |.


71
Presto! Dillo a tutti i programmatori C / b /!
Esteban Küber,

235
Le trigrafi sono incredibili, perché puoi essere sicuro che nessuno scoprirà mai ??! significherà da Google senza conoscere già il nome.
Zaratustra,

56
Le trigrafi sono disabilitate per impostazione predefinita in GCC.
sastanin,

360
Questi consentono di utilizzare l '"operatore WTF": (foo ()! = ERROR) ??! ??! cerr << "Si è verificato un errore" << endl;
user168715

57
Le trigrafi erano un male necessario quando furono introdotte. Alcune piattaforme non includevano alcuni caratteri chiave per il linguaggio, quindi erano "trigraphs" o "non si può avere un periodo di fine ciclo del compilatore C, quindi usare assembler". Controlla la descrizione di Stroustrup in "Il linguaggio di programmazione C ++".
Euro Micelli,

573

Divertimento con il boxe automatico e la cache intera in 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

Spiegazione

Una rapida occhiata al codice sorgente Java mostrerà quanto segue:

/**
 * 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: il IntegerCache.high valore predefinito è a 127meno che non sia impostato da una proprietà.

Quello che succede con l'auto boxing è che sia foo che bar lo stesso oggetto intero recuperato dalla cache a meno che non sia stato esplicitamente creato: ad esempio foo = new Integer(42), quindi quando si confronta l'uguaglianza di riferimento, saranno veri piuttosto che falsi. Si sta utilizzando il modo corretto di confrontare il valore intero.equals;


31
Mi ci sono voluti un paio di secondi per capire perché ... java deve mantenere un pool di istanze Integer per valori compresi tra -128 e 128, altrimenti assegnerà un nuovo intero, giusto?
Mike Akers,

18
tuttavia tieni presente che se specifichi un nuovo numero intero (42) non utilizzerà l'istanza dal pool, quindi foo == bar valuterà falso
z -

10
Uso sempre ints anziché Integer, se possibile, ma se dovessi usare Integer per qualche motivo, dovrei usare solo .equals () invece di ==?
MatrixFrog,

246
Sono contento di essere un programmatore C #.

87
@Will: C # ha alcuni gotcha molto simili. Vedi blogs.msdn.com/jmstall/archive/2005/03/06/386064.aspx
spookylukey

373

Citando Neil Fraser (guarda la fine di quella pagina),

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

(in Java, ma il comportamento è apparentemente lo stesso in JavaScript e Python). Il risultato è lasciato come esercizio al lettore.

EDITED: Fintanto che siamo in materia considerare anche questo:

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

42
+1. Per qualche motivo, lo trovo divertente e non riesco a smettere di ridacchiare.
uscita

153
Per fortuna C # non permette tale follia ...Control cannot leave the body of a finally clause
Richard Ev

64
Questo ritorna, falso, vero? Può sembrare un WTF (e forse lo è), ma io vivo secondo la regola: alla fine vince sempre, a meno che tu non abbia fatto il crash della Macchina prima.
Michael Stum

28
Per essere onesti, incolpo la bella spiegazione di TDWTF per ricordare che alla fine vince sempre a meno che non si strappi il cavo di alimentazione: thedailywtf.com/Articles/My-Tales.aspx
Michael Stum

22
Non sono sicuro di cosa dovrebbe restituire il codice in questo caso. Ma sono assolutamente sicuro che non si deve mettere returnin finallyclausola.
jfs,

325

APL (diverso da TUTTO), la possibilità di scrivere qualsiasi programma in una sola riga.

ad es. Conway's Game of Life in una riga in APL :

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

Se quella linea non è WTF, allora niente lo è!

Ed ecco un video


19
Adoro APL. Ah, le gioie di passare un intero pomeriggio a scrivere mezza riga di codice! La prima cosa che farò quando avrò una tastiera in cui posso programmare quali lettere vengono visualizzate è riacquistare di nuovo me stesso con APL.
Daniel C. Sobral,

24
Sembra una lingua per i greci.
Esko,

45
@Erik: c'è gioia nel scrivere il codice che riguarda esclusivamente ciò che vuoi e non come arrivarci. Di esprimere il tuo codice come una singola espressione. È come l'ultimo taglio perfetto di katana. Certo, in una vera battaglia preferirei avere una pistola.
Daniel C. Sobral,

7
@Daniel: passi un intero pomeriggio a scrivere una riga di codice ... e un'intera settimana a leggere una riga di codice. ;-)
Jürgen A. Erhard,

93
APL sarebbe fantastico da vedere in un film d'azione di fantascienza. Posso immaginare qualcuno seduto ad un terminale a tre colori che mormora "Rimodella il vettore missilistico nemico ... trasponi ... pi volte il logaritmo ... vota - e - esegui!" seguito da esplosioni e tifo.
Joey Adams,

321

Le cose strane per cui si possono usare i template C ++, meglio dimostrate da "Letterali analogici multidimensionali" che usano i template per calcolare l'area delle forme "disegnate". Il seguente codice è C ++ valido per un rettangolo 3x3

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

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

Oppure, un altro esempio 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
Mentre i letterali analogici di Eelis sono fantastici, sono una strana caratteristica del linguaggio o solo uno strano modo di usare una funzione?

85
Il vero WTF sarà l'errore del compilatore generato da uno di quelli non validi.
Andrew McGregor,

6
Quanto è malato ... svegliami di nuovo quando esiste una versione di AnalogLiterals che supporta la rotazione letterale attorno agli assi X, Y e Z in Eclipse ... ora questo darebbe alla "programmazione visiva" un nuovo significato reale.
TheBlastOne,

2
L'ordinamento di o's, L e | è importante?
Ming-Tang,

4
L'ordinamento è importante, poiché i modelli fanno un uso creativo del sovraccarico dell'operatore (non farlo con il codice reale, l'uso improprio degli operatori rende il codice difficile da leggere)
josefx,

292

Molte variabili integrate di Perl:

  • $#- no un commento!
  • $0, $$e$? - proprio come le variabili shell con lo stesso nome
  • , $&e$' - strane variabili corrispondenti
  • $" e $, - strane variabili per i separatori di campi elenco e output
  • $!- come errnoun numero mastrerror(errno) come una stringa
  • $_- la variabile invisibile, sempre usata e mai vista
  • $#_ - numero indice dell'ultimo argomento della subroutine ... forse
  • @_ - i (non) nomi della funzione corrente ... forse
  • $@ - l'ultima eccezione sollevata
  • %:: - la tabella dei simboli
  • $:, $^, $~, $-, E $=- a che fare con formati di output
  • $.e $%- numero della riga di input, numero della pagina di output
  • $/e $\- separatori di record di input e output
  • $| - controller di buffering di output
  • $[- cambia la base dell'array da 0 in base a 1 in base a 42: WHEEE!
  • $}- niente affatto, stranamente!
  • $<, $>, $(, $)- UID e GID reali ed efficaci
  • @ISA - nomi delle superclassi dirette del pacchetto corrente
  • $^T - tempo di avvio dello script in secondi di epoca
  • $^O - nome del sistema operativo corrente
  • $^V - quale versione di Perl è questa

C'è molto di più da dove provengono. Leggi l'elenco completo qui .


83
La $[variabile è la più malvagia di tutte.
Brad Gilbert,

24
Lo apprezzerei sicuramente se Perl 6 fosse qualcosa su cui potrei scrivere il codice senza dover controllare perldoc perlvarogni cinque secondi. (Anche se lo confesso che la metà delle volte lo controllo pensando "So che c'è una variabile speciale che può fare questo per me, non ricordo quale ..." = P)
Chris Lutz

17
Il problema use English;è che influisce sulle prestazioni di RegExp. Non sto inventando. perldoc.perl.org/English.html#PERFORMANCE
Dave Webb

13
@Dave: non è un problema a causa dell'opzione -no_match_vars nella pagina che hai collegato. @Brad: $ [è COSÌ malvagio. L'intenzione è cattiva, sì, ma non funziona nemmeno! @Artem: da perlvar "Gli identificatori Perl che iniziano con cifre, caratteri di controllo o caratteri di punteggiatura sono esenti dagli effetti della dichiarazione del pacchetto e sono sempre costretti a trovarsi nel pacchetto principale; sono inoltre esenti da rigorosi errori 'var'. Ciò significa che @ $ verrebbe creato e assegnato senza errori anche sotto stress. Ugh!
RJ

4
@Brian: Come proponi di apprendere la sintassi quando la stessa documentazione ufficiale afferma che ci sono circostanze in cui l'interprete Perl indovina euristicamente cosa significa una sequenza di caratteri? Ad esempio /$foo[bar]/, la [bar]parte è una classe di caratteri o un pedice dell'array @foo? Grep perldata per la risposta terrificante.
j_random_hacker,

289

PHP gestisce i valori numerici nelle stringhe . Vedi questa risposta precedente a una domanda diversa per tutti i dettagli ma, in breve:

"01a4" != "001a4"

Se hai due stringhe che contengono un numero diverso di caratteri, non possono essere considerate uguali. Gli zeri iniziali sono importanti perché si tratta di stringhe e non di numeri.

"01e4" == "001e4"

A PHP non piacciono le stringhe. Sta cercando qualsiasi scusa che può trovare per trattare i tuoi valori come numeri. Cambia leggermente i caratteri esadecimali in quelle stringhe e improvvisamente PHP decide che queste non sono più stringhe, sono numeri in notazione scientifica (a PHP non importa che tu abbia usato le virgolette) e sono equivalenti perché gli zeri iniziali vengono ignorati per i numeri. Per rafforzare questo punto scoprirai che PHP valuta anche "01e4" == "10000"come vero perché si tratta di numeri con valori equivalenti. Questo è un comportamento documentato, semplicemente poco sensato.


56
Basta usare === e! ==. Che dovrebbe essere usato comunque a meno che non sia necessario un confronto di tipo libero.
Dykam,

14
@Dykam, se segui il link alla risposta più completa vedrai che ho indirizzato l'uso dell'operatore ===.
Dan Dyer,

18
La digitazione debole colpisce ancora!
Gillonba,

43
Ho sempre saputo che PHP era un peccato. Fino ad ora non mi ero reso conto che fosse un peccato imperdonabile: D
Thomas Eding,

2
Dovrebbero le persone tecnologiche usare === in qualsiasi libro di programmazione o tutorial. Nota aggiunta: su un'app PHP scritta male sono riuscita a fornire come password tutto ciò che è stato analizzato con lo stesso numero.
Pepijn,

282

Diamo un voto a tutte le lingue (come PL / I) che hanno cercato di eliminare le parole riservate.

Dove altro potresti legalmente scrivere espressioni così divertenti come:

IF IF THEN THEN = ELSE ELSE ELSE = THEN

( IF, THEN, ELSESono i nomi delle variabili)

o

IF IF THEN THEN ELSE ELSE

( IFè una variabile THENe ELSEsono subroutine)


1
@quark: questa è una risposta separata a questa! ;) ... (e sì, puoi programmare con l'inglese, basta distribuirlo come .ppt ad altri sviluppatori.;)
Macke,

28
@RoadieRich un gruppo di bufali non è esplicitamente di Buffalo, sono solo bufali anonimi.
Jürgen A. Erhard,

18
John, dove James aveva avuto, aveva avuto, aveva avuto un effetto migliore sull'insegnante.
GameFreak,

4
L'altro giorno ho visto alcuni produttori di insegne all'esterno di una fabbrica di gelateria Ben e Jerrys. Ho criticato il loro lavoro, ho detto loro che non c'era abbastanza spazio tra ben e e e e e e jerrys.
Tom Gullen,

9
Forse sarà necessario per i futuri programmi temporali. SE POI = ORA && DOVE = QUI QUANDO = POI ALTRO ORA = ALTRO ORA
Kelly S. francese

282

La 'caratteristica' di conversione ottale JavaScript è buona da conoscere:

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

Maggiori dettagli qui .


60
Rimasi bloccato su un bug che funzionava con tutti i numeri tranne 8 e 9 !! Stava impazzendo !!! Grazie Brian!
Faruz,

10
@Yada Non intendi ottale? L'esadecimale è 0x.
luiscubal,

48
Ed è per questo che parseInt accetta un argomento extra (facoltativo) :).
LiraNuna,

10
0 iniziale indica un numero ottale. poiché 8 non è una cifra ottale valida, il risultato deve essere 0.
devio

22
... e parseInt ('010') -> 8 solo per confonderti.
Richard Gadsden,

213

Il dispositivo di Duff in C!

In C si può intrecciare un do / while con un'istruzione switch. Ecco un esempio di memcpy usando questo metodo:

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);
    }
}

9
Il dispositivo di Duff è probabilmente una buona ragione per cui l'istruzione switch non ha un'interruzione di default ;-) Tuttavia, non ho ancora visto nessun altro buon uso di switch e loop interlacciati, ma probabilmente ce n'è uno. Oh aspetta, sì, c'è un altro uso: coroutine e protothread.
Frunsi,

16
@frunsi: "Il dispositivo di Duff è probabilmente una buona ragione per cui l'istruzione switch non ha un'interruzione di default" - Rendi sempre il caso comune predefinito. Non direi esattamente questo è il caso comune ..
BlueRaja - Danny Pflughoeft

6
@mcv probabilmente è più semplice se provi a leggerlo come codice assembly, ovvero whilealla fine è un (condizionale) di JMPnuovo a do, il che spiega perché puoi saltare il doe finire comunque nel ciclo.
wds,

14
Tieni presente che il dispositivo Duff generalmente produce codice WORSE rispetto alla normale istruzione di loop per i compilatori moderni, che sanno come (meglio) eseguire lo srotolamento in loop di quanto tu possa fare a mano.
Billy ONeal

37
@frunsi: Duff stesso, pubblicandolo, ha affermato qualcosa del genere: "Questo fornisce sicuramente un argomento nella discussione se l'interruttore dovrebbe cadere per impostazione predefinita, ma non sono sicuro che l'argomento sia pro o contro."
SF.

204

Algol passa per nome (illustrato usando la sintassi 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
Se ci pensate, in realtà ha una sorta di senso contorto
RCIX

90
Questo è l'ultimo "passaggio per riferimento".
Dykam,

3
È possibile a Scala ( def f(j : => int))
Dario,

10
Quindi questo è qualcosa del genere ... 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
In realtà è piuttosto semplice: si genera un piccolo pezzo di codice (di solito chiamato "thunk", quindi il mio gioco di parole sopra) che calcola l'indirizzo risultante dall'espressione, in questo caso e un [i]. Un puntatore a questa funzione viene passato alla funzione chiamata, che quindi la utilizza per calcolare l'indirizzo corrente ogni volta che si accede al parametro.
Richard Pennington,

189

In Python:

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

Non un WTF, ma una funzione utile.


176
Vorrei che ogni altra lingua avesse questa funzione
vava

32
Come con quasi tutte le fantastiche funzionalità di Python, sembra che Guido abbia appena ALGOL-ized la sintassi di una fantastica funzionalità di Lisp. :-)
Ken

4
Geoffrey, è una funzionalità, e (10 > 5 > 1) != ((10 > 5) > 1)in Python.
sastanin,

18
Inoltre, valuta solo una volta, quindi (funct_a(5)+5 > b > funct_a(5))chiama solo funct_a(5)una volta. È una GRANDE funzionalità!
Khelben

57
@Khelben: No, funct_averrà chiamato due volte in questo esempio. In b > funct_a(5) > cesso verrà chiamato solo una volta, invece di b > funct_a(5) and funct_a(5) > c.
Baffe Boyois,

189

In Java:

int[] numbers() {
  return null;
}

Può essere scritto come:

int numbers() [] {
  return null;
}

23
Wow! Vorrei poter essere una mosca sul muro quando è stata progettata quella sintassi dell'array!
Adam Paynter,

29
Odio dirlo, ma quello del WTF è un'estensione coerente del sistema di tipo C. Se alle funzioni C fosse permesso di restituire le matrici, ecco come sarebbe. Quella più bella è una violazione della coerenza per renderla più leggibile. Proprio come "const char * var" vs "char const * var".
Gordon Wrigley,

15
@Adam - In realtà ha senso se si considera che la dichiarazione delle variabili consente allo stesso modo "int stuff []" e "int [] stuff". Lasciano semplicemente funzionare le stesse regole per la dichiarazione del metodo.
Brandon Yarbrough,

2
@lImbus: in realtà, const T*e T const*sono equivalenti, è T* constquello che rappresenta il puntatore. Inoltre, odio i caratteri sans.
Simon Buchan,

3
Dopo tutto, numbers()[2]è una dichiarazione legale.
badp,

184

INTERCAL è probabilmente il miglior compendio di funzionalità linguistiche più strane. Il mio preferito è l' istruzione COMEFROM che è (quasi) l'opposto di GOTO.

COMEFROM è all'incirca l'opposto di GOTO in quanto può portare lo stato di esecuzione da qualsiasi punto arbitrario nel codice a un'istruzione COMEFROM. Il punto nel codice in cui si verifica il trasferimento dello stato viene generalmente assegnato come parametro a COMEFROM. Se il trasferimento avviene prima o dopo l'istruzione nel punto di trasferimento specificato dipende dalla lingua utilizzata. A seconda della lingua utilizzata, più COMEFROM che fanno riferimento allo stesso punto di partenza possono essere non validi, non deterministici, essere eseguiti in una sorta di priorità definita o persino indurre un'esecuzione parallela o simultanea come visto in Threaded Intercal. Un semplice esempio di un'istruzione "COMEFROM x" è un'etichetta x (che non deve essere posizionata fisicamente in alcun punto vicino al corrispondente COMEFROM) che funge da "botola". Quando l'esecuzione del codice raggiunge l'etichetta, il controllo viene passato all'istruzione che segue COMEFROM. L'effetto di questo è principalmente quello di rendere estremamente difficile il debug (e la comprensione del flusso di controllo del programma), poiché non vi è alcuna indicazione vicino all'etichetta che il controllo salti misteriosamente a un altro punto del programma.


16
Abbastanza male - trasforma le etichette in GOTO. Sembra che una caratteristica della lingua che gli hacker
chiedano

114
Ok, ma INTERCAL dovrebbe essere divertente - questo non è davvero un "gotcha" sorprendente. Il compilatore INTERCAL può effettivamente rifiutare di compilare il programma se non si utilizza il PLEASEmodificatore abbastanza spesso!
Groo

10
Sembra AOP :)
Akuhn

6
Ciò che mi stupisce di più è che nell'analisi dei requisiti di sistema nel "World of Commercial TI", i COMEFROM sono effettivamente utilizzati nei file di testo che descrivono i casi d'uso. (seriamente: alcuni analisti qui hanno ritardato una vasta migrazione aziendale a OpenOffice anziché all'ufficio di MS perché il primo non poteva correttamente riferire un "comefrom" con la granularità richiesta in un link)
jsbueno

5
Groo: è peggio. Usa PLEASE troppo frequentemente e si rifiuta di compilare il tuo programma perché stai rovistando (C-INTERCAL richiede tra il 33% e il 66% delle istruzioni per avere modificatori PLEASE).
Vatine,

160

Non proprio una caratteristica del linguaggio, ma un difetto di implementazione: alcuni primi compilatori Fortran implementavano costanti usando un pool costante. Tutti i parametri sono stati passati per riferimento. Se hai chiamato una funzione, ad es

f(1)

Il compilatore passerebbe l'indirizzo della costante 1 nel pool di costanti alla funzione. Se si assegna un valore al parametro nella funzione, si cambierà il valore (in questo caso il valore 1) a livello globale nel programma. Ha causato qualche graffio alla testa.


124
Ooh. Quindi 2+2 può eguagliare 5(per valori molto grandi 2ovviamente!).
Alok Singhal,

12
ehm, quale valore di 2 renderebbe "2 + 2" == "5"? Non so che nessun valore intero 2 possa assumere per essere vero.
Aaron,

36
@earlz: ho il sospetto che sarebbe finito come un valore integrale, di qualunque schema di bit. D'altra parte, probabilmente potresti impostare da 5 a 4 in questo modo (quindi 2+2sarebbe uguale 5per piccoli valori di 5).
David Thornley,

18
Mi scusi, Alok, ma stiamo parlando dei primi FORTRAN. Non sarà vero 2 + 2 = 5; sarà un errore di sintassi. Ciò che sarà vero è 2 + 2 .EQ. 5.
David Thornley,

3
In Haskell il seguente frammento valuta 5: "let 2 + 2 = 5 in 2 + 2" :)
Tirpen

153

Non so se può essere considerata una funzionalità del linguaggio, ma, in C ++, quasi ogni errore del compilatore relativo ai modelli fornisce una buona quantità di WTF a molti programmatori C ++ in tutto il mondo su base giornaliera :)


15
Va bene, la maggior parte del codice relativo ai modelli crea già molti WTF in tutto il mondo.
Joris Timmermans,

43
Oh, vieni ora. riferimento indefinito 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 *) 'È perfettamente leggibile!
Matt Greer,

10
Una volta ho avuto un errore del compilatore relativo al modello di cinque righe, la più breve delle quali era diciassette mila caratteri (il classico errore "nessuna corrispondenza per x", in un programma profondamente ispirato). Questo è il WTF, non la caratteristica in primo luogo, i modelli sono meravigliosi.
Andrew McGregor,

111
Anche se non ci sono errori, prova a trovare quali funzioni impiegano più tempo con il tuo profiler. Oh guarda, è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
Penso che questo si adatti qui: controlla STLFilt su bdsoft.com/tools/stlfilt.html per rendere leggibile l'output.
foraidt

150

I molti spazi dei nomi di C:

typedef int i;

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

O con personaggi:

typedef char c;

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

Come diavolo si compila senza ambiguità !?
Earlz,

13
+1 Gli identificatori di tag per enumerazioni e strutture sono la parte più confusa di C imho. Poche persone capiscono perché l'idioma per scrivere un puntatore a una struttura si presenta così.
Tadeusz A. Kadłubowski il

11
Si compila perché ognuno di questi ha uno spazio dei nomi inequivocabile a causa del contesto.
Andrew McGregor,

149

Direi che l'intera cosa degli spazi bianchi di Python è la mia più grande caratteristica di WTF. È vero, ti ci abitui più o meno dopo un po 'e i moderni editor lo rendono facile da gestire, ma anche dopo lo sviluppo del pitone principalmente a tempo pieno per l'anno passato, sono ancora convinto che fosse una cattiva idea. Ho letto tutto il ragionamento alla base, ma onestamente, mi ostacola la mia produttività. Non di molto, ma è ancora una sbavatura sotto la sella.

modificare: giudicare dai commenti, alcune persone sembrano pensare che non mi piace rientrare nel mio codice. Questa è una valutazione errata. Ho sempre indentato il mio codice, non importa quale sia la lingua e se sono costretto o meno. Quello che non mi piace è che è il rientro che definisce in quale blocco si trova una riga di codice. Preferisco i delimitatori espliciti per quello. Tra le altre ragioni, trovo che i delimitatori espliciti rendano più semplice tagliare e incollare il codice.

Ad esempio, se ho un blocco con rientro di 4 spazi e lo incollo alla fine di un blocco con rientro di 8 spazi, il mio editor (tutti gli editor?) Non ha idea se il codice incollato appartiene al blocco di 8 spazi o all'esterno bloccare. OTOH, se ho delimitatori espliciti è ovvio a quale blocco appartiene il codice e come dovrebbe essere (ri) rientrato - lo fa cercando in modo intelligente i delimitatori di blocco.

modifica 2: alcune persone che forniscono commenti sembrano pensare che questa sia una caratteristica che odio o che ritenga che Python sia un linguaggio scadente. Ancora una volta, non è vero. Anche se non mi piace così tanto, non è questo il punto. La domanda riguarda la strana caratteristica del linguaggio, e penso che sia strano, in quanto si tratta di qualcosa che molto, pochissime (ma> 0) lingue usano.


63
se interferisce con la tua produttività, il tuo codice non Python non può essere molto leggibile ...
Tor Valamo

27
Che lingua hai usato prima di Python? Come hai potuto lavorare con altre persone e non indentare quella lingua? Come si può tollerare un codice non indentato in qualsiasi lingua? Hai lavorato in una stanza piena di geni che non avevano bisogno di segnali visivi nel codice sorgente?
S.Lott

53
+1 Non potrei essere più d'accordo, se il mio editor (Emacs) non è in grado di indentare il mio codice in base a qualcosa di distinto (come parentesi graffe / inizio, fine / nome) automaticamente, è seriamente sciocco. Praticamente qualsiasi refactoring che faresti con una funzione "più grande" può essere davvero una brutta esperienza.
Dmitry

83
Ecco il problema: con qualsiasi altra lingua, posso evidenziare un blocco di codice e farlo rientrare correttamente da qualsiasi editor. Ma poiché lo spazio bianco è per definizione il rientro corretto, si perde quell'abilità in Python. Quindi è più difficile spostare il codice o riformattare le cose. E per la persona che afferma che l'OP è la "prima persona a dichiarare che si trattava di un problema", ho dovuto mantenere un po 'di codice Python per un po' e ora userò qualsiasi linguaggio su Python proprio per questo motivo.
Kendall Helmstetter Gelner,

38
Non mi dispiace lo spazio bianco in Python. Il WTF è che non viene applicato in modo coerente. Puoi mescolare livelli e schede di rientro, purché siano coerenti con i loro fratelli. Quindi il primo livello di rientro può essere uno spazio e il secondo può essere due TAB, e questo non è un errore di sintassi.
Vale a dire il

138

Ho faticato un po 'su questo:

1;

In perl, i moduli devono restituire qualcosa di vero .


29
Alcuni moduli possono restituire valori in base alle operazioni di runtime. Se ritorni sempre vero, non devi essere per nulla creativo
Anonimo

8
Se la mia memoria Perl mi serve correttamente, il ritorno true da un modulo indica che il modulo è stato caricato correttamente. Restituire un valore falso significava che qualcosa non andava e impediva l'esecuzione del programma (se non rilevato).
Barry Brown,

Anche questa è un'istruzione C valida, non viene restituito nulla.
sigjuice,

24
Mark Dominus ha scritto: "Ho usato molto raramente il 'Cogito ergo sum';che, come tutti sanno, è evidentemente vero in tutti i possibili universi. Ciò garantisce la massima portabilità".
Greg Bacon,

PHP <?=1;?>restituisce 1. <?=true;?>restituisce 1. <?=false;?>restituisce null.
Talvi Watia,

135

Sono sorpreso che nessuno abbia menzionato i costrutti a 7 loop di 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

Perché attaccare un! di fronte al vostro condizionale è modo troppo complicato!


47
Avrebbero dovuto farlo " Whilee Whend", dal momento che ci sono alcune persone che pronunciano la parola "while" con l'approssimativo velare labeless senza voce. E ovviamente si allinea meglio, e il codice che fa la fila è carino.
dreamlax,

43
Perché ti comporti in modo così strano?
Erik Forbes,

48
Wow. Divento un po 'nostalgico quando ci penso. La prima volta che ho mai usato VB è tornato come un bambino di 9 anni. Vengo dalla Svezia, e all'epoca non conoscevo molto bene l'inglese. Ora, c'è una parola svedese chiamata "vänd" che sostanzialmente significa "tornare indietro" e che è pronunciata in modo simile a "wend". Per questo motivo ho pensato che avesse molto senso ... :)
Emil H,

61
! non è in VB, è "Non". O è? Sì, non lo è!, Ma non.
brianary

7
Sì, "Wend" è una parola inglese, che significa andare o procedere in qualche modo ( google.com/search?q=define%3A+wend ). Non sono sicuro che ciò aiuti o faccia male.
Michael Myers

134

Per chi non lo sapesse, bcè un "linguaggio di calcolatrice di precisione arbitrario", e lo uso abbastanza spesso per calcoli rapidi, in particolare quando i numeri coinvolti sono grandi ( $è il prompt):

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

bcè stato un comando Unix standard per molto tempo.

Ora per la "funzione WTF". Questo è da man bc(enfasi mia):

quit : quando viene letta l'istruzione quit, il processore bc viene terminato, indipendentemente da dove si trova l'istruzione quit. Ad esempio, "if (0 == 1) quit" farà terminare bc.

halt : l'istruzione halt (un'estensione) è un'istruzione eseguita che provoca la chiusura del processore bc solo quando viene eseguita. Ad esempio, "if (0 == 1) halt" non farà terminare bc perché l'arresto non viene eseguito.


41
Uso Haskell per questa roba.
Thomas Eding,

8
Calcolatrice Google?
igul222,

7
Ho iniziato a usare Python da solo e Google Calculator è bello se sei online. Ma lo usavo bcprima e volevo scrivere bcnel mio post a causa delle grandi citazioni dalla pagina man.
Alok Singhal,

6
@Brian, allora ti piacerà: echo '[q]sa[ln0=aln256%Pln256/snlbx]sb3135071790101768542287578439snlbxq'|dc(anche se potresti già saperlo).
Alok Singhal,

2
Uso irb (Ruby Interactive Shell). Ma in passato, ho sempre cercato dc - come bc, ma usa il reverse polish. Geektastic!
tragomaskhalos,

134

Mi sono sempre chiesto perché il programma più semplice fosse:

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

Considerando che potrebbe essere:

print "Hello World!"

Forse questo è per spaventare gli studenti di informatica in primo luogo ...


34
In alcune lingue, "Hello World!" è un programma valido.
David Thornley,

31
@SoMoS: nella maggior parte dei linguaggi dinamici come Python, Ruby o Perl, stampa "Hello World!" o qualche variazione minore (es. put invece di print) è un programma valido e completo.
Dave Kirby,

36
@Loadmaster: l'implicazione era che "tutto il codice appartiene a una classe" o "tutto il codice appartiene a una funzione" sono vincoli inutili
Jimmy,

19
Solo perché un linguaggio impone l'uso degli oggetti, non significa che venga utilizzato per una corretta programmazione orientata agli oggetti. È perfettamente possibile programmare in modo procedurale in Java o C #. Ecco a cosa servono i metodi statici.
jdmichal,

68
Adoro le persone che pensano che OOP significhi che tutto dovrebbe essere un oggetto.
Tor Valamo,

132

JavaScript è orientato agli oggetti, giusto? Quindi i metodi in esecuzione su stringhe e numeri letterali dovrebbero funzionare. Mi piace "hello".toUpperCase()e 3.toString(). Si scopre che il secondo è un errore di sintassi, perché? Perché il parser si aspetta che un numero seguito da un punto sia letterale in virgola mobile. Questo non è il WTF, il WTF è che devi solo aggiungere un altro punto per farlo funzionare:

3..toString()

Il motivo è che il letterale 3.viene interpretato come 3.0e 3.0.toString()funziona bene.


8
Funziona in questo modo anche in Python (prova 3..__add__(4)). Poi di nuovo penso che (3).__add__(4)sia un modo molto meno
dannoso

49
Puoi semplicemente fare (3) .toString ()
Joseph Montanez il

13
@ Gorilla3D: sì, ma non è una strana caratteristica del linguaggio, vero?
Theo,

25
3.0.toString()mi fa prudere gli occhi.
Ben Blank,

18
127.0.0.1.toInt ()
berkus,

130

In JavaScript:

2 == [2]

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

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

Fortunatamente le persone gentili su stackoverflow.com mi hanno spiegato tutto: perché 2 == [2] in JavaScript?


6
Ecco perché dovresti usare ===invece.
Gumbo,

10
Ciò è utile tra l'altro, se si dispone di una funzione che restituisce un numero e si desidera restituire alcuni metadati aggiuntivi, è possibile restituire [numero] con alcuni campi aggiuntivi aggiunti. Il codice semplice non saprà mai che non è un numero reale e un altro codice può ottenere i metadati richiesti.
Andrey Shchekin,

36
@Andrey tranne che se dovessi mai mantenere un codice che fa quello che mi suggerisci, vorrei molto presto la morte del suo autore.
Bretone

@Andrey, è un'ottima idea! Puoi anche usare Number(n)qualcosa di simile. Purtroppo in entrambe le nostre soluzioni si ===rompe = (.
Xavi il

5
+1: Mi sono considerato un programmatore esperto di js e non ne ho mai saputo nulla: D
Thomas Eding

126

La mia più grande caratteristica odiata è qualsiasi sintassi del file di configurazione che includa la logica condizionale. Questo genere di cose è diffuso nel mondo Java (Ant, Maven, ecc. Sai chi sei!).

Finisci per programmare in un linguaggio ac ** p, con debugging limitato e supporto editor limitato.

Se hai bisogno di logica nella tua configurazione, l'approccio "Pythonic" di codificare la configurazione in un linguaggio reale è molto meglio.


24
Tcl ha reinventato molto prima della nascita di Python e Lisp l'ha inventato prima. Quindi non chiamiamolo Pythonic, chiamiamolo Emacs-ish.
Slebetman,

46
Chiamiamolo giusto.
mletterle,

30
AMEN. Se la tua configurazione o il linguaggio di compilazione sono completati, stai sbagliando. Ti sto guardando CMake / autotools.
Joseph Garvin,

16
Questo è esattamente ciò per cui è stata progettata Lua, in origine
Ruota dentata

1
Bene, se il tuo codice è in Python, avere il tuo file di configurazione come file Python è un'ottima idea, perché devi solo importare il file e leggere gli attributi del modulo. E ottieni la potenza completa al 100% di Python nel tuo file di configurazione.
asmeurer

113

powerbasic (www.powerbasic.com) include la direttiva del compilatore:

# BLOAT {bloatsize}

ciò aumenta la dimensione dell'eseguibile compilato di <bloatsize>byte. questo è stato inserito nel compilatore nel caso in cui alle persone che creano l'eseguibile non piaccia la piccola dimensione dell'eseguibile generato. fa sembrare EXE più grande competere con linguaggi di programmazione gonfiati :)


9
Haha Yuk. Ho sentito parlare di sviluppatori che rallentano deliberatamente alcune operazioni (ad esempio una ricerca) perché aiutano le persone a credere che stia davvero facendo qualcosa. Cosa simile suppongo.
David

42
Questo mi ricorda qualcosa che ho letto di recente. Stavano testando un FPS e decisero di aumentare il numero di punti feriti dei cattivi. Quindi hanno chiesto ai tester come erano le IA e hanno giurato che era molto più intelligente. Ma l'IA non era cambiata, ma solo i punti ferita. Le persone hanno una certa narrazione sul mondo nelle loro teste e se capisci e abbini le loro aspettative, assumeranno semplicemente che convalida la loro narrazione.
Nate CK,

5
Aggiungevo molti rallentamenti extra ai miei programmi per far sembrare che stessero facendo qualcosa di complicato. Di nuovo alle elementari, cioè.
Matti Virkkunen,

3
A scuola avevamo 80286 macchine e in realtà dovevo scrivere alcune routine di output dello schermo in assemblea per ottenere una velocità ragionevole (cioè non strisciare).
Berkus,

7
@Nate CK, se l'IA vive abbastanza a lungo da mostrare la sua IA, potrebbe effettivamente essere più intelligente, mentre prima potrebbe essere morta troppo rapidamente per dimostrarlo.
zzzzBov,
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.