あなた自身の (私は完璧だと思います) プログラミング言語はどのようなものですか? 小さな例を挙げて、あなたの斬新なアイデアを説明してください!
私は構文に非常に興味があります。
あなた自身の (私は完璧だと思います) プログラミング言語はどのようなものですか? 小さな例を挙げて、あなたの斬新なアイデアを説明してください!
私は構文に非常に興味があります。
Jon の言う「[異なる] タスクは、異なる言語とパラダイムに適している」というのは正しいことです。ただし、ドメインとはほとんど関係のない考慮事項がいくつかあります。これらは主に構文に関するものですが、コードは書かれるよりも読み取られることが多いため、実際には構文が重要だと思います。
1 つには、多くの言語が間違っている点として、構文を C に基づいて作成することは完全に恣意的です。実際、C には非常に悪い構文があります。例を2つだけ取り上げます。
1 つ目はまったく議論の余地がありません。セミコロンは不要です。次のコードを見てください。文法は完全に曖昧ではなく、コンパイラーにとって簡単に解析できます。セミコロンも明示的な行継続も必要ありません。
answer = 42
fraction = answer * 2 /
(answer + 1)
Console.WriteLine(
"Some funny number: {0}",
fraction
)
これは実際には Python に非常に似ていますが、さらに寛大です: の定義はfraction複数行にまたがっています。最初の行がまだ完成していないため、これは論理的です。
C ライクな構文で選択しなければならないもう 1 つの骨は、ほとんどが暗黙的な変数宣言です。「私はvariableof 型を宣言しています」と明確に宣言する代わりに、Foo恥ずかしそうにささやくのは「 <sub> Foo var」だけです。Fooほとんどの場合、 は予約語でさえないため、プログラマーにはここで視覚的なヒントが 1 つも提供されません。私は VB の explicit を好みDim var As Fooますが、ここで使用されているキーワードは非常に薄暗いとは言えません。
(C++ は、変数の初期化から関数宣言まで、まったく異なる意味を持つほぼ同一で、しばしばあいまいな構文を多数導入することで、実際には問題をさらに悪化させます)。
私の言語に必要なもう 1 つのことは、静的型付けです。確かに動的型付けには用途がありますが、驚くほどまれです。ほとんどの「スクリプト言語」でさえ、実際にはそれらを必要としません。これは、より多くの用途がある暗黙の型付けと混同されることが多いと思います。(再び) Python の例を取り上げます。静的型付けを提供しないのはなぜですか? すでに強く型付けされており、静的型チェックは結果としてのみ行われ、デバッグがかなり削減されます。明示的な変数宣言についても同様です。暗黙の変数宣言が提供する利点がわかりません。
これで、言語の概要がすでに得られました。
さらに、汎用テンプレート、RAII (ガベージを収集するのではなくガベージを回避する)、不変性、反復子によって定義される値の範囲の概念など、特定の C++ の概念の大ファンです。イテレータはこれまでで最も基本的な革新の 1 つだと信じていることを別の場所で述べました。小さな口紅をつければ、C++ という醜い野獣にさえ気付かないでしょう。
for i in MyVector:
print(i)
それよりも
for (typename vector<T>::const_iterator i = MyVector.begin();
i != MyVector.end();
++i)
cout << *i << endl;
もちろん、上記の構文が多くの言語で提供されていることは承知しています。しかし、それらはすべて、C++ の強力なイテレーターの概念の骨抜きバージョンしか提供していません (C++ の用語を使用すると、ほとんどの言語が知っている唯一の種類のイテレーターは入力イテレーターであり、基本的に最も強力なイテレーターではありません)。
この時点で、おそらく、これらすべてのアイデアの唯一の著作権は私にあり、特許は出願中です (特に、実際にはオブジェクト参照を比較しないMayOrMayNotBeオペレーターの場合)。
実行するタスクが 1 つだけではないため、「完璧な」プログラミング言語の概念はありません。
異なるタスクは、異なる言語とパラダイムに適しています。
C# のようになります。マイクロソフトを所有したいです。
私の完璧な言語は、必要に応じて機能を段階的に増やすことを可能にします。クラスなしで簡単なユーティリティプログラムを書く必要がある場合は、できます。クラスを使用する必要がある場合は、それも可能です。また、完全なオブジェクト指向ソリューションを作成したい場合は、それも可能です。リンカは、小さな高速コマンド ライン ユーティリティ (ランタイム依存関係なし) や、想像できる最大の肥大化した OOP GUI アプリを作成できるほどスマートです。
問題は、私が好きなことには相反する目標があり、そのため常にまったく異なる言語を使用することを余儀なくされてきたことです。私は現在、PowerShell、VBScript、PowerBasic、Java、および C# を順不同で使用しています (場合によっては、VB .NET、VB 6、C++、Python、および Perl も使用します)。
これらの小さなアプリを作成するときにランタイムに依存しないグローバル関数を備えた 1 つの C# のような言語ですべてを実行でき、必要に応じて .NET Framework と Java SDK の機能をフルに活用できるとしたら、幸せだろう。
完璧なプログラミング言語は、SF 小説によく見られます。例えば:
それはすべて、同じ基本的な難問に帰着します。人間にスキルの習得を強制しないプログラミング言語は、思考の自由を制限する傾向があります。自然言語も曖昧さが多いので苦手です。
自由とパワー、最小限のシンタックスを組み合わせたものは気にしません。私は最近 Lisp を学び始めましたが、今のところとても良いようです。
Amazon Mechanical Turkによって強化された大規模な並列処理。
job = "Upvote this answer"
@price = "$0.01"
fork(10000, job, @price)
EiffelとC#の最高のアイデアを採用することと大差ありません(明らかに、私にはもっと良いものを思いつくための知識がないためです-私はそもそもCSを勉強していません)。
しかし、私の主な実際的な関心事は、古典的な「ソースコードテキスト」アプローチを超えた一歩に進むことです。これはIDEのものである(またはそのように聞こえる)ことは知っていますが、「線形」形式(i)の代わりにpreconditions / body/postconditionsなどの列を持つ構成可能なコードビューを使用できないのはなぜですか。
function f
// f's preconditions
// f's body
// f's postconditions
end
function g
// g's preconditions
// g's body
// g's postconditions
end
なぜ(ii)-これが(境界線のある)テーブルであると想像してください:
f f's parameters f's prec f's body f's postc f's comments
g g's parameters g's prec g's body g's postc g's comments
また、スタイル(i)で関数の「開始」と「終了」(中括弧、キーワード...)を選択できないのはなぜですか?プライベートメンバーまたは保護されたメンバーをすぐに表示または非表示にできないのはなぜですか?継承されたすべての関数が内部にある「フラットバージョン」がすぐに表示されないのはなぜですか?等
重要なのは、編集する1つの聖なるコードファイルと複数の「クールなビュー」を用意することではなく、(i)、(ii)、および最も役立つ形式の両方でコードを編集および追加できるようにすることです。
ある意味で、「IDE」について話すことは、ここでは話題から外れているように見えるかもしれません。しかし、OTOHこれにより、遅かれ早かれ、コードの記述と読み取りの方法が変わると思います。そして、これは最終的に言語の進化の仕方に影響を与えます。将来の目標は、読みやすさだけでなく、「理解しやすさ」と双方向性も強化することです。
私は C マクロの大ファンですが、使用しているのと同じ言語でマクロまたは「メタコード」を記述できればいいと思いました。(C は悪い例です。スクリプト言語ではこれが適している可能性があります。)
これらの例では、中かっこを使用してメタコードを識別しています。「プリプロセッサ」を介してソースを実行して、メタコードを展開することができます。そうしないと、実行時に一度だけ展開されます。
print "Your product ID is: ", { print '"', generateGUID(), '"' }
また
lookupTable[] = {
/* insert code to generate table here
*
* This lets you modify the algorithm easily
* but speeds up the final program.
*
* This would be especially appropriate in
* cases where you would otherwise type out
* the table as a literal (yuck)
*/
}
ときどき、非常に反復的なコードを何行も書かなければなりません。今は良い例が思い浮かびませんが、この種の考え方はそのような状況でも非常に役立ちます。
私は、より多くの括弧を除いて、 Brainf * ckとLOLCODEの間のどこかにあると思います。
Python は私にとって理想にかなり近いです... self キーワードを使用するような煩わしさを取り除くだけです... しかし、優れたエディターを使用すると、Python は驚くべきことを非常に迅速に行うことができます...
私の夢の言語がどのようなものになるかはわかりませんが、C スタイルの言語については少し改善されています。次のようなことを何度書いたことか。
Node foundNode = null; // need stupid null value here to keep track if it was not found
foreach (Node testNode in nodes) {
if (testNode.YesItsMe) {
foundNode = testNode;
break;
}
}
if (foundNode == null) {
// create new instance
foundNode = new Node(blabla);
}
これにはもっと洗練された機能的な方法があることは知っていますが、それでもこのようなコードになってしまうことがあります。ここでは、単純な「ガード」ステートメントが役立ちます。
Node foundNode; // no need to initialize anymore
foreach (Node testNode in nodes) {
if (testNode.YesItsMe) {
foundNode = testNode;
break;
}
} guard { // we get here if break was never called
// create new instance
foundNode = new Node(blabla);
}
私は、入力と変数、および実行順序に関する正確な制限を伝える必要があり、高速なマルチスレッド (またはクラスター化可能) ソフトウェアにコンパイルできる言語を思い描いています。
ここに興味深いアイデアがあります。「関数」内のすべての「ステートメント」を任意の順序で実行できると想像してください。何かが他の何かに依存している場合は、依存関係を明示的に「呼び出す」必要があります。これにより、並列処理の設計が言語の不可欠なコンポーネントになります。
残念ながら、私はもっと具体的なことを考え出すのに十分な想像力を投資していません.
構造体や変数がなく、関数が 1 つだけの言語。
doEverything();// すでに予測された入力に基づくすべてのコンテンツの自動生成
Clojureはかなり近づいています...
特定の目標を満たすために言語を設計します。構文とセマンティクスは、目的の機能に従う必要があります。
私の場合、細粒度の並列処理を備えた言語、つまり、コードの小さなチャンクを並列化できるように、細粒度あたりのオーバーヘッドが非常に低い言語が必要でした。
x86 SMPシステムで設計および実装し、大規模なソフトウェア分析ツールの基盤として約10年間使用されています。
重要な点は、私(私たち)が並列処理を簡単に指定できるようにすることでした。
(|| A B)
AとBを並行して実行し、これを可能にするすべてのクラッドをコンパイラーに生成させます。構文が中置であるかどうかは気にしないので、引数を避けるためにLISPスタイルを使用しました。
言語と多数の並列アプリケーションについて説明している論文は、 http://www.semanticdesigns.com/Company/Publications/parallelism-in-symbolic-computation.pdfにあります。
この論文では、私たちの決定にもかかわらず、構文に関する議論を回避することに成功しなかった方法について簡単に説明します。
それはSchemeとまったく同じように見えます。それだけがILとJavaの両方のバイトコード、およびアセンブリにコンパイルされるので、これらすべてのライブラリを使用できます。
私の理想的なプログラミング言語です。コードはスマートで、別のコードに問題があるかどうかを教えてくれます。座って話をすると、何が問題なのかを教えてくれるので、解決することができます...私はそれを「EmotionPeople++」と呼んでいます
主な機能から始めます。
現在、ウィッシュリストに最も近いのはClojureで、これらの要件のほとんどを満たしています。
OPは構文を参照しているため、いくつかのコード例を示します。
大きな引数リストをサポートする適切な可変アリティ関数:
(+ 1 2 3 4 5)
=> 15
(apply + (range 10000))
=> 49995000
実行時のコンパイラへの対話型アクセス:
(def function-string "+")
(def function (compile-string function-string))
(function 7 8 9)
=> 24
分散コード実行 (MapReduce スタイル)。これは、言語/ライブラリがローカルで定義されたものを取得し、実行時some-long-running-functionに実行するためにクラスター内のすべてのノードに透過的に配布できることを意味することに注意してください。
(def my-cluster
(create-compute-cluster :nodes 100 :service "Amazon"))
(defn some-long-running-function [input]
....)
(def reduction-function
(fn [a b]
(do-something-to-reduce a b)))
(def lots-of-inputs (range 10000))
(distributed-map-reduce
my-cluster
some-long-running-function
inputs
reduction-function)
=> (whatever the result of the mapreduce is over the cluster)
適切な型推論 (つまり、コンパイラは my-function が常に String を返し、それに応じて最適化/推論を行うことを解決します:
(def my-function [name]
(str "Hello " name "!"))
(my-function "Bob")
=> "Hello Bob!"
(compile-time-type my-function)
=> [java.lang.String :not-null]
関数が任意の数の参照パラメーターを含み、それらをネストされた関数呼び出しに渡す機能を確認したいと思います。.netでは、次のようなものを使用して、任意の固定数のジェネリックパラメーターに対してこれを行うことができます(2つの追加パラメーターバージョンが示されています)。
//通常はvbでコーディングしているため、デリゲートのC#構文を忘れています
void RefAction <T1、T2、T3>(ref T1 p1、ref T2 t2、ref T3 p3);をデリゲートします。
ポイントmyPoints[];
void DoSomethingWithIndexedPoint <XT1、XT2>(int index、
RefAction <Point、XT1、XT2)theAction、
ref XT1 xp1、
ref XT2 xp2)
{{
theAction(myPoints [index]、xp1、xp2);
}
私の好みの構文は次のようになります。
void RefAction <T1、T2、T3>(ref T1 p1、ref T2 t2、ref T3 p3);をデリゲートします。
ポイントmyPoints[];
void DoSomethingWithIndexedPoint <ref ...>(int index、
RefAction <Point、ref ...>、ref ...)theAction、
ref XT1 xp1、
ref XT2 xp2)
{{
theAction(myPoints [index]、...);
}
ここで、「...」は、適切な方法でコンパイラによって自動的に展開されます。このような機能により、クロージャーインスタンスを生成することなく、多くの状況でLambdaを使用できるようになり、次のようなコードを実行することも可能になります。
Interlocked.CompareExchange(SomeObject ["George"]、SomeValue、SomeOtherValue);
コンパイラはこれを次のようなものとして書き直すことができます。
SomeObject.ActUponProperty( "George"、
(ref dest、ref p1、ref p2)=> {Interlocked.CompareExchange(dest、p1、p2);}、
SomeValue、SomeOtherValue);
ラムダ式は、refパラメーターとして渡されたもの以外のインスタンスメンバーまたは変数を使用しないため、静的関数として実装でき、クロージャーを生成する必要がないことに注意してください。
うーん。これは大変なことです。私の好みは、人間が簡単に理解できる、軽量のスクリプト スタイルの言語です (ただし、これはより大きなアプリでも機能すると思います)。コード スニペットを参照してください。
function Foo takes x as string, y as boolean //can add returns [return type] if one wishes to be explicit
//explicit variable declaration
z as number
//explicit cast from boolean to number
z is y as number
//implicit variable declaration
bar is 3 * 5
//function call
print x
return z / bar //since we casted z to a number, it returns a number
私の最適な言語は、Nemerle によく似ています (恣意的な制限を除いたものです)。実際には、メタプログラミング機能に行き着きます。ドメインに完全に適合するように、適切と思われる方法 (ピリオド) で言語を任意に拡張または変更できる必要があります。
すべてのコードの AST を自由に操作できるマクロを提供してください。そうすれば、完璧な言語を構築できます。