Killer準ユニークなプログラミング言語の機能[終了]


25

新しいプログラミング言語を学習するとき、あなたが知っている他のプログラミング言語でそれを持ちたいと思う言語機能に出くわすことがあります。

あなたにとって非常に新しいことを学んだときに、他のプログラミング言語が持っていたことを望んでいるいくつかの言語機能は何ですか。

この例は、PythonまたはC#のジェネレーターです。他の例としては、Pythonのリスト内包表記、C ++のテンプレート、.NETのLINQ、Haskellの遅延評価などがあります。

まったく新しい、あなたにとって啓発的な、他にどんなユニークな言語機能がありますか?古いプログラミング言語には、ユニークで時代遅れになった他の機能がありますか?

回答:


25

Haskellの実質的にすべて

  • モナド。はい-驚くほど簡単なパーサー、IO、リストの操作などを簡単にする大きな怖い言葉(一般的なパターンに気づいたら)
  • 矢印。上級ユーザーも同じです;)
  • ラムダなどの標準的なもの
  • カリー化機能
  • 代数データ型
  • パターンマッチング

などなど。

PS。はい。誰かが尋ねたら私はHaskellのファンです。


12
公平を期すために、そのリストのほとんどにMLクレジットを与える必要があります。
明白な

1
さて-モナドと矢印IIRCを除く。しかし、彼らはまだユニークです
マチェイピエチョトカ

downvoteの特定の理由は?
マチェイピエチョトカ

2
パターンマッチングの場合は+1。他の人に見せてもらえません。天才だと思う。
バリーブラウン

必須steve-yegge.blogspot.com/2010/12/…)。ところで、私はラムダが一意であるとはほとんど考えていませんでした、Python、C#、javascriptなど。モナド?他のほとんどの言語では、これをチェーンと呼んでいます。jqueryコアは、本質的にHTML / DOMおよびAJAXモナド(Google:jQuery.fn)の1つの大規模なセットです。カレーは最近では比較的一般的です。
エヴァンプライス

21

Lispマクロ。

Lispマクロ言語はLispであり、便宜上、いくつかの事前定義された構文機能を備えています。それらを使用すると、オブジェクトの向きのスタイルの選択やPrologのような決定論的なマッチングなど、主要な機能を言語に追加できます。これにより、setfマクロが可能になります。これは、概念的に非常に強力なマクロです。 (setf A B)つまり、評価Aするとが得られB、好きな制限に拡張できます。

C ++テンプレートのメタプログラミングも同様の機能を備えていますが、通常のC ++とは大幅に異なる言語です。


+1いつかLisp方言でプログラムできるようになることを願っています。
オリバーワイラー

C ++のテンプレート[怖い笑い]を経由して@Helper ...
mlvljr

@mlvjr:あなたは怖いです。
デビッドソーンリー

実際、それはあなたが言語でこれまでに必要とする唯一のすぐに使える機能です。Lispマクロを使用すると、他のすべての可能な機能を後で追加できます。
SKロジック

18

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秒かかりました。


Javaには注釈があり、それらの目的と構文は似ていますが、動作が大きく異なります
-Casebash

1
+1:Pythonのデコレーターは、言語の他のほとんどの機能よりも感銘を受けました。彼らは非常に美しくシンプルです!
アダムペインター

たぶんあなたは私たちと簡単な例を共有できますか?Pythonが正直であることは知りません。
ShdNx

@ShdNx、例を追加しました。
grokus

1
呼び出しの一部として開始時刻を計算するべきではありませんか?
明らかに

14

キャストvoid*C.あなたには、生のバイトにすべてをキャストし、行うことができますあなたが望むものは何でも、これらのデータを。

(はい、今日ではそれはだユニークな...)


1
.Net言語のオブジェクトは非常に似ています。タイプセーフなどのみ
Maciej Piechotka

多くの言語でオブジェクトにキャストできます。主な問題は、多くの言語は、プリミティブやオブジェクトを分けることである
Casebash

5
@Maciej:.NETでも、実際にプリミティブをObjectにキャストすることはできません。あなたはそれらを箱に入れます、そしてそれは全く異なる獣です。また、それはまだにキャストとは全く違うのですvoid*...
ディーン・ハーディング

1
PointerPascalおよびObject Pascalでのキャストも同じことを行います。
フランクシェラー

1
@DeanHarding:さて-Cでは、あなたはint64_t常に安全にキャストできないものを持っていますvoid *(遅くごめんなさい-2年-返信)。
マチェイピエチョトカ

