13

私は Haskell の完全な初心者です。いつも私を悩ませているのは、Haskell が Java のようなマネージド (MS から借用した用語) 言語なのか、それとも C のようなネイティブにコンパイルするコードなのか、あいまいなことです。

GHC ページには、「GHC は Haskell コードをネイティブ コードに直接コンパイルするか、バックエンドとして LLVM を使用してコンパイルする」と書かれています。

「ネイティブ コードにコンパイル」の場合、JVM のようなものなしでガベージ コレクションのような機能をどのように実現できるのでしょうか?

/更新/

ご回答ありがとうございます。概念的に、Haskell でのガベージ コレクションに関する次の理解のうち、どれが正しいかを指摘していただけませんか。

GHC は Haskell コードをネイティブ コードにコンパイルします。コンパイルの処理で、ガベージ コレクション ルーチンが元のプログラム コードに追加されますか?

また

Haskell プログラムと並行してガベージ コレクションを実行するプログラムはありますか?

4

5 に答える 5

21

私の知る限り、「マネージ言語」という用語は、具体的には.NET/共通言語ランタイムを対象とする言語を意味します。いいえ、Haskell はマネージ言語ではなく、Java もそうではありません。

Haskell のコンパイル対象について: 引用したドキュメントにあるように、GHC は Haskell をネイティブ コードにコンパイルします。これは、ネイティブ コードを直接発行するか、最初に LLVM コードを発行してから LLVM にそれをネイティブ コードにコンパイルさせることによって行うことができます。いずれにせよ、GHC を実行した結果は、ネイティブの実行可能ファイルになります。

GHC 以外にも、Haskell の他の実装があります。最も注目すべきは Hugs です。Hugs は、実行可能ファイル (ネイティブであろうとなかろうと) を決して生成しない純粋なインタープリターです。

JVMのようなものなしで、ガベージコレクションのような機能をどのように実現できるでしょうか?

JVM で可能になるのと同じ方法: メモリが割り当てられるたびに、ガベージ コレクタに登録されます。その後、指定されたガベージ コレクション アルゴリズムの手順に従って、ガベージ コレクタが時々実行されます。GHC でコンパイルされたコードは、世代別ガベージ コレクションを使用します。


あなたの編集に応じて:

GHC は Haskell コードをネイティブ コードにコンパイルします。コンパイルの処理で、ガベージ コレクション ルーチンが元のプログラム コードに追加されますか?

基本的。ただし、「ガベージ コレクション ルーチンが元のプログラム コードに追加される」と言うと、間違った図が描かれる可能性があります。GC ルーチンは、すべての Haskell プログラムがリンクされるライブラリの一部にすぎません。コンパイルされたコードには、これらのルーチンへの呼び出しが適切な場所に含まれているだけです。

基本的には、malloc を呼び出すたびに GC の alloc 関数を呼び出すだけです。

C 用の GC ライブラリとその使用方法を調べてください。必要なのは、ライブラリのヘッダーを #include してライブラリにリンクし、malloc の出現ごとに GC ライブラリの alloc 関数に置き換えることです (そして へのすべての呼び出しを削除しますfree) 。そしてバム、あなたのコードはガベージコレクションされています。

Haskell プログラムと並行してガベージ コレクションを実行するプログラムはありますか?

いいえ。

于 2012-05-30T04:09:19.527 に答える
13

Haskell が Java のようなマネージ (MS から借用した用語) 言語かどうか

GHC でコンパイルされたプログラムには、ガベージ コレクターが含まれています。(私の知る限り、Haskell のすべての実装にはガベージ コレクションが含まれていますが、これは仕様の一部ではありません。)

またはCのようなネイティブコードにコンパイルしますか?

GHC でコンパイルされたプログラムは、ネイティブ コードにコンパイルされます。Hugs はプログラムを解釈し、ネイティブ コードにコンパイルしません。私の知る限り、ネイティブ コードにコンパイルされる実装は他にもいくつかありますが、この事実に自信がないため、これらを個別にリストします。

「ネイティブ コードにコンパイル」の場合、JVM のようなものなしでガベージ コレクションのような機能をどのように実現できるのでしょうか?

GHC でコンパイルされたプログラムには、M 対 N のグリーン スレッド、ガベージ コレクション、IO マネージャーなどの基本的な機能を提供するランタイム システムが含まれています。ある意味では、これは同じ機能の多くを提供するという点で「JVM のようなもの」を持つことに少し似ていますが、実装が大きく異なります。すべてのアーキテクチャに共通のバイトコードはありません (したがって、「仮想マシン」はありません)。 .

