プログラミング言語を設計する場合、どうしますか?どの機能を追加しますか?何を残しますか?静的または動的に型付けされましたか?強くまたは弱く入力されましたか?コンパイルまたは解釈されましたか?答えを正当化します。
プログラミング言語を設計する場合、どうしますか?どの機能を追加しますか?何を残しますか?静的または動的に型付けされましたか?強くまたは弱く入力されましたか?コンパイルまたは解釈されましたか?答えを正当化します。
回答:
関数型プログラミング言語が普及することは間違いないので、私の言語は機能するでしょう。関数型プログラミングによる効果の調整を参照してください
CPUにはすぐにコアの数百があり、スレッドは管理するのに大変なことになると思います。したがって、アクターモデルはスレッドではなく必須です。Erlang-Concurrent Worldのソフトウェアをご覧ください
また、OOPが失敗し、オブジェクト間の通信は非同期であると想定されたと思います。そのため、不変のメッセージでメッセージを渡す必要があると思います。送信して忘れる。アクターモデルのように。参照してください。間違ったパス:オブジェクト指向プログラミングを?
静的型付けは良いと思いますので、開発サイクルの早い段階でエラーをキャッチします。しかし、Haskellのように型推論を使用するので、開発者はC、C#、Javaのようにコードのどこにでも型を記述する必要がありません。Learn You A Haskell for Great Goodをご覧ください
私はまた、デザインでしょう偉大なUIライブラリをして、宣言型レイアウト WPFとAndroidのように、。しかし、Functional Reactive Programmingのようにそれを持ちたいです。
したがって、私の言語は、Erlangの並行性のようになりますが、Haskellのように入力し、WPF.NETのようにGUIフレームワークを使用します。
注:Cのような構文を使用してこの投稿の機能を説明しましたが、すべてのキーワードがCAPSのように馬鹿げたものでない限り、構文自体については気にしません。
1.入力システム
私が言語で望む一番の機能は、オプションの動的型付けを伴う静的型付けです。その理由は、静的型付けを使用すると、a)遅延ではなく早期にエラーをキャッチし、b)言語が区別するかどうかにかかわらず、ほとんどのコードが暗黙的に静的に型付けされるためです。ただし、動的な型指定が非常に役立ついくつかのユースケースがあります。たとえば、ファイルからデータを読み取る場合、多くの場合、さまざまなタイプのフィールドがあり、動的な型付けにより異種コンテナが簡単になります。したがって、私の理想的な言語には次のようなものがあります。
//variable declarations
int anInt = 42 //anInt is now irrevocably an integer and assigning another type to it is an error
vartype aVariable = 42 //aVariable is currently an integer, but any type can be assigned to it in the future
//function definitions
int countElements(Collection c)
{
return c.count();
}
//c HAS to be a collection, since countElements doesn't make sense otherwise
void addToCollection(Collection& c, vartype v)
{
c.append(v)
}
//c is passed by reference here
2.コンパイル済みと解釈済み
言語を事前にコンパイルするか、JITコンパイルするが、純粋に解釈されないため、速度が理由です。これは、最適化コンパイラ/ジッターが静的に型付けされたコードを最適化する時間をはるかに容易にし、動的に型付けされたコードをそのまま残すことができるため、ポイント1に結び付けられます。
3.クロージャー
言語は関数型プログラミングの構成をサポートする必要があり、関数はファーストクラスのオブジェクトでなければなりません。
4.オブジェクト指向
この言語では、オブジェクト指向のコードを記述できますが、単純な命令型コードも許可する必要があります。つまり、次のようなhello worldプログラムを作成できるはずです。
int main(string<> args=null)
{
printf("hello, world");
return 0;
}
// this code also demonstrates two other features,
// default arguments for functions (not explained further)
// and immutable lists like string<> (see 6. Built-in datatypes)
5.名前空間
名前空間は良いことです。グローバルな名前空間に入れるものはほとんどありません。しかし、グローバルな名前空間に何かを置く必要がある場合は、できます(ala C ++)。
6.組み込みデータ型
言語には、組み込みデータ型として次の構造が必要です。
int
つまたは複数のデータ型。int
タイプが1つしかない場合は、範囲を無制限にする必要があります。さらにある場合は、計算結果を保持できる最小の型に暗黙的にアップキャストする必要があり、無制限の範囲型が最大になります。float
IEEE 754と同等の単一の組み込みバイナリタイプdouble
list
二重リンクリストまたは各要素へのポインタを保持する連続したメモリのブロックとして実装される可変タイプlist
配列のように機能するが、作成後にサイズを変更できない不変の型string
タイプ。デフォルトは不変です。map
またはdict
型。vartype
必要に応じてdboolean
タイプnull
またはnone
任意の型の変数に割り当てることができるタイプ。set
型および不変型decimal
10進浮動小数点変数を実装する型fixed
固定小数点数を実装するタイプ、decimal
、float
及びfixed
タイプは共有する必要があり、正確なそれらの透過に渡され、関数から返されることを可能にする、(いずれかの相続またはダックタイピングを介して)同じパブリックインターフェイスを。親タイプを呼び出すことができますreal
。
7.値と参照による呼び出し
値と参照の両方で関数を呼び出すことができます。デフォルトは値です(つまり、引数のコピーが作成され、関数内で操作されます)。
8.ポインター
言語にはポインターが必要であり、ポインター演算を許可する必要があります。ポインターは静的にのみ入力できます(悪夢を回避するためvoid*
)。vartype
ポインターは明示的に禁止されています。ポインターとポインター演算を使用すると、この言語をシステムプログラミング言語として真剣に使用できます。
9.インラインアセンブリ
8.に関連して、言語は、必要な状況でインラインアセンブリ言語コードを許可する必要があります。
10.安全性
この言語は、例外処理などをサポートするために、ほとんど安全に使用できる必要があります。ポインター演算とインラインアセンブリは、安全でないと明示的にマークされたコードの部分に委ねることができます。安全でないコードは許可されますが、強く非推奨です。
11.未定義の動作
言語標準では、明示的に安全でないとマークされたコードを除き、すべての状況でプログラムがどのように動作するかを指定する必要があります。つまり、安全でないブロック以外に未定義の動作がありません。これにより、この言語を実行可能なアプリケーション開発言語として使用できますが、OSを記述することもできます。
現時点で考えられるのはこれだけです。しかし、もっと多くのことを考えて、投稿を編集/更新します。
decimal
ここに実際に型を追加します。
これは私の夢のプログラミング言語がどのように見えるかです:
yield
SmalltalkでPythonを実装できますか?使用するのと同じくらいきれいでなければなりません。
私はC#とほぼ同じように設計していましたが、Microsoftは私を打ち負かしました。:)
(もちろん、私のものはあまりよく考えられておらず、よりアマチュアだったはずです。)
コンパイルまたは解釈されるかどうかはあまり気にしないので、そのビットを正当化する必要はありません。
強力な静的型付けに関しては、正当化が必要な理由を理解するのは難しいと感じています。静的型付けは、コンパイル時にバグをキャッチする機能です。動的型付けはその機能の欠如であり、実行時までバグを延期します。私の個人的な経験では、動的ディスパッチが理にかなって有用なユースケースはほとんどなかったので、4.0の前にC#でそれを取得する必要があった畳み込みは、簡単に正当化されました。C#4.0では、動的ディスパッチがあるため、それを正当化する必要さえありません。
ただし、C#のように古いC構文に忠実に固執するのではなく、おそらく新しい構文を作成したでしょう。switchステートメントは特に恐ろしく、キャスト構文も嫌いです(これは間違った方法です)。ただし、構文の詳細については大騒ぎしないので、Visual Basicほど冗長にしたくない場合を除き、詳細に正当化する必要はありません。
他に何を正当化してほしいですか?
さて、ここに私が入れた機能のリストがあります:
Lispスタイル
長所:
(eval "your data files")
短所:
ハスケルスタイル
長所:
短所:
Pythonスタイル
長所:
実装:
CLのように、型に基づいて関数のオーバーロードを許可しますdefgeneric
。
(define (+ (a <int>) (b <int>))
(ints-add a b))
(define (+ (a <string>) (b <string>))
(string-concat a b))
(define (+ a b)
(add-generic a b))
長所:
短所:
Cスタイル
長所:
短所:
長所:
短所:
考えてみれば、これは多かれ少なかれスキームを定義していますが、コンパイルとシステムプログラミングビットを除きます。libguileを使用してこれらのビットをCで記述することで回避できます。
car
関数でありcdr
引数であるリストの代わりに、name
フィールドがメソッドであり、arguments
フィールドが引数であるオブジェクト。ネストする代わりにprev
、next
ポインタフィールドがあります。)
私はかなり良いと思ういくつかの言語があります(C#が現在のお気に入りです)。これは私の幻想的な言語なので、ここに私が本当に欲しいものがあります:
私は言語設計についてあまり知らないので、私はおかしな話をしていますが、私が話している機能は他の言語のヒントと呼ばれると思います。コンパイラのヒント、多分?
これをPerl6ドラフトで読んだのか、それとも当時はただ高かったのかはわかりませんが、デフォルトではすべてがだらしないグージーで自動の言語であると思います。しかし、実際にパフォーマンスを上げたいと思ったら、この値は常に整数であるか、決してnullではない、これは並列である、またはこれはステートレスである、など...コンパイラは自動的に町に行くことができるこれらの特別にマークされた領域。
E:私が求めていることを明確にしたり、これが既に存在する例を引用したりするコメントをいただければ幸いです。
safety
and speed
値を変更することで、多くの場合、コンパイラーにチェックと強制(問題を見つけるため)をさせるか、ユーザーの発言が正しいと仮定する(およびより高速なコードをコンパイルする)ことです。
新しいアイデアを試すには:
動的型の関数型プログラミング言語を作成します。これにより、すべてのステートメント式のトリックと、パターンマッチングを使用した最も単純なラムダ構文を実行できます。オフサイドルールが有効になっています。
// a view pattern (or Active Pattern in F#)
default = \def val: !!val.Type val def
// usage of the pattern
greet = \name<(default "world") `and` hasType Str>:
p "Hello, \{name}!"
(p "Enter your name", .input).greet // (, ) is a sequence expression, returning the last value
説明は次のとおりです。
default =
設定記憶、\def val
2つの引数を持つカリー化関数を開始するval.Type
のと同じでありType[val]
、!!
変換ブールし、ブール値を適用することができるので、val
及びdef are after it.
f x
= f[x]
= x.f
.f
=f[]
そしてgreet
、それは使用さname<(default "world")
れhasType Str>
、それはパターンdefault "world"
が使用され、バインドされることを意味しname
ます。デフォルトパターンはデフォルト値を指定します。
and
2つのパターンを連結する別のパターンです。default
一方、パターンが失敗することはできませんhasType
失敗する可能性があります。その場合、例外をスローします。
変数は実際にはストレージであり、機能的に渡すことができ、ストレージテーブルは参照の作成、スコープの変更に応じて作成および破棄することができます。
ハッシュなどは、LuaやJavaScriptのようになります。
コンパイル済み言語を作成する場合は、Haskellのような機能を備えたJava用のF#を作成します。純粋な関数型言語です。ただし、QuotationsとComp Exprsを組み合わせて、擬似コードのようなブロックを記述することで命令型プログラミングを実現する機能があります。
私が知っている唯一の言語はPHPとjavascriptであり、言語を設計する前にもう少し学ぶ必要があることに留意してください。
構文: 関数名と引数の順序について慎重に検討します(つまり、PHPよりも乱雑ではありません)。
特徴:
の設定したstring
一連のバイトとして変数を操作する関数を、が、テキストを理解していない、とのセットtext
機能、エンコーディングの多くを理解しているし、UTF-8およびその他のマルチバイト文字列を操作することができます。(そしてtext.isValidEncoding(text, encoding)
、バイトシーケンスが不正な形式であり、テキストとして扱うのに安全でないかどうかを通知するような関数を使用して、言語にエンコードの健全性チェックを組み込みます。
私は強力な静的型付けのアイデアが好きだと思いますが、私はそれを使用したことがないので、私は本当に言うことができません。
プログラミング言語を設計する前に、質問に対する良い答えを見つけるでしょう:なぜさらに別のプログラミング言語が必要なのですか?この記事の執筆時点でのRosettaコードには、344の言語がリストされています。それらのどれもが私のニーズを満たしていない場合、なぜ彼らがそうしなかったのかという詳細が、出発点(最も近い言語)とそれに追加されるものを決定するでしょう。
宝くじに当選し、何らかの理由でそれ以上のことをする必要がなかった場合、Liskellから始めてGHCフロントエンドではなく本格的な言語にしてから、FFIをより簡単(および自動化)にして、 C / C ++ライブラリ。
良い言語とは、次の言語です。
これを機能のリストに変えるのはかなり難しいですが、関数型プログラミングは、自然ではないと感じていますが、命令型プログラミングよりもこれに近いと思います(特に重要な詳細を隠す場合)
現時点では、このリストに近い言語はおそらくHaskellです。
最初の質問、「どうやってやるの?」-短い答え、私はしません。私はそれを引き出すのに十分なパーサー/コンパイラ理論を持っていません。しかし、私は25年間プログラミングを行ってきました。そのため、共有するアイデアや意見があります。
まず、真に接続されたモデルを作成できるOOPアプローチを考えます。つまり、モデルはほとんどすべての種類のプログラミングプロジェクトで最も重要なものの1つです。それを正しく行うには、常に多くの面倒な作業と継続的なリファクタリングが必要です。オブジェクト指向言語。
デモを許可してください。クラスHouseにDoorプロパティがあるとします。
var door = house.Door;
これで、Doorインスタンスへの参照を含むローカル変数が作成されました。
しかし、何が起こったのかを考えてみてください。あなたはちょうどドアを家から引き裂いたので、ドアをすり抜けることにとても満足しています。残りのコードは、このドアが実際に家に取り付けられているという事実を知らないのです。
私にとって、これは根本的に間違っています。
そして、はい、私は知っています、これはケースバイケースで「簡単に」修正されます-この場合、現在接続されている家へのすべてのドアからの逆参照を維持することによって。もちろん、これは2つの逆参照を正確に維持する義務があるため、モデルにエラーが発生するため、House.DoorsプロパティとDoor.Houseプロパティをプライベートにし、House.AddDoor()、House.RemoveDoor()などのメソッドを追加します。 )、Door.SetHouse()など、すべてを配線し、ユニットテストして実際に機能することを確認します。
これは、そのような単純な関係をモデル化するための多くの作業のように聞こえ始めていませんか?維持すべき多くのコード?モデルの進化に合わせてリファクタリングするコードはたくさんありますか?
問題はポインターです。私が見たすべてのオブジェクト指向言語は、オブジェクト参照が本当にポインターであるという事実に本質的に苦しんでいます。それはコンピューターが使用するものだからです。
ポインターは、実世界をモデル化するための良い方法ではありません。どの世界をモデル化しようとしても、その世界の関係は双方向の関係になることがほぼ保証されています。ポインターは一方向のみを指します。
基本的なデータモデルがグラフであり、デフォルトですべての関係に両端がある言語を見てみたいです。これはほぼ確実に、現実世界のモデリングにはるかに自然な適合性を提供しますが、そもそもコンピューターが必要なのはこれだけです。(それとビデオゲーム。)
そのような言語の構文がどのように見えるか、またはテキストを使用して表現できるかどうかはわかりません。(どういうわけか、そのような言語はグラフィカルでなければならないのだろうか...)
また、あらゆる形態の偶発的な状態が解消されることを望んでいます。
たとえば、Web開発では、データをデータベースからビジネスモデル、表示モデルに表示するために多くの時間を費やします。そのデータの一部はフォーム上に表示されますが、これはまさに別の変換です。 ..状態はフォームポストから返されます。その後、そのデータの形状を変更して、ビューモデルに再投影します。たとえば、ビューモデルバインダーなどです。次に、ビューモデルからビジネスに再投影します。モデル...次に、オブジェクトリレーショナルマッパー(または単調な作業)を使用して、ビューモデルからのデータを変換し、リレーショナルデータベースに投影します...
これは冗長に聞こえ始めていますか?この狂気のすべての時点で、私たちは実際に何か有益なことを達成しましたか?そして、有用というのは、具体的なもの、つまりエンドユーザーが理解し、気にすることができるものです。結局のところ、ユーザーが理解できるものを構築するのに実際に費やした時間は、実際に費やした唯一の時間です。それ以外はすべて副作用です。
非常に動的な言語が必要です。書き込み/コンパイル/実行サイクルは退屈な時間の無駄です。理想的には、言語は変更内容を把握し、必要に応じてバックグラウンドで透過的にコンパイル/ロードする必要があります。
理想的には、「実行」を押す必要さえないはずです-変更を行うと、すぐに変更が反映され、画面上で発生するはずです。書き込み/コンパイル/実行サイクル、またはさらに直接的な書き込み/実行サイクルの問題は、あなたがやっていることから切り離されていることです-私たちの仕事とのつながりを感じるために、即時のフィードバック、即時の結果が必要です。待ち時間が長すぎます!
繰り返しますが、これが従来のIDEで実現できるかどうか、またはこれがまったく新しい種類のインターフェイスを必要とするかどうかもわかりません。
あなたが取り組んでいる問題に最も適したものであれば、弱いタイピングと強いタイピングを組み合わせて使用できるはずです。
一般に、状態は、言語が完全に管理するものでなければなりません。永続性をデータベースに依存する必要があるのはなぜですか?理想的には、モデル内の任意の変数の寿命を単純に指定できるようにしたいです:1つのWeb要求、1つのセッション、24時間、永久に。
さまざまなメディアや寿命に合わせて、ストレージソリューション全体を選択する必要があるのはなぜですか?-各メディアに合わせてデータを変換および整形することは言うまでもありません。ブラウザのキャッシュ、データベース、メモリ、ディスク、気にする人!データはデータです。データを保存する場所(およびその期間)は、神との戦いではなく、単純な選択である必要があります。
まあ、それで幸運。
それはおそらく、以下をサポートするマルチパラダイム言語でしょう。
なぜこれらですか?特にデータを整理するために、大規模なプログラムを整理するのに最適な方法であるため、オブジェクト指向です。常にそれが必要/必要というわけではないため(OOP)構造化されているので、人々は選択する必要があります。プログラマがデバッグしやすくなり、プログラムがより明確になるため、機能的です。
インデントされたブロックを持つPythonのモデルを使用して、コードブロックをマークします。それは非常にクレンと読んでいいです。
Pythonは非常に素晴らしい言語であるため、実際にはPythonから多くのアイデアを盗みます。私はそれを声明のために取り、そのマップ、リスト、およびタプルをコピーします。
今、私は恐らくPythonの動的な概念を受け入れないでしょう。1つには、おそらく明示的かつ静的に型付けされるでしょう。それによってプログラムがより明確になると思います。変数はすべてメソッドを持つオブジェクトである可能性が高いstr.length()
ため、文字列の長さを取得するなどの操作を行うことができます。関数定義では、戻り値の型と引数の型を指定する必要があります(ある種のジェネリック型もサポートします)。
Pythonからのコピーに戻りましょう;-)。オプションの手続き引数を持つ方法が大好きなので、おそらくそうするでしょう。ただし、Pythonはプロシージャのオーバーロードをサポートしていません。
クラスを見てみましょう、私は多重継承を捨てます。悪用しやすい。プライベートスコープと同様のスコープを実装し、おそらくC ++で行われる方法で実装します。抽象クラスとインターフェイスもあります。Pythonにそれがあるとは思わない。
内部クラスをサポートします。実際、非常に強力なオブジェクト指向言語が必要です。
おそらく解釈されるでしょう。優れたJITコンパイル(プログラマーの生産性が最初になりますが、高速な言語が必要です)を使用して、本当に高速に取得することができます。通訳された言語は、プラットフォームの独立性も促進しますが、これは日々重要になっています。
組み込みのUnicodeサポートがあるはずです。最近の国際化は非常に重要です。
それは間違いなくガベージコレクションです。くそー、私は自分でメモリ管理をするのが嫌いです。生産性も良くありません。
最後に、それは良い標準ライブラリを持つでしょう。
うわー、私はPythonがどれだけ大好きかを実感しました。
Interpreted languages also promote platform independance
?コンパイラ(パーセンテージ)よりもクロスプラットフォームインタプリタの方が多いと思いますが、なぜこの文が正しいのか理解できませんでしたか?クロスプラットフォームの能力に関して、両者の間に違いはないと思います。
まず第一に、コンパイラーに関するいくつかの本といくつかの標準を購入し、言語とコンパイラーのコースを1つか2つ受講します。私はPEPに貢献し、C ++標準委員会の会議に出席します。できれば機能とバグの両方のために、使用するコンパイラにパッチを提供します。
それから私は戻って、今私が出てきたこのリストを恐ろしく見ます。それは、今すぐ始めた場合、私は言語でどんな方向に行くでしょうか:
言語を実装し始めると、これらのかなり広いポイントでさえもおそらくおそらく急速に変化するので、さらに詳細に進む必要はないと思います。
時間があれば、Scalaに基づいたローカライズ可能なプログラミング言語を設計するので、おそらくXMLを除き、ほとんどの機能を備えています。私の目標は、アラビア語(母国語)など、英語とは異なる構造を持つ言語でほぼ自然に読める言語を作ることです。私は次の機能を考えています:
#lang
ディレクティブ。プログラミングに使用される人間の言語をプリプロセッサに通知するために使用されます。たとえば#lang ar
、のفئة
代わりにclass
、のعرف
代わりに単語の使用を許可しますdef
。人間の言語固有のキーワードは、標準のプリプロセッサファイルで定義されます。class MyClass is composed of {
てになりclass MyClass {
、「として」を削除しdef MyMethod(x: Int) as {
てになりdef MyMethod(x: Int) {
ます。一部の(人間の)言語では、これにより、特に学生にとってコードがはるかに理解しやすくなります。اعرض طول اسم محمد
これはprint(length(name(Mohammad)))
、プログラミング英語の場合と同等です。(括弧は明確にするためのものです。)プリプロセッサーとコンパイラーに対するこれらの最小限の変更により、英語以外のスピーカーにとってプログラミングがはるかに簡単になると思います。
print
)のローカライズされたラッパーを作成しても害はありません。