一般的な言語でどのような機能が必要ですか?もっと正確に言えば、「動的型付けが普及したい」というよりも、一般的にはまったく存在しないが、見たほうがいい機能を意味します。
17 に答える
私はしばしば、「観察可能」は優れたフィールド修飾子 (public、private、static など) になると考えてきました。
GameState {
observable int CurrentScore;
}
次に、他のクラスがそのプロパティのオブザーバーを宣言できます。
ScoreDisplay {
observe GameState.CurrentScore(int oldValue, int newValue) {
...do stuff...
}
}
コンパイラは CurrentScore プロパティへのすべてのアクセスを通知コードでラップし、オブザーバーは値が変更されるとすぐに通知されます。
確かに、ほとんどのプログラミング言語でイベント リスナーとプロパティ変更ハンドラーを使用して同じことを行うことができますが、これはお尻に大きな苦痛を与え、多くの断片的な配管が必要です。特に、必要な値を持つクラスの作成者でない場合はなおさらです。観察すること。その場合、通常はラッパー サブクラスを記述して、すべての操作を元のオブジェクトに委譲し、ミューテーター メソッドから変更イベントを送信する必要があります。コンパイラーは、なぜそのばかげた定型コードをすべて生成できないのでしょうか?
Haskellのような型システムを持つ言語をもっと増やしたいです。Haskellは本当に素晴らしい型推論システムを利用しているので、型を宣言する必要はほとんどありませんが、それでも強い型の言語です。
Haskellで新しい型を宣言する方法もとても気に入っています。たとえば、オブジェクト指向システムよりもはるかに優れていると思います。たとえば、Haskellで二分木を宣言するには、次のようにします。
data Tree a = Node a (Tree a) (Tree a) | Nothing
したがって、複合データ型はオブジェクトというより代数型に似ています。プログラムについての推論がずっと簡単になると思います。
さらに、型クラスでのミキシングははるかに優れています。型クラスは、型が実装するクラスのセットです。Javaのような言語のインターフェイスのようなものですが、Rubyのような言語のミックスインのようなものだと思います。ちょっとかっこいいです。
理想的には、Pythonのような言語が欲しいのですが、オブジェクトの代わりにHaskellのようなデータ型と型クラスがあります。
私はクロージャー/無名関数の大ファンです。
my $y = "world";
my $x = sub { print @_ , $y };
&$x( 'hello' ); #helloworld
と
my $adder = sub {
my $reg = $_[0];
my $result = {};
return sub { return $reg + $_[0]; }
};
print $adder->(4)->(3);
それらがもっと一般的であることを願うばかりです。
最も明白な答えは、Lisp ライクなマクロだと思います。自分のコードで自分のコードを処理できるということは、素晴らしく「メタ的」であり、かなり印象的な機能を (ほぼ) ゼロから開発することを可能にします。
C++ などの言語では、近い秒は double または multiple-dispatch です。ポリモーフィズムが仮想関数のパラメーターにまで拡張できれば幸いです。
私が他の言語で見逃しているLispからのもの:
- 複数の戻り値
- 関数の必須、キーワード、オプション、および残りのパラメーター (自由に混合可能)
- ファーストクラスのオブジェクトとして機能します (最近ではより一般的になっています)
- テールコールの最適化
- テキストではなく言語で動作するマクロ
- 一貫した構文
まず、エスケープコードを使用する場合は、デフォルトで使用するのではなく、文字列の標準としてプレフィックスを使用することをお勧めします。たとえば、C#では、生の文字列の前に@を付けることができます。同様に、Pythonにはrプレフィックスがあります。生の文字列が不要でエスケープコードが必要な場合は、@/rを使用します。
比較的単純なジェネリック用に実際に設計され、ほぼ偶然にチューリング完全である C++ テンプレートではなく、実際にメタプログラミングに使用するように設計された、より強力なテンプレート。D プログラミング言語にはこれらがありますが、まだあまり主流ではありません。
immutable
キーワード。はい、不変オブジェクトを作成することはできますが、ほとんどの言語では非常に面倒です。
class JustAClass
{
private int readonly id;
private MyClass readonly obj;
public MyClass
{
get
{
return obj;
}
}
}
どうやらJustAClass
不変クラスのようです。しかし、そうではありません。別のオブジェクトが同じ参照を保持しているため、obj
オブジェクトを変更できます。
ですから、新しいimmutable
キーワードを導入する方がよいでしょう。がimmutable
使用されると、そのオブジェクトは不変として扱われます。
私はRuby言語にある配列操作機能のいくつかが好きです。その一部を.NetとJavaに組み込んでおけばよかったのにと思います。もちろん、いつでもそのようなライブラリを作成できますが、そうする必要がないのは素晴らしいことです。
また、静的インデクサーは必要なときに最適です。
型推論。ゆっくりとメインストリーム言語への道を歩んでいますが、まだ十分ではありません。ここでは F# がゴールド スタンダードです
シングルメソッドとシングルオペレーターのインターフェースを見たいのですが:
interface Addable<T> --> HasOperator( T = T + T)
interface Splittable<T> --> HasMethod( T[] = T.Split(T) )
...またはそのようなもの...
私はそれがダックタイピングのタイプセーフな実装であると想像しています。インターフェイスは、元のクラスの作成者によって提供された保証ではありません。これらは、元の作成者が予期していなかった場合に限定された型安全性を提供するために、サードパーティのAPIの利用者によって行われたアサーションになります。
(これの実際の良い例は、人々が時間の夜明け以来C#で詰め込んでいるINumericインターフェースです。)
Rubyのようなダックタイピング言語では、任意のメソッドを呼び出すことができます。メソッドが存在しない可能性があるため、実行時に操作がサポートされているかどうかはわかりません。
型の安全性について小さな保証を付けて、異種オブジェクトのすべてに呼び出したいメソッドまたは演算子がある限り、それらのオブジェクトのメソッドを多態的に呼び出すことができるようにしたいと思います。
そして、コンパイル時に呼び出したいメソッド/演算子の存在を確認できるはずです。実行時が吸盤のためになるまで待つ:o)
map、flatMap、foldLeft、foldRightなどの機能関数。Scala(ビルダーの安全性)のような型システム。コンパイラーにコンパイル時に高レベルのライブラリーを削除させる一方で、「インタープリター」または「コンパイルされていない」モードで実行している場合はそれらを保持します(速度...時々必要になります)。
スコープ外のときにロールバックする自己反転代入演算子があればいいのにと思います。これは次のように置き換えられます。
type datafoobak = item.datafoobak
item.datafoobak = 'tootle'
item.handledata()
item.datafoobak = datafoobak
これとともに
item.datafoobar @=@ 'tootle'
item.handledata()
そのような変更を明示的にロールバックすることもできますが、範囲外になるとロールバックします。この種の機能は少しエラーが発生しやすいかもしれませんが、場合によってはよりクリーンなコードになることもあります。ある種の浅いクローンは、これを行うためのより効果的な方法かもしれません:
itemclone = item.shallowclone
itemclone.datafoobak='tootle'
itemclone.handledata()
ただし、関数が内部データを変更した場合、浅いクローンに問題が発生する可能性があります...ただし、可逆的な割り当てには問題があります。
ここにはいくつかの良い答えがありますが、いくつか追加します。
1 - 現在のコードと呼び出し元のコードの文字列表現を取得する機能。変数名とその値を簡単に出力したり、現在のクラス、関数、またはスタック トレースの名前をいつでも出力したりできます。
2 - パイプもいいでしょう。この機能はシェルでは一般的ですが、他のタイプの言語では一般的ではありません。
3 - 任意の数のメソッドを別のクラスに簡単に委譲する機能。これは継承のように見えますが、継承が存在する場合でも、子クラスとして実装できないある種のラッパーまたはスタブが必要になる場合があり、すべてのメソッドを転送するには多くのボイラープレート コードが必要です。
Lisp スタイルのマクロ。
複数発送。
テールコールの最適化。
ファーストクラス継続。
ばかげていると思いますが、すべての機能がすべての言語に属しているとは思いません。それは、「何でも屋、無職」症候群です。さまざまなツールを利用できるのが好きで、それぞれが特定のタスクに最適です。
私は、はるかに制限的で、トリッキーさのない優れた保守可能なコードを生成するように設計された言語が欲しい. また、コンパイラがコンパイル時に可能な限りチェックできるように設計する必要があります。
新しい VM ベースの重度の OO 言語から始めます。
- 演算子のオーバーロードや多重継承などの複雑さが存在する場合は削除します。
- すべての非最終変数を強制的に非公開にします。
- メンバーはデフォルトで「Final」にする必要がありますが、それをオーバーライドするには「Variable」タグが必要です。(これには、ビルダー パターンを完全に有効にするための組み込みサポートが必要になる場合があります)。
- 変数はデフォルトで「Null」値を許可するべきではありませんが、変数とパラメーターには、その変数で null が許容されることを示す「nullable」タグが必要です。
また、いくつかの一般的な疑わしいパターンを回避できると便利です。
- IOC/DI を簡素化してシングルトンを排除する組み込みの方法
- Java -- チェックされた例外を排除して、人々が空のキャッチを入れないようにします。
最後に、コードの読みやすさに焦点を当てます。
- 名前付きパラメータ
- たとえば、100 行を超えるメソッドを作成する機能を削除します。
- 複雑なメソッドとクラスの検出に役立つ複雑さの分析を追加します。
可能性のある項目の 1/10 に名前を付けていないことは確かですが、基本的には、C# や Java と同じバイトコードにコンパイルされるものについて話しているのですが、非常に制限的であるため、プログラマーは良いコードを書かずにはいられません。 .
はい、これを行う lint タイプのツールがあることは知っていますが、私が取り組んだプロジェクトでそれらを見たことはありません (また、現在取り組んでいるコードでは物理的に実行されません)。 、たとえば)あまり役に立たないので、101行のメソッドを入力したときにコンパイルが実際に失敗するのを見てみたい...