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.
language-agnostic
programming-languages
Robert Harvey
la source
la source
Réponses:
En C, les tableaux peuvent être indexés comme suit:
ce qui est très courant.
Cependant, la forme la moins connue (qui fonctionne vraiment!) Est:
ce qui signifie la même chose que ci-dessus.
la source
En JavaScript:
Tandis que
la source
+
pour la concaténation de chaînes est horribleEn JavaScript, la construction suivante
retoursest une erreur de syntaxe due à l'insertion sournoise de points-virgules implicites sur la nouvelle ligne aprèsundefined
return
. Les choses suivantes fonctionnent cependant comme vous vous en doutez:Pire encore, celui-ci fonctionne également (dans Chrome, au moins):
Voici une variante du même problème qui ne génère pas d'erreur de syntaxe, échoue silencieusement:
la source
Table de vérité JavaScript:
la source
==
sert le concepteur de langage?==
avait le sens de===
, et puis il y avait un autre opérateur, quelque chose comme~=
ça permettait la contrainte de type.Trigraphes en C et C ++.
Cela s'imprimera
LOL|
, car le trigraphe??!
est converti en|
.la source
Amusant avec la boxe automatique et le cache d'entiers en Java:
Explication
Un rapide coup d'œil au code source Java se présente comme suit:
Remarque: par
IntegerCache.high
défaut,127
sauf 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;
la source
Citant Neil Fraser (regardez à la fin de cette page),
(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:
la source
Control cannot leave the body of a finally clause
return
dans lafinally
clause.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
la source
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
Ou, un autre exemple avec un cube 3D:
la source
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$!
- commeerrno
un nombre maisstrerror(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-ilIl y a beaucoup plus d'où cela vient. Lisez la liste complète ici .
la source
$[
variable est la plus mauvaise de toutes.perldoc perlvar
toutes 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)use English;
est qu'il affecte les performances de RegExp. Je ne l'invente pas. perldoc.perl.org/English.html#PERFORMANCE/$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.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:
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.
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é.la source
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
,THEN
,ELSE
Sont les noms de variables)ou
(
IF
est une variableTHEN
etELSE
sont des sous-programmes)la source
La «fonctionnalité» de conversion octale JavaScript est une bonne chose à savoir:
Plus de détails ici .
la source
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:
la source
while
à-d. à la fin est unJMP
retour (conditionnel) à lado
, ce qui explique pourquoi vous pouvez ignorer ledo
et toujours vous retrouver dans la boucle.Algol passe par nom (illustré en utilisant la syntaxe C):
la source
def f(j : => int)
)... 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]; } }); }
?En Python:
Pas un WTF, mais une fonctionnalité utile.
la source
(10 > 5 > 1) != ((10 > 5) > 1)
en Python.(funct_a(5)+5 > b > funct_a(5))
n'appellefunct_a(5)
qu'une seule fois. C'est une GRANDE fonctionnalité!funct_a
sera appelé deux fois dans cet exemple. Dansb > funct_a(5) > c
ce ne sera appelée une fois que, par opposition àb > funct_a(5) and funct_a(5) > c
.En Java:
Peut être écrit comme:
la source
const T*
etT const*
sont équivalents, c'estT* const
ce consts le pointeur. De plus, je déteste les polices sans.numbers()[2]
c'est une déclaration légale.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.
la source
PLEASE
assez souvent le modificateur!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
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.
la source
2+2
peut alors égaler5
(pour de très grandes valeurs2
bien sûr!).2+2
serait donc égal5
pour les petites valeurs de5
).2 + 2 = 5
; ce sera une erreur de syntaxe. Ce qui sera vrai, c'est2 + 2 .EQ. 5
.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 :)
la source
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> >)
Les nombreux espaces de noms de C:
Ou avec des personnages:
la source
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.
la source
J'ai un peu lutté à ce sujet:
En perl, les modules doivent retourner quelque chose de vrai .
la source
'Cogito ergo sum';
ce qui, comme tout le monde le sait, est évidemment vrai dans tous les univers possibles. Cela garantit une portabilité maximale."<?=1;?>
renvoie 1.<?=true;?>
renvoie 1.<?=false;?>
renvoie null.Je suis surpris que personne n'ait mentionné les constructions de boucle 7 de Visual Basic .
Parce que coller un! devant votre conditionnel est bien trop compliqué!
la source
While
etWhend
», 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.Pour ceux qui ne le savent pas,
bc
c'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
est une commande Unix standard depuis longtemps.Maintenant pour la "fonctionnalité WTF". Cela vient de
man bc
(soulignement le mien):la source
bc
avant cela, et je voulais en parlerbc
dans mon article en raison des grandes citations de la page de manuel.echo '[q]sa[ln0=aln256%Pln256/snlbx]sb3135071790101768542287578439snlbxq'|dc
(bien que vous le sachiez déjà).Je me suis toujours demandé pourquoi le programme le plus simple était:
Alors que ça pourrait être:
C'est peut-être pour effrayer les étudiants en informatique en premier lieu ...
la source
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()
et3.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:La raison en est que le littéral
3.
est interprété comme3.0
, et3.0.toString()
fonctionne très bien.la source
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 :)3.0.toString()
me démange les yeux.En JavaScript:
Heureusement, les gens aimables de stackoverflow.com m'ont expliqué tout cela: pourquoi 2 == [2] en JavaScript?
la source
===
place.Number(n)
pour faire quelque chose de similaire. Malheureusement, dans nos deux solutions, les===
pauses = (.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.
la source
powerbasic (www.powerbasic.com) inclut la directive du compilateur:
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 :)la source