Fonction de langue la plus étrange


974

Quelle est, selon vous, la fonctionnalité de langage la plus surprenante, bizarre, étrange ou vraiment "WTF" que vous ayez rencontrée?

Veuillez une seule fonctionnalité par réponse.


5
@gablin Je pense que si vous combiniez des délimiteurs LISP avec des expressions rationnelles PERL en utilisant l'analyse javascript, vous
Talvi Watia

Réponses:


1859

En C, les tableaux peuvent être indexés comme suit:

a[10]

ce qui est très courant.

Cependant, la forme la moins connue (qui fonctionne vraiment!) Est:

10[a]

ce qui signifie la même chose que ci-dessus.


758
c'est parce que [10] signifie * (a + 10) ... et 10 [a] signifie * (10 + a) :)
Michel Gokan

77
N'oubliez pas "Hello World" [i]. Ou je ["Hello World"]
Richard Pennington

167
Ou, plus utilement, "0123456789abcdef" [x & 0xf]
Jauge

17
@frunsi: Cela fonctionne toujours comme prévu. L'ajout de pointeur n'est pas la même chose que l'ajout d'entiers simples sur les adresses. Il est commutative , peu importe quelle taille est le type en question.
R. Martinho Fernandes

12
@mcv - a [10] est identique à "* (a + 10)", où l'expression "a + 10" est une arithmétique de pointeur (et puisque a est un court, dans votre exemple, un + 10 signifie 'commencer à l'adresse de a, et déplacez 10 courts métrages, soit 20 octets). L'expression 10 [a] est interprétée comme "* (10 + a)", où "10 + a" est également l' arithmétique des pointeurs et est traitée exactement de la même manière.
Edan Maor

1292

En JavaScript:

 '5' + 3 gives '53'

Tandis que

 '5' - 3 gives 2

81
Je me souviens quand j'ai commencé à utiliser javascript en utilisant ce type de technique pour ajouter des nombres dans les chaînes: "111" - - "222" donne 333 tandis que "111" + "222" donne "111222".
Callum Rogers

112
+pour la concaténation de chaînes est horrible
Matteo Riva

416
+ pour concat n'est pas le problème. Faible frappe est.
FogleBird

270
@FogleBird Aucun des deux n'est vraiment le problème. C'est juste la combinaison des deux avec des règles de coercition incohérentes.
TM.

70
Donc, fondamentalement, + est concat quand une chaîne est impliquée. Pourquoi ne peuvent-ils pas coder quelque chose comme '123456' - 456 = '123'? Ce serait intéressant.
Jimmie Lin

872

En JavaScript, la construction suivante

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

retoursundefined est une erreur de syntaxe due à l'insertion sournoise de points-virgules implicites sur la nouvelle ligne après return. Les choses suivantes fonctionnent cependant comme vous vous en doutez:

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

Pire encore, celui-ci fonctionne également (dans Chrome, au moins):

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

Voici une variante du même problème qui ne génère pas d'erreur de syntaxe, échoue silencieusement:

return
    2 + 2;

225
L'insertion de points-virgules est l'une des parties les plus malveillantes de JavaScript.

230
Vous rencontrez toujours des problèmes lorsque vous concevez des fonctionnalités de langage autour de l'hypothèse que vos utilisateurs seront principalement des idiots.
Rob Van Dam

8
En fait, j'ai eu ce problème, étant moi-même développeur c #, j'ai mis l'accolade dans une nouvelle ligne. Cela m'a pris des heures pour réaliser quel était le problème. Même lorsque j'ai résolu le problème, je ne savais pas quel était le problème avant d'avoir lu votre réponse!
Fedor Hajdu du

24
Nick Retallack: Parce que, en raison de la syntaxe des crochets et des points-virgules de type C de JavaScript, il n'est pas du tout évident que les nouvelles lignes sont importantes.
Tamas Czinege

19
Si vous n'êtes pas censé utiliser le style C lors de la programmation en JavaScript, il était plutôt pervers pour les concepteurs de langage JavaScript de choisir une syntaxe de style C.
Ryan Lundy

795

Table de vérité 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

Source: Doug Crockford


237
Heureusement, Javascript a l'opérateur ===, alors.
Anonyme

65
Alors, à quoi ==sert le concepteur de langage?
Chris S

137
Confondre les gens.
Javier

123
Ce serait bien si on ==avait le sens de ===, et puis il y avait un autre opérateur, quelque chose comme ~=ça permettait la contrainte de type.
TM.

18
@Otto En fait, puisque nous geeking out, son exemple montre que == n'est pas symétrique. Pour le moment, je n'ai pas vu comment la commutativité serait spécifiée pour une relation binaire.
PeterAllenWebb

660

Trigraphes en C et C ++.

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

Cela s'imprimera LOL|, car le trigraphe ??!est converti en |.


71
Rapide! Dites à tous les programmeurs C / b /!
Esteban Küber

235
Les trigraphes sont incroyables, car vous pouvez être sûr que personne ne saura quoi que ce soit ??! signifiera de Google sans connaître le nom déjà.
zaratustra

56
Les trigraphes sont désactivées par défaut dans GCC.
sastanin

360
Ceux-ci vous permettent d'utiliser "l'opérateur WTF": (foo ()! = ERREUR) ??! ??! cerr << "Une erreur s'est produite" << endl;
user168715