Haskell のガベージ コレクションに関する次の理解のうち、正しいものはどれですか。

  1. GHC は Haskell コードをネイティブ コードにコンパイルします。コンパイルの処理で、ガベージ コレクション ルーチンが元のプログラム コードに追加されますか?
  2. Haskell プログラムと並行してガベージ コレクションを実行するプログラムはありますか?

ケース 1 は正しいです。コンパイル時にランタイム システム コードがプログラム コードに追加されます。

于 2012-05-30T04:07:04.863 に答える
4

「管理された言語」は過剰な用語なので、ここでは一言で答えてから、(私の) 心に浮かぶ通常のさまざまな意味の詳細をいくつか示します。

CLR ターゲットとして管理

いいえ、Haskell は Microsoft CLI の IL にコンパイルされません。
まあ、それを行うことができるいくつかのソリューションがあることを読みましたが、そうではありません.CLRはFP用に構築されておらず、最適化が深刻に欠けているため、おそらく研究言語のパフォーマンスが得られます. 個人的に本当に CLR をターゲットにしたい場合は、F# を使用します。F#は関数型言語ではありませんが、それに近い言語です。

注: これは、「マネージド言語」という用語の最も正確で実際的な意味です。次の意味は、まあ、間違っていますが、残念ながら一般的です。

自動ガベージコレクションで管理

はい、これはほぼ必須です。つまり、仕様を超えて: ガベージ コレクションが必要になると、私たちの最愛の家である高地で作業する機能的なテーマが破壊されます。

また、不純物とメモリ モデルを強制します。

VM によって実行されるバイトコードにコンパイルされたものとして管理される

いいえ(通常)
それはあなたのバックエンドに依存します: 現在、さまざまな Haskell コンパイラがあるだけでなく、一部のコンパイラにはさまざまなバックエンドがあります。JavaScript 用のバックエンドもあります!

したがって、VM をターゲットにしたい場合は、既存のものを使用するか、そのバックエンドを作成できます。しかし、Haskell はそれを必要としません。したがって、ネイティブの raw-metal バイナリにコンパイルできるのと同じように、他のものにコンパイルできます。

C# 1、VB.NET などの CLR 言語とは対照的に、Java などとは対照的に、 Haskell はVM をまったく必要としないため、JVM、CLR、Mono などをターゲットにする必要はありません。

GHCがいい例です。GHC でコンパイルすると、そのままバイナリにコンパイルされるのではなく、Core と呼ばれる中間言語にコンパイルされます。次に、STG と呼ばれる別の言語に進む前に、Core から Core へと何度か最適化されてから、コードに進みます。世代(あなたがそれを言うならば、それはそこで止まることができます)。2そして最近では、それを使用して LLVM バイトコードにコンパイルすることもできます (これにはいくつかの素晴らしい最適化が適用されます)。LLVM バックエンドにより、GHC は非常に高速なプログラムを作成できます。それと GHC バックエンドの詳細については、こちらを参照してください。

下の図は、GHC コンパイル パイプラインを示しています。ここでは、さまざまな段階に関する詳細情報を見つけることができます。

GHC コンパイル パイプライン

3 つの異なるターゲットの下部にあるフォークを参照してください。それらは私が言及していたバックエンドです。


1将来の例外と楽しい事実: Microsoft は現在ネイティブ .NET に取り組んでいます! 狡猾な名前: Microsoft .NET Native .

于 2015-01-22T22:37:12.650 に答える
1

あなたにとって、「マネージ言語」の決定的な特徴は何ですか? あなたが引用した「GHCはHaskellコードをネイティブコードに直接コンパイルするか、バックエンドとしてLLVMを使用してコンパイルする」というフレーズは、GHCが何をするかについて非常に明確であるため、バグを引き起こす「あいまいさ」はむしろ「マネージ言語」という用語にあると思います" GHC のドキュメントよりも。

「ネイティブ コードにコンパイル」の場合、JVM のようなものなしでガベージ コレクションのような機能をどのように実現できるのでしょうか?

「JVM のようなもの」は、ガベージ コレクションなどの機能をどの程度正確に実装していると思いますか? JVM は魔法ではありません。他のすべてのものと同じように単なるプログラムです。あるレベルでは CPU がそれを実行するためにネイティブ コードが必要になるため、ネイティブ コードでガベージ コレクションなどの機能可能であることは明らかです。

于 2012-05-30T06:15:46.290 に答える
0

あなたが現在いる場所については、(GHC) Haskell を「管理された」ものと考えるのがおそらく最善ですが、GHC がコンパイルするプラットフォームは他の何の対象にもなっていません。もちろん、それだけではありませんが、Haskell の経験がなくても十分に説明できます

于 2012-05-30T04:12:51.837 に答える