12

Pythonでの収量

Python(と私はC#を信じています)では、yieldステートメントで関数の実行を一時停止し、値を返し、後続の呼び出しで、関数を中断したところから再開する(呼び出し間で状態を保持して)いわゆるジェネレーターを定義できます。これは、関数の現在の値(非常に一般的)のみに関心がある値の長いリストを生成するのに最適です。メモリ内の非常に限られたスペースのみを占有しながら、潜在的に無限に長いシーケンスを構築できます。


1
利回りはすでに質問に記載されています。
トリニダード

これはBCPLにまでさかのぼります。
ピーターテイラー

8

ラムダ式(クロージャー、ネストされた関数、匿名メソッド、それらを呼び出すもの)。

私は最初にそれらをPerlで見つけて、すぐにそれらを愛し、他の言語にはなぜないのか疑問に思いました。最近では、それほどユニークではないようです。PHPでさえ、なんとかしてそれらをハックすることができました。しかし、それらは当時は半ユニークでした。


5
Lispに戻る限り、ユニークです。Lispは、2番目に古いプログラミング言語です。;-)
マイケルH.

-1:半一意ではありません
Casebash


7

Delphiのセットは非常に便利で、ほとんど名前付きブール配列です。32個のチェックボックスを含む設定フォームを保存するのに非常に便利です。しかし、それらはすべて同じ集合理論関数(すなわち、差、交差、結合)を持っています。

それらがファッションから落ちたかどうかはわかりませんが、私はいつもそれらを使用しています。


素敵ですが、Javaに実装するのは簡単ではありません。たとえば、boolean []?
マークC

ええ、できますが、次のように簡潔だとは思いません:TForm =(FF_1500 = 1、FF_CA251 = 5、FF_UB04 = 6、FF_MA10 = 7); TFormSet = TFormのセット;
ピーターターナー

7

送る

アーランから。別のスレッドに非同期でメッセージを送信します。

Expr1 ! Expr2

受け取る

アーランから。別のスレッドからメッセージを受信します。

receive
    Pattern1 [when GuardSeq1] ->
        Body1;
    ...;
    PatternN [when GuardSeqN] ->
        BodyN
end

5

C#プロパティ

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

2
はい、彼らは優れていますが、これは悪い例です。ゲッター/セッターが実際に何か特別なことをし、C#バージョンのドキュメント化が少なければ、その差ははるかに小さくなります。
バートヴァンヒューケロム

1
私の上司はC#の自動プロパティに強く反対しており、それについて議論があるときはいつでも、私たちのどちらも他方が正しいか間違っているのかを見ることができません。コードが非常にきれいになり、長い目で見れば時間を大幅に節約できるので、私はそれらが大好きです。
mbillard

2
人々がゲッターとセッターをいたるところに持っていくようにこれを許可しないでください。オブジェクトに対するアクションとして意味のあるゲッターとセッターのみを使用する必要があります。
デビッドソーンリー

3
彼らは、彼らは自動プロパティと呼ばれている、C#のプロパティと呼ばれていない
ジャコ・プリトリアス

1
最近では、自動プロパティが非常に一般的です。Python、Objective-C ...
Casebash

5

Cのユニオン

私はこれらを自分で作成するのに十分なCを書いていないと正直に言うことはできませんが、他のコードを使って作業しました。

ネットワーキングやバイナリデータストレージなどの生のビット/バイトを操作するアプリケーションで、異なるデータの混合をパッケージ化することになります。強く型付けされた言語では、同等のことを行う簡単な方法はありません。

免責事項:

ユニオンは場合によっては非常に役立ちますが、タイプセーフではないため、ほとんどの高レベル言語では見つかりません。IEでは、ユニオンを使用して変数の境界を越えてデータをブリードできます(タイプセーフの世界では大きな違いはありません)。大きな力には大きな責任が伴います。


2
正当な理由で私見。データを再解釈することは、自分で徒歩で撮影する美しい方法です(en.wikipedia.org/wiki/Aliasing_(computing))。私見で明示的な変換を使用する方が良い。正しいやり方の組合は私見代数データ型です。
マチェイピエチョトカ

@Maciej必要な免責事項を追加しました。ただし、ユニオンを使用することの詳細な知識がないため、ユニオンを使用することの危険性を正確に説明しているかどうかはわかりません。私が知っているのは、コードを使用するのを見たところでは、同等の高レベル言語よりもはるかに簡潔で作業しやすいことです。
エヴァンプレイス