57
Les trigraphes étaient un mal nécessaire lors de leur introduction. Certaines plates-formes ne comprenaient tout simplement pas certains caractères clés du langage, il s'agissait donc de «trigraphes» ou «vous ne pouvez pas avoir de période de fin de déclaration du compilateur C, alors utilisez l'assembleur». Consultez la description de Stroustrup dans "Le langage de programmation C ++".
Euro Micelli

573

Amusant avec la boxe automatique et le cache d'entiers 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

Explication

Un rapide coup d'œil au code source Java se présente comme suit:

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

Remarque: par IntegerCache.high défaut, 127sauf si défini par une propriété.

Ce qui se passe avec la boxe automatique, c'est qu'à la fois foo et bar le même objet entier récupéré du cache à moins qu'il ne soit explicitement créé: par exemple foo = new Integer(42), lors de la comparaison de l'égalité de référence, ils seront vrais plutôt que faux. La bonne façon de comparer la valeur entière utilise.equals;


31
Cela m'a pris quelques secondes pour voir pourquoi ... java doit conserver un pool d'instances Integer pour les valeurs comprises entre -128 et 128, sinon il alloue un nouvel Integer, non?
Mike Akers

18
Cependant, gardez à l'esprit que si vous spécifiez un nouvel entier (42), il n'utilisera pas l'instance du pool, donc foo == bar sera évalué à false
z -

10
J'utilise toujours des entiers au lieu de nombres entiers si possible, mais si je devais utiliser des nombres entiers pour une raison quelconque, devrais-je simplement utiliser .equals () au lieu de ==?
MatrixFrog

246
Je suis tellement content d'être un programmeur C #.

87
@Will: C # a des accrochages très similaires. Voir blogs.msdn.com/jmstall/archive/2005/03/06/386064.aspx
spookylukey

373

Citant Neil Fraser (regardez à la fin de cette page),

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

(en Java, mais le comportement est apparemment le même en JavaScript et en Python). Le résultat est laissé au lecteur comme exercice.

ÉDITÉ: Tant que nous sommes sur le sujet, considérez également ceci:

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

42
+1. Pour une raison quelconque, je trouve cela hilarant et je ne peux pas arrêter de rire.
2010

153
Heureusement, C # ne permet pas une telle folie ...Control cannot leave the body of a finally clause
Richard Ev

64
Cela revient, faux, n'est-ce pas? Cela peut ressembler à un WTF (et peut-être en est-il un), mais je respecte la règle: Enfin, toujours gagne, à moins que vous ne plantiez la Machine avant.
Michael Stum

28
Pour être honnête, je blâme la belle explication de TDWTF de se souvenir que finalement on gagne toujours à moins que vous ne tiriez sur le cordon d'alimentation: thedailywtf.com/Articles/My-Tales.aspx
Michael Stum

22
Je ne sais pas ce que le code devrait retourner dans ce cas. Mais je suis absolument sûr que vous ne devez pas mettre returndans la finallyclause.
jfs

325

APL (autre que TOUS), la possibilité d'écrire n'importe quel programme sur une seule ligne.

par exemple Game of Life de Conway en une seule ligne dans APL :

texte de remplacement http://catpad.net/michael/APLLife.gif

Si cette ligne n'est pas WTF, alors rien ne l'est!

Et voici une vidéo


19
J'adore APL. Ah, les joies de passer un après-midi entier à écrire une demi-ligne de code! La première chose que je ferai lorsque j'aurai un clavier où je pourrai programmer les lettres affichées est de me remettre à nouveau en contact avec APL.
Daniel C.Sobral

24
On dirait une langue pour les Grecs.
Esko

45
@Erik: Il y a de la joie à écrire du code qui concerne uniquement ce que vous voulez, et non comment y arriver. D'exprimer votre code en une seule expression. C'est comme l'ultime coupe parfaite de katana. Bien sûr, dans un vrai combat, je préfère avoir un pistolet.
Daniel C.Sobral

7
@Daniel: Vous passez un après-midi entier à écrire une ligne de code ... et une semaine entière à lire une ligne de code. ;-)
Jürgen A. Erhard

93
APL serait génial à voir dans un film d'action de science-fiction. Je peux imaginer quelqu'un assis à un terminal tricolore murmurant "Remodeler le vecteur de missile ennemi ... transposer ... logarithme pi fois ... passer au niveau supérieur - et - exécuter!" suivi d'explosions et d'applaudissements.
Joey Adams

321

Les choses étranges que les modèles C ++ peuvent être utilisées, le mieux est démontré par les "littéraux analogiques multidimensionnels" qui utilisent des modèles pour calculer la zone des formes "dessinées". Le code suivant est C ++ valide pour un rectangle 3x3

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

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

Ou, un autre exemple avec un cube 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
Bien que les littéraux analogiques d'Eelis soient excellents, sont-ils une caractéristique de langage étrange ou simplement une étrange façon d' utiliser une fonction?

85
Le vrai WTF sera l'erreur de compilation générée par l'un de ceux qui sont mal formés.
Andrew McGregor

6
Comment est-ce malade ... réveillez-moi à nouveau quand il existe une version d'AnalogLiterals qui prend en charge la rotation du littéral autour des axes X, Y et Z dans Eclipse ... maintenant, cela donnerait à la "programmation visuelle" une nouvelle signification réelle.
TheBlastOne

