新しいプログラミング言語を学ぶとき、あなたはあなたがあなたが知っている他のプログラミング言語でそれがあったことを望む言語機能に出くわすことがあります。
初めて学習したときに、他のプログラミング言語に期待したい言語機能は何ですか。
この例は generators in PythonまたはC#です。他の例には、Pythonのリスト内包表記、C++のテンプレート、.NETのLINQ、Haskellの遅延評価などがあります。
まったく新しく啓発された、他にどのような独自の言語機能がありますか?ユニークで時代遅れになった古いプログラミング言語の他の機能はありますか?
Haskellのほとんどすべて
などなど。
PS。はい。誰かが尋ねたなら私はハスケルのファンボーイです。
LISPマクロ。
LISPマクロ言語はLISPであり、便宜上いくつかの事前定義された構文機能があります。それらを使用して、オブジェクトオリエンテーションスタイルの選択やPrologのような決定論的マッチングなど、主要な機能を言語に追加できます。これはsetf
マクロを可能にします。これは概念的に非常に強力なマクロです:(setf A B)
は、A
を評価するとB
が得られることを意味し、これを任意の制限に拡張できます。
C++テンプレートのメタプログラミングは同様の機能を備えていますが、通常のC++とは言語が大きく異なります。
Pythonのデコレータ。
デコレータを使用して、メモ化や関数のタイミングを実装するのは非常に簡単です。
関数タイマーの例。
class FuncTimer(object):
""" Time how much time a function takes """
def __init__(self, fn):
self.fn = fn
self.memo = {}
self.start_time = time.time()
def __call__(self, *args):
self.memo['return'] = self.fn(*args)
print("Function '%s' took %u seconds" % (self.fn.__name__, time.time() - self.start_time))
return self.memo['return']
時間を計りたい関数fooがある場合、これを行うことができます。
@FuncTimer
def foo():
# foo's implememtation goes here
次のようなものが表示されます
関数「foo」には3秒かかりました。
Cのvoid*
へのキャスト。すべてをrawバイトにキャストし、これらのデータで何でもを実行できます。
(はい、今日それはユニークです...)
Python(そして私はC#を信じています)では、yield
ステートメントで関数の実行を一時停止し、値を返し、その後の呼び出しで再起動する、いわゆるジェネレーターを定義できます。 (呼び出し間で状態が保持された)関数が中断した関数。これは、関数の現在の値(非常に一般的)だけに関心がある長い値のリストを生成するのに最適です。これにより、潜在的に無限にビルドできます。メモリ内の非常に限られたスペースを占有するだけの長いシーケンス。
ラムダ式(クロージャー、ネストされた関数、無名メソッド、それらを呼び出すものは何でも)。
私は最初にPerlでそれらに出会い、すぐにそれらを愛し、なぜ他の言語にそれらがないのか疑問に思いました。今日では、それはもうそれほど珍しいものではないと思います。でもPHPはなんとかしてそれらをハッキングすることに成功しました。しかし、それらは当時、かなりユニークでした。
Delphiのセットは非常に便利で、ほとんど名前の付いたブール配列です。 32個のチェックボックスがある設定フォームを保存するのに非常に便利です。しかし、それらはすべて同じセット理論関数(すなわち、差、交差、和集合)を持っています。
時代遅れかどうかはわかりませんが、いつも使っています。
Cの共用体
私はこれらを自分で作るのに十分なCを書いていないと正直に言うことはできませんが、他の人のコードを使って作業しました。
ネットワーキングやバイナリデータストレージなどの生のビット/バイトを操作するアプリケーションで、さまざまなデータの混合物をパッケージ化することになります。強く型付けされた言語では、同等のことを行う簡単な方法はありません。
免責事項:
ユニオンは非常に便利な場合もありますが、タイプセーフではないため、ほとんどの高級言語では見つかりません。 IEでは、共用体を使用して変数の境界を越えてデータを流すことができます(タイプセーフの世界では大きな違いはありません)。大きな力には大きな責任が伴います。
/// <summary>
/// Get ID
/// </summary>
public int ID
{
get; set;
}
対
(Java)
/**
* Name of user
*/
private String name;
/**
* Gets name of user
* @return Name of user
*/
public String getName() {
return this.name;
}
/**
* Sets name of user.
* @param name
*/
public void setName(final String name) {
this.name = name;
}
Rubyのnless修飾子が本当に好きです。それはとても自然に見え、コードなしではコードが非常に乱雑に見える多くのシナリオを置き換えます。
puts "All good" unless input.nil?
どうしてそんなに嫌いなの? :D
これがどれほどユニークであるかはわかりませんが、pythonでは、キーワードのペアを自動的に辞書に入れたり戻したりすることができます。リストと同じです:
def parrot(voltage, state='a stiff', action='voom', type='Norwegian Blue'):
print "-- This parrot wouldn't", action,
print "if you put", voltage, "volts through it."
print "-- Lovely plumage, the", type
print "-- It's", state, "!"
parrot(1000)
parrot(action = 'VOOOOOM', voltage = 1000000)
parrot('a thousand', state = 'pushing up the daisies')
parrot('a million', 'bereft of life', 'jump')
Cプリプロセッサ。 ifdefsを使用して、共通のコードを異なるプラットフォームに書き込むこともできます。
Objective-Cカテゴリ
カテゴリは、実行時にオブジェクトの機能を拡張する簡単な方法を提供します(構成と継承を比較してください)。古典的な例は、NSStringクラスにスペルチェッカーを追加することです。
@interface NSString (SpellChecker)
- (BOOL) checkSpelling;
@end
カテゴリのメソッドの実装がその親の実装をオーバーライドするため、影響の少ないバグ修正にも役立ちます。
Rubyのinjectメソッドと Symbol#to_proc 機能Ruby 1.9を使用すると、信じられないほど簡潔な(ただし読みやすい)コードを記述できます。
例えば(1..10).inject(:+)
1から10までの整数の合計=> 55
このような例を見て、Rubyを学びたくなりました。
The Binding Mechanism in JavaFX(R.I.P)。 bindキーワードを使用すると、変数の値を式の値にバインドし、醜いリスナーのボイラープレートコードをすべて取り除くことができます。
JavaFXは多くの点でかなり失敗しましたが、スクリプト言語の多くの機能が非常に優れていることがわかりました。
Dでの文字列ミックスインとコンパイル時関数の評価は、かなりユニークなキラー機能です。はい、技術的には2つの機能ですが、本当の力はそれらを組み合わせることから生まれます。この組み合わせにより、コンパイル時に文字列としてコードを生成する通常のD関数を記述し、このコードを任意のスコープに混合して、通常のDコードとして評価させることができます。コードは完全に静的にコンパイルされ、手書きのように正確に実行されます。この機能は、標準ライブラリの2つの厄介な状況を回避するためにも使用されます。