問題は、Cが「高レベル言語」(単に低レベルの高レベル言語)であることです。K&R C以降、より高速で移植可能なコードを使用できるようにする多くのルールを取得します。代償として、コンパイラーはさまざまなことを想定でき、一部は混乱する場合があります。ほとんどのunion使用は、いくつかはよくイディオム(技術的に正しいものではないが)を安全にサポートされている-を参照してcellperformance.beyond3d.com/articles/2006/06/...を(それがポインタ組合ができるだけでなく、偽のそれを持つよりpoblemですが)。
マチェイピエチョトカ

Delphiはその延長recordサポート組合に構文:in_addr = record case integer of 0: (S_un_b: SunB); 1: (S_un_w: SunW); 2: (S_addr: u_long); end;
フランクShearar

5

私はRubyunless修飾子が本当に好きです。それはとても自然に思え、コードなしではコードが非常に乱雑に見える多くのシナリオを置き換えます。

puts "All good" unless input.nil?

どうしてそんなこと好きじゃないの?:D


6
PerlはRubyの前にそれを持っていました。私も好き。
バリーブラウン

1
Nemerleには、同様のキーワードがunlessあり、when伝統的に使用される最も一般的な分岐シナリオを置き換えますif/else
MattDavey

5

派手なpython引数の構文

これがどれほどユニークなのかはわかりませんが、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')

python docs(引数の解析のためにスクロールしてください)


1
+1 は、その前にあるすべてのオプションパラメータの値を渡す必要なく、リストの奥深くにパラメータを渡すことができるためです。
エスワルド

4

Cプリプロセッサ。ifdefsを使用して、異なるプラットフォームに共通のコードを記述することもできます。


2
独自の追加手順を実行し、すべての言語で動作するより優れたプリプロセッサがすぐに利用できます。
デビッドソーンリー

私はifdef、ifndefなどにかなり満足しています。
ern0

3

Objective-Cカテゴリ

カテゴリを使用すると、実行時にオブジェクトの機能を簡単に拡張できます(構成と継承を考えてください)。典型的な例は、NSStringクラスにスペルチェッカーを追加することです。

@interface NSString (SpellChecker)
- (BOOL) checkSpelling;
@end

メソッドのカテゴリの実装はその親実装をオーバーライドするため、影響の少ないバグ修正にも役立ちます。


1
C#で拡張メソッドに非常に似て
Casebash

2

RubyinjectメソッドとRuby 1.9のSymbol#to_proc機能を組み合わせることで、信じられないほど簡潔な(しかしまだ読みやすい)コードを作成できます。

例えば (1..10).inject(:+)

整数1〜10 => 55を合計します

このような例を見て、Rubyを学びたいと思いました。Rubyを始めたばかりです。


9
公平を期すと、injectはLisp、Haskellなどの言語のRubyのfold / foldl / foldrバージョンです。
mipadi

私は本当にこれをユニークとは呼びません。
デニース

1
質問のタイトルは「半一意」であり、一意ではありません。確かに、inject(またはmapなど)とSymbol#to_procの組み合わせによって提供されるコードの簡潔さは、C、Java、C ++などの主流言語をはるかに超えています。
-tcrosley

非常に簡潔です(そして、私はそれが好きです)が、それが次のようなものとそれほど違うかどうかはよくわかりません:Enumerable.Range(1、10).Aggregate((s、x)=> s + x); C#や他の言語から
FinnNk

1

JavaFX(RIP)のバインディングメカニズムバインドキーワードを使用すると、式の値に変数の値を結合して、あなたはすべてのそれらの醜いリスナー一切定型コードを取り除くことができます。

JavaFXは多くの点でかなり失敗しましたが、スクリプト言語の多くの機能が非常に優れていることがわかりました。


1

Dの文字列ミックスインとコンパイル時の関数評価は、非常にユニークなキラー機能です。はい、技術的には2つの機能ですが、本当の力はそれらを組み合わせることによってもたらされます。この組み合わせにより、コンパイル時にコードを文字列として生成する通常のD関数を記述し、このコードを任意のスコープにミックスして、通常のDコードとして評価できます。コードは完全に静的にコンパイルされ、手書きされたかのように正確に実行されます。この機能は、標準ライブラリのいくつかの厄介な状況を回避するためにも使用されます。


メソッドから自動的に推論される戻り値の型も好きです。
nawfal13年
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.