2
L'ordonnance des o et des L et des | est-elle importante?
Ming-Tang

4
L'ordre est important, car les modèles font un usage créatif de la surcharge des opérateurs (ne faites pas cela avec du vrai code, une mauvaise utilisation des opérateurs rend le code difficile à lire)
josefx

292

Les nombreuses variables intégrées de Perl:

  • $#- pas un commentaire!
  • $0,, $$et $?- tout comme les variables shell du même nom
  • , $&Et $'- variables d'appariement étranges
  • $"et $,- variables étranges pour les séparateurs de liste et de champ de sortie
  • $!- comme errnoun nombre mais strerror(errno)comme une chaîne
  • $_- la variable furtive, toujours utilisée et jamais vue
  • $#_ - numéro d'index du dernier argument du sous-programme ... peut-être
  • @_ - les (non) noms de la fonction courante ... peut-être
  • $@ - la dernière exception levée
  • %:: - la table des symboles
  • $:, $^, $~, $-Et $=- quelque chose à faire avec les formats de sortie
  • $.et $%- numéro de ligne d'entrée, numéro de page de sortie
  • $/et $\- séparateurs d'enregistrements d'entrée et de sortie
  • $| - contrôleur de tampon de sortie
  • $[- changez votre base de baies de 0 à 1 à 42: WHEEE!
  • $}- rien du tout, curieusement!
  • $<, $>, $(, $)- UID et GID réels et efficaces
  • @ISA - noms des superclasses directes du paquet courant
  • $^T - temps de démarrage du script en secondes d'époque
  • $^O - nom du système d'exploitation actuel
  • $^V - de quelle version de Perl s'agit-il

Il y a beaucoup plus d'où cela vient. Lisez la liste complète ici .


83
La $[variable est la plus mauvaise de toutes.
Brad Gilbert

24
J'apprécierais certainement si Perl 6 était quelque chose que je pouvais coder sans avoir à vérifier perldoc perlvartoutes les cinq secondes. (Bien que j'avoue que la moitié du temps je le vérifie en pensant "Je sais qu'il y a une variable spéciale qui peut le faire pour moi, je ne me souviens juste pas laquelle ..." = P)
Chris Lutz

17
Le problème use English;est qu'il affecte les performances de RegExp. Je ne l'invente pas. perldoc.perl.org/English.html#PERFORMANCE
Dave Webb

