あなたの意見では、あなたが遭遇した最も驚くべき、奇妙な、奇妙な、または本当に「WTF」の言語機能は何ですか?
回答ごとに1つの機能のみを入力してください。
あなたの意見では、あなたが遭遇した最も驚くべき、奇妙な、奇妙な、または本当に「WTF」の言語機能は何ですか?
回答ごとに1つの機能のみを入力してください。
回答:
Cでは、配列に次のようにインデックスを付けることができます。
a[10]
これは非常に一般的です。
ただし、あまり知られていない形式(実際に機能します)は次のとおりです。
10[a]
これは上記と同じ意味です。
JavaScriptの場合:
'5' + 3 gives '53'
一方
'5' - 3 gives 2
+
文字列の連結は恐ろしい
JavaScriptでは、次の構文
return
{
id : 1234,
title : 'Tony the Pony'
};
リターンの後に改行に起因する卑劣な暗黙のセミコロン挿入に構文エラーですundefined
return
。ただし、以下は期待どおりに機能します。
return {
id : 1234,
title : 'Tony the Pony'
};
さらに悪いことに、これも機能します(少なくともChromeでは)。
return /*
*/{
id : 1234,
title : 'Tony the Pony'
};
構文エラーが発生しない同じ問題の変種は次のとおりです。ただ黙って失敗します。
return
2 + 2;
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
出典:Doug Crockford
==
、言語デザイナーの目にはどのような目的がありますか?
==
の意味があり===
、~=
タイプの強制を許可するような別の演算子があった場合、それは良いことです。
CおよびC ++の3文字表記。
int main() {
printf("LOL??!");
}
LOL|
トリグラフ??!
はに変換されるため、これは印刷され|
ます。
自動ボクシングと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
Javaソースコードをざっと見ると、次のことがわかります。
/**
* 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);
}
注: プロパティによって設定されない限り、IntegerCache.high
デフォルトは127
です。
自動ボクシングで何が起こるかは、fooとbarの両方が、明示的に作成されない限り、キャッシュから取得された同じ整数オブジェクトを使用foo = new Integer(42)
することです。整数値を比較する適切な方法は、.equals;
Neil Fraserの引用(そのページの最後を見てください)、
try {
return true;
} finally {
return false;
}
(Javaでは、動作はJavaScriptとPythonで明らかに同じです)。結果は読者への演習として残されます。
編集:この件については、次の点も考慮してください。
try {
throw new AssertionError();
} finally {
return false;
}
Control cannot leave the body of a finally clause
return
がfinally
条項に入れてはならないことを確信しています。
APL(そのすべてを除く)、任意のプログラムを1行で記述する機能。
たとえば、APLの1行でのConwayのLife of Game:
代替テキストhttp://catpad.net/michael/APLLife.gif
その行がWTFでなければ、何もありません!
C ++テンプレートを使用できる奇妙なことは、テンプレートを使用して「描画」された形状の面積を計算する「多次元アナログリテラル」で最もよく示されます。次のコードは、3x3の長方形に有効なC ++です。
#include"analogliterals.hpp"
using namespace analog_literals::symbols;
unsigned int c = ( o-----o
| !
! !
! !
o-----o ).area;
または、3Dキューブの別の例:
assert( ( o-------------o
|L \
| L \
| L \
| o-------------o
| ! !
! ! !
o | !
L | !
L | !
L| !
o-------------o ).volume == ( o-------------o
| !
! !
! !
o-------------o ).area * int(I-------------I) );
Perlの多くの組み込み変数:
$#
— コメントではありません!$0
、$$
と$?
-ちょうど同じ名前のシェル変数のよう$ˋ
、$&
、および$'
-奇妙なマッチング変数$"
and $,
—リストおよびセパレーターの奇妙な変数$!
— errno
数値のstrerror(errno)
ように、文字列のように$_
- ステルス変数は、常に使用して見たことがありません$#_
—最後のサブルーチン引数のインデックス番号...多分@_
—現在の関数の(非)名前...多分$@
—最後に発生した例外%::
—シンボルテーブル$:
、$^
、$~
、$-
、と$=
-出力形式とは何か$.
and $%
—入力行番号、出力ページ番号$/
and $\
—入力および出力レコード区切り記号$|
—出力バッファリングコントローラ$[
—アレイベースを0ベースから1ベースから42ベースに変更します。WHEEE!$}
— まったく何もない、奇妙なことに十分です!$<
、$>
、$(
、$)
-現実と効果的なUIDとGID@ISA
—現在のパッケージの直接のスーパークラスの名前$^T
—エポック秒単位のスクリプト起動時間$^O
—現在のオペレーティングシステム名$^V
—これはどのバージョンのPerlですか$[
変数は、それらすべての最も邪悪です。
perldoc perlvar
5秒ごとにチェックしなくてもコード化できるものであれば、間違いなく感謝します。(私は半分の時間を私がそれをチェックすることを認めると言いますが、「私のためにこれを行うことができる特別な変数があることを知っています、私はそれを覚えていません...」= P)
use English;
は、それがRegExpのパフォーマンスに影響を与えることです。私はこれを補っていません。 perldoc.perl.org/English.html#PERFORMANCE
/$foo[bar]/
その[bar]
部分は文字クラス@foo
ですか、配列の添え字ですか?恐ろしい答えのGrep perldata。
PHPによる文字列内の数値の処理。詳細については、別の質問に対するこの以前の回答を参照してください。
"01a4" != "001a4"
異なる数の文字を含む2つの文字列がある場合、それらは等しいとは見なされません。これらは数値ではなく文字列であるため、先行ゼロは重要です。
"01e4" == "001e4"
PHPは文字列を好みません。それはあなたの値を数値として扱うために見つけることができる言い訳を探しています。これらの文字列の16進文字を少し変更すると、突然PHPはこれらがもはや文字列ではないと判断し、科学表記法の数値(PHPは引用符の使用を気にしません)であり、先行ゼロは無視されるため同等です。この点を補強すると、PHPも"01e4" == "10000"
同等の値を持つ数値であるため、PHPもtrueと評価されることがわかります。これは文書化された動作であり、あまり賢明ではありません。
予約語を排除しようとしたすべての言語(PL / Iなど)に投票しましょう。
次のような面白い表現を合法的にどこに書けますか?
IF IF THEN THEN = ELSE ELSE ELSE = THEN
(IF
、THEN
、ELSE
変数名です)
または
IF IF THEN THEN ELSE ELSE
(IF
は変数でTHEN
ありELSE
、サブルーチンです)
JavaScriptの8進変換の「機能」は、知っておくと良いものです。
parseInt('06') // 6
parseInt('07') // 7
parseInt('08') // 0
parseInt('09') // 0
parseInt('10') // 10
詳細はこちら。
Cでは、switchステートメントでdo / whileをインターレースできます。このメソッドを使用したmemcpyの例を次に示します。
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);
}
}
while
最後のはへの(条件付き)JMP
バックdo
です。これにより、スキップdo
してループに入る理由を説明できます。
Algolは名前で渡します(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]);
}
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]; } }); }
ですか?
Pythonの場合:
>>> x=5
>>> 1<x<10
True
>>> 1<x<3
False
WTFではありませんが、便利な機能です。
(10 > 5 > 1) != ((10 > 5) > 1)
、Pythonでも。
(funct_a(5)+5 > b > funct_a(5))
はfunct_a(5)
1回だけなので、呼び出しは1回だけです。それは素晴らしい機能です!
funct_a
その例では2回呼び出されます。b > funct_a(5) > c
かかわらず、一度は対照的に、それだけで、呼び出されますb > funct_a(5) and funct_a(5) > c
。
Javaの場合:
int[] numbers() {
return null;
}
次のように書くことができます:
int numbers() [] {
return null;
}
const T*
とT const*
等価です、それはだT* const
、ポインタというconsts。また、私はフォントを嫌います。
numbers()[2]
法的声明です。
INTERCALは、おそらく最も奇妙な言語機能の概要です。私の個人的なお気に入りは、GOTOの(ほぼ)反対のCOMEFROMステートメントです。
COMEFROMは、コードの任意のポイントからCOMEFROMステートメントに実行状態を移すことができるという点で、GOTOのほぼ反対です。状態転送が発生するコード内のポイントは、通常、COMEFROMへのパラメーターとして指定されます。指定された転送ポイントでの指示の前または後に転送が行われるかどうかは、使用される言語によって異なります。使用する言語によっては、同じ出発点を参照する複数のCOMEFROMが無効であるか、非決定的であるか、ある種の定義された優先度で実行されるか、スレッドインターカルで見られるように並列実行または同時実行を誘導することさえあります。「COMEFROM x」ステートメントの簡単な例は、「トラップドア」として機能するラベルx(対応するCOMEFROMの近くに物理的に配置する必要がない)です。コードの実行がラベルに到達すると、COMEFROMに続くステートメントに制御が渡されます。ラベルの近くに制御が不可解にプログラムの別のポイントにジャンプするという表示がないため、これの効果は主にデバッグ(およびプログラムの制御フローの理解)を非常に困難にすることです。
PLEASE
修飾子を十分に使用しないと、プログラムのコンパイルを実際に拒否する可能性があります。
実際には言語機能ではありませんが、実装上の欠陥があります。初期のFortranコンパイラーは、定数プールを使用して定数を実装していました。すべてのパラメーターは参照によって渡されました。たとえば、関数を呼び出した場合
f(1)
コンパイラーは、定数プール内の定数1のアドレスを関数に渡します。関数のパラメーターに値を割り当てた場合、プログラムで値(この場合は1の値)をグローバルに変更します。頭を引っかいた。
2+2
できる等しく5
(の非常に大きな値のため2
、もちろん!)。
2+2
は等しく5
なります5
)。
2 + 2 = 5
。構文エラーになります。何が本当でしょうか2 + 2 .EQ. 5
。
言語機能と見なせるかどうかはわかりませんが、C ++では、テンプレートに関連するほとんどすべてのコンパイラエラーによって、世界中の多くのC ++プログラマにかなりの量のWTFが毎日提供されます:)
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> >)
Cの多くの名前空間:
typedef int i;
void foo()
{
struct i {i i;} i;
i: i.i = 3;
printf( "%i\n", i.i);
}
または文字で:
typedef char c;
void foo()
{
struct c {c c;} c;
c: c.c = 'c';
printf( "%c\n", c.c);
}
Pythonのホワイトスペース全体が私の最大のWTF機能だと思います。確かに、しばらくすると慣れてきますし、最新のエディターで簡単に処理できますが、過去1年間のほとんどのフルタイムのpython開発の後でも、それは悪い考えだと確信しています。私はその背後にあるすべての理由を読みましたが、正直なところ、それは私の生産性の邪魔になります。それほどではありませんが、それでもサドルの下のバリです。
編集:コメントから判断すると、コードをインデントしたくないと思う人もいます。それは間違った評価です。言語を問わず、また強制されているかどうかに関わらず、コードは常にインデントしています。私が気に入らないのは、コード行が含まれるブロックを定義するのがインデントであることです。そのためには、明示的な区切り文字を使用します。他の理由の中でも、明示的な区切り文字を使用すると、コードのカットアンドペーストが簡単になることがわかりました。
たとえば、4つのスペースがインデントされたブロックがあり、8つのスペースがインデントされているブロックの最後に貼り付けた場合、私のエディター(すべてのエディター?)は、貼り付けられたコードが8スペースブロックまたは外側のスペースに属しているかどうかわかりませんブロック。OTOH、私が明示的な区切り文字を持っている場合、コードが属するブロックとそれが(再)インデントされる方法は明らかです-ブロック区切り文字をインテリジェントに探すことでそうなります。
編集2:コメントを提供する一部の人々は、これは私が嫌いな機能であると思うか、Pythonを貧弱な言語にしていると思います。繰り返しますが、そうではありません。私はそれがあまり好きではありませんが、それは要点の外です。問題は最も奇妙な言語機能に関するものであり、これは非常に少数の(ただし> 0)言語を使用しているため、これは奇妙だと思います。
私はこれについて少し苦労しました:
1;
Perlでは、モジュールは何かtrueを返す必要があります。
'Cogito ergo sum';
誰もが知っているように、可能な限りすべての宇宙で自明であることがほとんど使用されていません。これにより、最大限の移植性が保証されます。」
<?=1;?>
は1を<?=true;?>
返します。1を<?=false;?>
返します。nullを返します。
Visual Basicの7つのループ構造について誰も言及していないことに驚いています。
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
こだわっているから!あなたの条件の前にある道あまりにも複雑!
While
そしてWhend
」にすべきだった。なぜなら、無声唇化されたベロア近似で「while」という単語を発音する人がいるからだ。そしてもちろん、それはより良く整列し、整列するコードは素晴らしいです。
知らない人のためにbc
、「任意精度の計算機言語」であり、特に関係する数値が大きい場合($
プロンプトが)は、迅速な計算に頻繁に使用します。
$ bc -lq
12^345
20774466823273785598434446955827049735727869127052322369317059031795\
19704325276892191015329301807037794598378537132233994613616420526484\
93077727371807711237016056649272805971389591721704273857856298577322\
13812114239610682963085721433938547031679267799296826048444696211521\
30457090778409728703018428147734622401526422774317612081074841839507\
864189781700150115308454681772032
bc
長い間、標準のUnixコマンドでした。
「WTF機能」について説明します。これはman bc
(私の強調)からです:
quit:quitステートメントが読み取られると、quitステートメントの場所に関係なく、bcプロセッサは終了します。 たとえば、「if(0 == 1)quit」はbcを終了させます。
halt:haltステートメント(拡張)は、bcプロセッサが実行された場合にのみ終了するように実行されるステートメントです。 たとえば、「if(0 == 1)halt」では、停止が実行されないため、bcは終了しません。
bc
、以前はそれを使用bc
していたため、manページからのすばらしい引用があったため、私の投稿について書きたかったのです。
echo '[q]sa[ln0=aln256%Pln256/snlbx]sb3135071790101768542287578439snlbxq'|dc
あなたはすでにこれを知っているかもしれませんが)。
私はいつも最も単純なプログラムがなぜなのか疑問に思っていました:
class HelloWorldApp {
public static void main(String[] args) {
System.out.println("Hello World!");
}
}
それが可能性があるのに対し:
print "Hello World!"
たぶん、これはそもそもコンピュータサイエンスの学生を怖がらせるためのものです...
JavaScriptはオブジェクト指向ですよね?したがって、リテラル文字列と数値に対してメソッドを実行すると機能するはずです。のよう"hello".toUpperCase()
に3.toString()
。2つ目は構文エラーであることが判明しました。なぜですか?パーサーは、ドットの後に続く数値が浮動小数点リテラルであることを期待しているためです。それはWTFではありません。WTFは、ドットを追加するだけで機能します。
3..toString()
その理由は、リテラル3.
がとして解釈され3.0
、3.0.toString()
正常に機能するためです。
3..__add__(4)
)。それからもう一度私(3).__add__(4)
はそれを行うためのはるかに少ない脳の損傷を受けた方法だと思います:)
3.0.toString()
目がかゆくなります。
JavaScriptの場合:
2 == [2]
// Even stranger
2 == [[[2]]]
// And down-right nutty
var a = { "abc" : 1 };
a[[[["abc"]]]] === a["abc"]; // this is also true
幸運なことに、stackoverflow.comの親切な人たちがすべてを説明してくれました。JavaScriptで 2 == [2]を使用するのはなぜですか。
===
代わりに使用する必要があります。
Number(n)
して同様のことを行うこともできます。残念ながら、当社のソリューションの両方で===
休憩=(。
私の最大の嫌いな機能は、条件付きロジックを含む構成ファイルの構文です。このようなことは、Javaの世界(Ant、Mavenなど)で蔓延しています。
結局、限られたデバッグと限られたエディタサポートで、ac ** p言語でプログラミングすることになります。
構成にロジックが必要な場合は、構成を実際の言語でコーディングする「Pythonの」アプローチの方がはるかに優れています。
powerbasic(www.powerbasic.com)にはコンパイラディレクティブが含まれています。
# BLOAT {bloatsize}
これにより、コンパイルされた実行可能ファイルのサイズが<bloatsize>
バイト単位で増加します。これは、実行可能ファイルを作成する人が生成された実行可能ファイルの小さなサイズが気に入らない場合に備えて、コンパイラに配置されました。EXEは肥大化したプログラミング言語と競合するために大きく見える:)