相互運用性

GraalVMでは、JavaScript、Ruby、Pythonや、LLVMビットコードにコンパイルされるものを含め、他の様々なプログラミング言語がサポートされています。GraalVMのRランタイムではプログラミング言語の相互運用性を確保するためのAPIが提供され、これを使用することで、GraalVMでサポートされている他の言語からコードを実行できます。他の言語にアクセスするには、--polyglotを指定してRスクリプトを開始する必要があります。

GraalVMのRランタイムでは、次の相互運用性プリミティブを使用できます:

さらに学習するには、?functionName構文を使用します。次の例は、相互運用性機能を示しています:

# get an array from Ruby
x <- eval.polyglot('ruby', '[1,2,3]')
print(x[[1]])
# [1] 1

# get a JavaScript object
x <- eval.polyglot(path='r_example.js')
print(x$a)
# [1] "value"

# use R vector in JavaScript
export('robj', c(1,2,3))
eval.polyglot('js', paste0(
    'rvalue = Polyglot.import("robj"); ',
    'console.log("JavaScript: " + rvalue.length);'))
# JavaScript: 3
# NULL -- the return value of eval.polyglot

(r_example.jsを使用しています。)

Rベクターは、配列として他の言語に渡されます。これには、42LNAなど、単一要素ベクターが含まれます。ただし、NAを含まない単一要素ベクターは通常、他の言語がスカラー値を必要とする場所で使用できます。配列の添字または同様の操作を他の言語で使用して、Rベクターの個々の要素にアクセスできます。ベクターの要素がNAでない場合、実際の値はスカラー値(intなど)として返されます。要素がNAである場合は、nullのような特殊なオブジェクトが返されます。次のRubyコードでこれを示します:

vec = Polyglot.eval("R", "c(NA, 42)")
p vec[0].nil?
# true
p vec[1]
# 42

vec = Polyglot.eval("R", "42")
p vec.to_s
# "[42]"
p vec[0]
# 42

Rに渡された外部オブジェクトは、暗黙的に特定のR型として扱われます。次の表に、いくつかの例を示します。

外部オブジェクトの例(Java) R側における表示
int[] {1,2,3} c(1L,2L,3L)
int[][] { {1, 2, 3}, {1, 2, 3} } matrix(c(1:3,1:3),nrow=3)
int[][] { {1, 2, 3}, {1, 3} } サポートされていません: エラーが発生します
Object[] {1, ‘a’, ‘1’} list(1L, ‘a’, ‘1’)
42 42L

次の例では、Ruby配列をR組込み関数sumに簡単に渡すことができます。これは、整数ベクターであるかのようにRuby配列を操作します。

sum(eval.polyglot('ruby', '[1,2,3]'))

外部オブジェクトを明示的にアダプタにラップして、目的のR型に見えるようにすることもできます。このような場合、可能であればデータのコピーは行われません。次のコード・スニペットは、最も一般的なユースケースを示しています:

# gives list instead of an integer vector
as.list(eval.polyglot('ruby', '[1,2,3]'))

# assume the following Java code:
# public class ClassWithArrays {
#   public boolean[] b = {true, false, true};
#   public int[] i = {1, 2, 3};
# }

x <- new('ClassWithArrays'); # see Java interop below
as.list(x)

# gives: list(c(T,F,T), c(1L,2L,3L))

詳細は、暗黙的および明示的な外部オブジェクト変換の実行可能ファイル仕様を参照してください。

ノート: (Rスクリプトを介してではなく)他の言語またはJavaから開始されたRコンテキストは、Rscriptと同様に、非対話型モードにデフォルト設定されます。これは、コンソール出力(結果がエコーされない)およびグラフィック(出力がウィンドウではなくファイルにデフォルト設定される)に影響し、一部のパッケージは非対話型モードで異なる動作をすることがあります。

相互運用性に関する使用可能なR組込み関数のリストを次にします。詳細は、R --helpのメッセージを参照し、次の例を試してみてください:

> help(java.type)
> ?java.type
> example(java.type)

他のプログラミング言語との相互運用性の詳細は、『Polyglot Programming』リファレンスを参照してください。