13
@Dave: ce n'est pas un problème en raison de l'option -no_match_vars dans la page que vous avez liée. @Brad: $ [est tellement diabolique. L'intention derrière c'est mal, oui, mais ça ne marche même pas! @Artem: from perlvar "Les identifiants Perl qui commencent par des chiffres, des caractères de contrôle ou des caractères de ponctuation sont exemptés des effets de la déclaration de package et sont toujours forcés d'être dans le package main; ils sont également exemptés des erreurs strictes de" vars "." Cela signifie donc que @ $ serait créé et attribué sans erreur, même sous restriction. Pouah!
rjh

4
@Brian: Comment proposez-vous d'apprendre la syntaxe lorsque la documentation officielle elle-même indique qu'il existe des circonstances où l'interpréteur Perl devine heuristement ce que signifie une séquence de caractères? Par exemple /$foo[bar]/, la [bar]pièce est-elle une classe de caractères ou un indice du tableau @foo? Grep perldata pour la réponse terrifiante.
j_random_hacker

289

Gestion par PHP des valeurs numériques dans les chaînes . Voir cette réponse précédente à une autre question pour plus de détails mais, en bref:

"01a4" != "001a4"

Si vous avez deux chaînes qui contiennent un nombre différent de caractères, elles ne peuvent pas être considérées comme égales. Les zéros en tête sont importants car ce sont des chaînes et non des nombres.

"01e4" == "001e4"

PHP n'aime pas les chaînes. Il cherche toutes les excuses qu'il peut trouver pour traiter vos valeurs comme des nombres. Modifiez légèrement les caractères hexadécimaux dans ces chaînes et soudainement PHP décide que ce ne sont plus des chaînes, ce sont des nombres en notation scientifique (PHP ne se soucie pas que vous utilisiez des guillemets) et ils sont équivalents car les zéros de tête sont ignorés pour les nombres. Pour renforcer ce point, vous constaterez que PHP est également évalué "01e4" == "10000"comme vrai car ce sont des nombres avec des valeurs équivalentes. C'est un comportement documenté, ce n'est tout simplement pas très sensé.


56
Utilisez simplement === et! ==. Qui devrait être utilisé de toute façon à moins qu'une comparaison de type lâche ne soit nécessaire.
Dykam

14
@Dykam, si vous suivez le lien vers la réponse plus complète, vous verrez que j'ai abordé l'utilisation de l'opérateur ===.
Dan Dyer

18
Une frappe faible frappe encore!
gillonba

43
J'ai toujours su que PHP était un péché. Jusqu'à présent, je ne savais pas que c'était un péché impardonnable: D
Thomas Eding

2
Ils devraient permettre aux techniciens d'utiliser === dans n'importe quel livre de programmation ou tutoriel. Note ajoutée: Sur une application PHP mal écrite, j'ai pu fournir comme mot de passe tout ce qui était analysé comme le même numéro.
Pepijn

282

Ayons un vote pour toutes les langues (comme PL / I) qui ont essayé de supprimer les mots réservés.

Où pourriez-vous légalement écrire des expressions amusantes telles que:

IF IF THEN THEN = ELSE ELSE ELSE = THEN

( IF, THEN, ELSESont les noms de variables)

ou

IF IF THEN THEN ELSE ELSE

( IFest une variable THENet ELSEsont des sous-programmes)


1
@quark: c'est une réponse distincte à cela! ;) ... (et oui, vous pouvez programmer avec l' anglais, déployer tout comme .ppt à d' autres développeurs;).
Macke

28
@RoadieRich un groupe de buffles n'est pas explicitement de Buffalo, ils sont juste des buffles indescriptibles.
Jürgen A. Erhard

18
John où James avait eu eu eu eu avait eu eu eu un meilleur effet sur le professeur.
GameFreak

4
L'autre jour, j'ai vu des fabricants d'enseignes à l'extérieur d'une fabrique de crème glacée Ben and jerrys. J'ai critiqué leur travail, je leur ai dit qu'il n'y avait pas assez d'espace entre ben et and and and and jerrys.
Tom Gullen

9
Peut-être sera-t-il nécessaire pour les futurs programmes temporels. SI ALORS = MAINTENANT && OERE = ICI ALORS QUAND = ALORS MAINTENANT = AILLEURS
Kelly S. French

282

La «fonctionnalité» de conversion octale JavaScript est une bonne chose à savoir:

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

Plus de détails ici .


60
Je suis resté coincé sur un bug que tous les nombres fonctionnaient sauf 8 et 9 !! Devenait fou !!! Merci Brian!
Faruz

10
@Yada Tu ne veux pas dire octal? Hexadécimal est 0x.
luiscubal

48
Et c'est pourquoi parseInt prend un argument supplémentaire (facultatif) :).
LiraNuna

10
0 en tête signifie le nombre octal. puisque 8 n'est pas un chiffre octal valide, le résultat doit être 0.
devio

22
... et parseInt ('010') -> 8 juste pour vous embrouiller.
Richard Gadsden

213

L'appareil de Duff en C!

En C, on peut entrelacer un do / while avec une instruction switch. Voici un exemple de memcpy utilisant cette méthode:

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
L'appareil de Duff est probablement une bonne raison pour que l'instruction switch n'ait pas de pause par défaut ;-) Cependant, je n'ai pas encore vu d'autre bon usage de switch et de boucle entrelacé - mais il y en a probablement un. Oh attendez, oui, il y a une autre utilisation: les coroutines et les protothreads.
Frunsi

16
@frunsi: "L'appareil de Duff est probablement une bonne raison pour que l'instruction switch n'ait pas de pause par défaut" - Faites toujours la casse par défaut. Je ne dirais pas exactement que c'est le cas commun ..
BlueRaja - Danny Pflughoeft

6
@mcv est probablement plus simple si vous essayez de le lire en tant que code assembleur, c.- whileà-d. à la fin est un JMPretour (conditionnel) à lado , ce qui explique pourquoi vous pouvez ignorer le doet toujours vous retrouver dans la boucle.
wds

14
Gardez à l'esprit que le périphérique de Duff produit généralement du code PIRE que l'instruction de boucle normale pour les compilateurs modernes, qui savent comment (mieux) boucler le déroulement que vous ne pouvez le faire à la main.
Billy ONeal

37
@frunsi: Duff lui-même, en le publiant, a affirmé quelque chose comme ceci: "Cela fournit certainement un argument dans la discussion si le commutateur doit échouer par défaut, mais je ne suis pas sûr si l'argument est pour ou contre."
SF.

204

Algol passe par nom (illustré en utilisant la syntaxe 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 vous y réfléchissez, cela a en fait une sorte de sens tordu
RCIX

90
Il s'agit de l'ultime "passe par référence".
Dykam

3
C'est possible à Scala ( def f(j : => int))
Dario

10
Donc, c'est quelque chose comme ça ... 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
C'est en fait assez simple: vous générez un petit morceau de code (généralement appelé "thunk", d'où mon jeu de mots ci-dessus) qui calcule l'adresse résultant de l'expression, dans ce cas & a [i]. Un pointeur vers cette fonction est transmis à la fonction appelée, qui l'utilise ensuite pour calculer l'adresse actuelle à chaque accès au paramètre.
Richard Pennington

189

En Python:

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

Pas un WTF, mais une fonctionnalité utile.


176
Je souhaite que toutes les autres langues aient cette fonctionnalité
vava

32
Comme avec à peu près toutes les fonctionnalités sympas de Python, il semble que Guido vient d'ALGOLISER la syntaxe d'une fonctionnalité Lisp sympa. :-)
Ken

4
Geoffrey, c'est une fonctionnalité, et (10 > 5 > 1) != ((10 > 5) > 1)en Python.
sastanin

18
De plus, il n'évalue qu'une seule fois, donc (funct_a(5)+5 > b > funct_a(5))n'appelle funct_a(5)qu'une seule fois. C'est une GRANDE fonctionnalité!
Khelben

57
@Khelben: Non, funct_asera appelé deux fois dans cet exemple. Dans b > funct_a(5) > cce ne sera appelée une fois que, par opposition à b > funct_a(5) and funct_a(5) > c.
Baffe Boyois

189

En Java:

int[] numbers() {
  return null;
}

Peut être écrit comme:

int numbers() [] {
  return null;
}

23
Hou la la! J'aimerais pouvoir être une mouche sur le mur lorsque cette syntaxe de tableau a été conçue!
Adam Paynter

29
Je déteste dire cela, mais le WTF est une extension cohérente du système de type C. Si les fonctions C étaient autorisées à renvoyer des tableaux, c'est à quoi cela ressemblerait. Le plus joli est une violation de cohérence pour le rendre plus lisible. Un peu comme "const char * var" vs "char const * var".
Gordon Wrigley

15
@Adam - Cela a du sens lorsque l'on considère que la déclaration de variable autorise à la fois "int stuff []" et "int [] stuff". Ils ont juste laissé les mêmes règles fonctionner pour la déclaration de méthode.
Brandon Yarbrough

2
@lImbus: En fait, const T*et T const*sont équivalents, c'est T* constce consts le pointeur. De plus, je déteste les polices sans.
Simon Buchan

3
Après tout, numbers()[2]c'est une déclaration légale.
badp

184

INTERCAL est probablement le meilleur recueil de fonctionnalités linguistiques les plus étranges. Mon préféré est la déclaration COMEFROM qui est (presque) l'opposé de GOTO.

COMEFROM est à peu près l'opposé de GOTO dans la mesure où il peut prendre l'état d'exécution de n'importe quel point arbitraire du code dans une instruction COMEFROM. Le point dans le code où le transfert d'état se produit est généralement donné comme paramètre à COMEFROM. Que le transfert ait lieu avant ou après l'instruction au point de transfert spécifié dépend de la langue utilisée. Selon le langage utilisé, plusieurs COMEFROM référençant le même point de départ peuvent être invalides, non déterministes, être exécutés dans une sorte de priorité définie, ou même induire une exécution parallèle ou autrement concurrente comme vu dans Threaded Intercal. Un exemple simple d'une instruction "COMEFROM x" est une étiquette x (qui n'a pas besoin d'être physiquement située n'importe où près de son COMEFROM correspondant) qui agit comme une "trappe". Lorsque l'exécution de code atteint l'étiquette, le contrôle est passé à l'instruction suivant COMEFROM. L'effet de ceci est principalement de rendre le débogage (et la compréhension du flux de contrôle du programme) extrêmement difficile, car il n'y a aucune indication près de l'étiquette que le contrôle sautera mystérieusement à un autre point du programme.


16
Tout à fait mal - transforme les étiquettes en GOTO. Cela ressemble à une fonctionnalité de langage que les pirates imploreraient ...
RCIX

114
D'accord, mais INTERCAL est censé être drôle - ce n'est pas vraiment un "gotcha" surprenant. Le compilateur INTERCAL peut en fait refuser de compiler le programme si vous n'utilisez pas PLEASEassez souvent le modificateur!
Groo

10
Sonne comme AOP :)
akuhn

6
Ce qui m'étonne le plus, c'est que dans l'analyse des exigences du système dans le "World of Commercial TI", les COMEFROM sont en fait utilisées dans des fichiers texte décrivant les cas d'utilisation. (sérieusement: certains analystes ici ont retardé une migration à l'échelle de l'entreprise vers OpenOffice au lieu de MS Office parce que le premier ne pouvait pas référencer correctement un "comefrom" avec la granularité requise dans un lien)
jsbueno

5
Groo: C'est pire. Utilisez PLEASE trop fréquemment et il refuse de compiler votre programme parce que vous vous effrayez (C-INTERCAL nécessite entre 33% et 66% des instructions pour avoir des modificateurs PLEASE).
Vatine du

160

Pas vraiment une fonctionnalité de langage, mais une faille d'implémentation: certains des premiers compilateurs Fortran ont implémenté des constantes en utilisant un pool constant. Tous les paramètres ont été transmis par référence. Si vous avez appelé une fonction, par exemple

f(1)

Le compilateur transmettrait l'adresse de la constante 1 dans le pool de constantes à la fonction. Si vous affectiez une valeur au paramètre dans la fonction, vous changeriez la valeur (dans ce cas la valeur de 1) globalement dans le programme. Causé quelques grattements de tête.


124
Ooh. On 2+2 peut alors égaler 5(pour de très grandes valeurs 2bien sûr!).
Alok Singhal

12
euh, quelle valeur de 2 ferait "2 + 2" == "5"? Je ne sais pas quelle valeur entière 2 peut prendre pour que ce soit vrai.
Aaron

36
@earlz: Je soupçonne que cela finirait par être une valeur intégrale, quelle que soit la configuration binaire. D'un autre côté, vous pouvez probablement définir 5 à 4 de cette façon (ce 2+2serait donc égal 5pour les petites valeurs de 5).
David Thornley

18
Excusez-moi, Alok, mais c'est au début de FORTRAN dont nous parlons. Ce ne sera pas vrai 2 + 2 = 5; ce sera une erreur de syntaxe. Ce qui sera vrai, c'est 2 + 2 .EQ. 5.
David Thornley

3
Dans Haskell, l'extrait de
code suivant vaut

153

Je ne sais pas si cela peut être considéré comme une fonctionnalité de langage, mais, en C ++, presque toutes les erreurs de compilation liées aux modèles fournissent quotidiennement une bonne quantité de WTF à de nombreux programmeurs C ++ du monde entier :)


15
C'est bien, la plupart du code lié aux modèles crée déjà de nombreux WTF dans le monde.
Joris Timmermans

43
Oh viens maintenant. référence non définie à `std :: basic_ostream <char, std :: char_traits <char>> & std :: operator << <std :: char_traits <char>> (std :: basic_ostream <char, std :: char_traits <char> > &, char const *) 'Est parfaitement lisible!
Matt Greer

10
J'ai eu une fois une erreur de compilateur liée au modèle qui était de cinq lignes, dont la plus courte était de dix-sept mille caractères (l'erreur classique «pas de correspondance pour x», dans un programme profondément basé sur des modèles). C'est le WTF, pas la fonctionnalité en premier lieu, les modèles sont merveilleux.
Andrew McGregor

111
Même s'il n'y a pas d'erreur, essayez de trouver les fonctions qui prennent le plus de temps avec votre profileur. Oh regarde, c'eststd::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
Je pense que cela convient ici: consultez STLFilt sur bdsoft.com/tools/stlfilt.html pour rendre la sortie lisible.
foraidt

150

Les nombreux espaces de noms de C:

typedef int i;

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

Ou avec des personnages:

typedef char c;

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

Comment diable cela compile-t-il sans ambiguïté!?
Earlz

13
+1 Les identificateurs de balises pour les énumérations et les structures sont la partie la plus déroutante de C imho. Peu de gens comprennent pourquoi l'idiome utilisé pour taper un pointeur sur une structure ressemble à cela.
Tadeusz A. Kadłubowski

11
Il compile parce que chacun de ces i a un espace de nom sans ambiguïté en raison du contexte.
Andrew McGregor

149

Je dirais que tout l'espace blanc de Python est ma meilleure fonctionnalité WTF. Certes, vous vous y habituez plus ou moins après un certain temps et les éditeurs modernes facilitent la gestion, mais même après le développement de python principalement à temps plein au cours de l'année écoulée, je suis toujours convaincu que c'était une mauvaise idée. J'ai lu tout le raisonnement derrière, mais honnêtement, cela nuit à ma productivité. Pas beaucoup, mais c'est toujours une bavure sous la selle.

edit: à en juger par les commentaires, certaines personnes semblent penser que je n'aime pas mettre en retrait mon code. C'est une évaluation incorrecte. J'ai toujours mis en retrait mon code, quelle que soit la langue et si je suis forcé ou non. Ce que je n'aime pas, c'est que c'est l'indentation qui définit le bloc dans lequel se trouve une ligne de code. Je préfère les délimiteurs explicites pour cela. Entre autres raisons, je trouve que les délimiteurs explicites facilitent la coupe et le collage de code.

Par exemple, si j'ai un bloc en retrait de 4 espaces et que je le colle à la fin d'un bloc en retrait de 8 espaces, mon éditeur (tous les éditeurs?) N'a aucune idée si le code collé appartient au bloc à 8 espaces ou à l'extérieur bloquer. OTOH, si j'ai des délimiteurs explicites, il est évident à quel bloc le code appartient et comment il doit être (ré) indenté - il le fait en recherchant intelligemment les délimiteurs de bloc.

edit 2: certaines personnes qui fournissent des commentaires semblent penser que c'est une fonctionnalité que je déteste ou qui, à mon avis, fait du python un langage pauvre. Encore une fois, ce n'est pas vrai. Bien que je n'aime pas beaucoup ça, c'est à côté de la question. La question porte sur la caractéristique de langage la plus étrange , et je pense que c'est étrange, car il s'agit de quelque chose de très, très peu (mais> 0) de langues.


63
si cela gêne votre productivité, alors votre code non-python ne peut pas être très lisible ...
Tor Valamo

27
Quelle langue utilisiez-vous avant Python? Comment avez-vous pu travailler avec d'autres personnes et ne pas mettre en retrait cette langue? Comment quelqu'un pourrait-il accepter du code non indenté dans n'importe quelle langue? Avez-vous travaillé dans une pièce pleine de génies qui n'avaient pas besoin d'indices visuels dans le code source?
S.Lott

53
+1 Je ne pourrais pas être plus d'accord, si mon éditeur (Emacs) ne peut pas indenter mon code en fonction de quelque chose de distinct (comme des accolades / commencer, terminer / vous l'appelez) automatiquement, c'est vraiment idiot. À peu près tout refactoring que vous feriez sur une fonction "plus grande" peut être une très mauvaise expérience.
Dmitry

83
Voici l'affaire - avec n'importe quel autre langage, je peux mettre en évidence un bloc de code et le mettre en retrait correctement par n'importe quel éditeur. Mais parce que les espaces blancs sont par définition la mise en retrait appropriée, vous perdez cette capacité en Python. Il est donc plus difficile de déplacer le code ou de refactoriser les choses. Et pour la personne qui prétend que l'OP est la "première personne à affirmer que c'était un problème", eh bien j'ai dû maintenir du code python pendant un certain temps et je vais maintenant utiliser n'importe quel langage sur python pour cette raison.
Kendall Helmstetter Gelner du

38
Cela ne me dérange pas l'espace blanc en Python. Le WTF est qu'il n'est pas appliqué de manière cohérente. Vous pouvez mélanger les niveaux de retrait et les onglets, tant qu'ils sont cohérents avec leurs frères et sœurs. Ainsi, le premier niveau de retrait peut être un espace et le second peut être deux tabulations, et ce n'est pas une erreur de syntaxe.
2010

138

J'ai un peu lutté à ce sujet:

1;

En perl, les modules doivent retourner quelque chose de vrai .


29
Certains modules peuvent renvoyer des valeurs basées sur des opérations d'exécution. Si vous retournez toujours vrai, vous n'avez pas besoin d'être créatif à ce sujet: returnvalues.useperl.at
Anonyme

8
Si ma mémoire Perl me sert correctement, le retour de true à partir d'un module indique que le module s'est correctement chargé. Renvoyer une valeur fausse signifiait que quelque chose n'allait pas et empêcherait le programme de s'exécuter (s'il n'était pas intercepté).
Barry Brown

Il s'agit également d'une instruction C valide, rien n'est retourné.
sigjuice

24
Mark Dominus a écrit: "J'ai très rarement utilisé 'Cogito ergo sum';ce qui, comme tout le monde le sait, est évidemment vrai dans tous les univers possibles. Cela garantit une portabilité maximale."
Greg Bacon

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

135

Je suis surpris que personne n'ait mentionné les constructions de boucle 7 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

Parce que coller un! devant votre conditionnel est bien trop compliqué!


47
Ils auraient dû le faire « Whileet Whend», car il y a des gens qui prononcent le mot «tandis que» avec l'approximant vélaire labialisé sans voix. Et bien sûr, cela s'aligne mieux et le code qui s'aligne est bien.
dreamlax

43
Pourquoi agissez-vous si bizarrement?
Erik Forbes

48
Sensationnel. Je deviens un peu nostalgique quand j'y pense. La première fois que j'ai utilisé VB, j'étais de retour à l'âge de 9 ans. Je viens de Suède et je n'étais pas très compétent en anglais à l'époque. Maintenant, il y a un mot suédois appelé "vänd" qui signifie essentiellement "revenir en arrière" et qui se prononce de manière similaire à "wend". Pour cette raison, je pensais que cela avait beaucoup de sens ... :)
Emil H

61
! n'est pas en VB, c'est "Non". Ou est-ce? Oui, non, non!, Mais pas.
Brian

7
Oui, "Wend" est un mot anglais, ce qui signifie aller ou suivre un cours ou un chemin ( google.com/search?q=define%3A+wend ). Je ne sais pas si cela aide ou fait mal.
Michael Myers

134

Pour ceux qui ne le savent pas, bcc'est un "langage de calculatrice à précision arbitraire", et je l'utilise assez souvent pour des calculs rapides, en particulier lorsque les nombres impliqués sont importants ( $est l'invite):

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

bcest une commande Unix standard depuis longtemps.

Maintenant pour la "fonctionnalité WTF". Cela vient de man bc(soulignement le mien):

quit : lorsque l'instruction quit est lue, le processeur bc est arrêté, quel que soit l'endroit où se trouve l'instruction quit. Par exemple, "if (0 == 1) quit" entraînera l'arrêt de bc.

halt : L'instruction halt (une extension) est une instruction exécutée qui provoque la fermeture du processeur bc uniquement lors de son exécution. Par exemple, "if (0 == 1) halt" n'entraînera pas l'arrêt de bc car l'arrêt n'est pas exécuté.


41
J'utilise Haskell pour ce genre de choses.
Thomas Eding

8
Calculatrice Google?
igul222

7
J'ai commencé à utiliser Python moi-même et la calculatrice Google est bien si vous êtes en ligne. Mais j'avais l'habitude d'utiliser bcavant cela, et je voulais en parler bcdans mon article en raison des grandes citations de la page de manuel.
Alok Singhal

6
@Brian, alors vous aimerez: echo '[q]sa[ln0=aln256%Pln256/snlbx]sb3135071790101768542287578439snlbxq'|dc(bien que vous le sachiez déjà).
Alok Singhal

2
J'utilise irb (shell interactif Ruby). Mais à l'époque, je recherchais toujours du DC comme le BC, mais j'utilise du polish inversé. Geektastic!
tragomaskhalos

134

Je me suis toujours demandé pourquoi le programme le plus simple était:

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

Alors que ça pourrait être:

print "Hello World!"

C'est peut-être pour effrayer les étudiants en informatique en premier lieu ...


34
Dans certaines langues, "Hello World!" est un programme valide.
David Thornley

31
@SoMoS: dans la plupart des langages dynamiques tels que Python, Ruby ou Perl, imprimez "Hello World!" ou une variation mineure (par exemple, met au lieu d'imprimer) est un programme valide et complet.
Dave Kirby

36
@Loadmaster: l'implication était que "tout le code appartient à une classe" ou "tout le code appartient à une fonction" sont des contraintes inutiles
Jimmy

19
Le fait qu'un langage impose l'utilisation d'objets ne signifie pas qu'il est utilisé pour une programmation orientée objet appropriée. Il est parfaitement possible de programmer de manière procédurale en Java ou en C #. C'est à cela que servent les méthodes statiques.
jdmichal

68
J'adore les gens qui pensent que la POO signifie que tout devrait être un objet.
Tor Valamo

132

JavaScript est orienté objet, non? Par conséquent, l'exécution de méthodes sur des chaînes et des nombres littéraux devrait fonctionner. Comme "hello".toUpperCase()et 3.toString(). Il s'avère que le second est une erreur de syntaxe, pourquoi? Parce que l'analyseur s'attend à ce qu'un nombre suivi d'un point soit un littéral à virgule flottante. Ce n'est pas le WTF, le WTF est que vous n'avez qu'à ajouter un autre point pour le faire fonctionner:

3..toString()

La raison en est que le littéral 3.est interprété comme 3.0, et 3.0.toString()fonctionne très bien.


8
Fonctionne également de cette façon en Python (essayez 3..__add__(4)). Là encore, je pense que (3).__add__(4)c'est une façon beaucoup moins endommagée par le cerveau de le faire :)
Badp

49
Vous pouvez simplement faire (3) .toString ()
Joseph Montanez

13
@ Gorilla3D: oui, mais ce n'est pas une caractéristique de langue étrange, n'est-ce pas?
Theo

25
3.0.toString()me démange les yeux.
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

Heureusement, les gens aimables de stackoverflow.com m'ont expliqué tout cela: pourquoi 2 == [2] en JavaScript?


6
C'est pourquoi vous devriez utiliser à la ===place.
Gumbo

10
C'est utile entre autres, si vous avez une fonction qui retourne un nombre et que vous souhaitez renvoyer des métadonnées supplémentaires avec elle, vous pouvez retourner [nombre] avec des champs supplémentaires ajoutés. Un code simple ne saura jamais qu'il ne s'agit pas d'un nombre réel, et un autre code peut obtenir les métadonnées requises.
Andrey Shchekin

36
@Andrey sauf que si jamais je dois maintenir un code qui fait ce que vous suggérez, je souhaiterais très bientôt la mort à son auteur.
Breton

@Andrey, c'est une excellente idée! Vous pouvez également utiliser Number(n)pour faire quelque chose de similaire. Malheureusement, dans nos deux solutions, les ===pauses = (.
Xavi

5
+1: Je me considère comme un programmeur js compétent, et je ne l'ai jamais su: D
Thomas Eding

126

Ma plus grande fonctionnalité la plus détestée est toute syntaxe de fichier de configuration qui inclut une logique conditionnelle. Ce genre de chose est répandu dans le monde Java (Ant, Maven, etc. Vous savez qui vous êtes!).

Vous venez de terminer la programmation en langage ac ** p, avec un débogage limité et un support d'édition limité.

Si vous avez besoin de logique dans votre configuration, l'approche "Pythonic" de codage de la configuration dans un langage réel est bien meilleure.


24
Tcl a réinventé cela bien avant la naissance de Python et Lisp l'a inventé avant cela. Alors ne l'appelons pas Pythonic, appelons-le Emacs-ish.
slebetman

46
Appelons ça juste.
mletterle

30
AMEN. Si votre langue de configuration ou de construction est complète, vous vous trompez. Je vous regarde CMake / autotools.
Joseph Garvin

16
C'est exactement pour cela que Lua a été conçu, à l'origine
Cogwheel

1
Eh bien, si votre code est en Python, avoir votre fichier de configuration en fichier Python est une excellente idée, car il vous suffit alors d'importer le fichier et de lire les attributs du module. Et vous obtenez la puissance 100% Turing complète de Python dans votre fichier de configuration.
asmeurer

113

powerbasic (www.powerbasic.com) inclut la directive du compilateur:

# BLOAT {bloatsize}

cela augmente la taille de l'exécutable compilé en <bloatsize>octets. cela a été mis dans le compilateur au cas où les personnes créant l'exécutable n'aiment pas la petite taille de l'exécutable généré. cela fait que l'EXE semble plus gros pour rivaliser avec les langages de programmation gonflés :)


9
Haha yuk. J'ai entendu parler de développeurs qui ralentissent délibérément certaines opérations (par exemple une recherche) car cela aide les gens à croire qu'il fait vraiment quelque chose. Chose similaire, je suppose.
David

42
Cela me rappelle quelque chose que j'ai lu récemment. Ils testaient un FPS et ont décidé d'augmenter le nombre de points de vie des méchants. Ensuite, ils ont demandé aux testeurs comment était leur IA, et ils ont juré que c'était beaucoup plus intelligent. Mais l'IA n'avait pas changé, juste les points de vie. Les gens ont un certain récit sur le monde dans leur tête, et si vous comprenez et répondez à leurs attentes, ils supposeront simplement qu'il valide leur récit.
Nate CK

5
J'avais l'habitude d'ajouter beaucoup de ralentissement supplémentaire à mes programmes pour leur donner l'air de faire quelque chose de compliqué. De retour à l'école primaire, bien sûr.
Matti Virkkunen

3
À l'école, nous avions 80286 machines et j'ai dû écrire des routines de sortie d'écran en assembleur pour obtenir une vitesse raisonnable (c'est-à-dire ne pas ramper).
berkus

7
@Nate CK, si l'IA vit assez longtemps pour montrer son IA, elle peut en fait être plus intelligente, alors qu'avant elle peut être morte trop rapidement pour le prouver.
zzzzBov
En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.