2017-09-25 4 views
2

私は、関数本体で特定の引数が評価された時点でのみ、R関数が足りない引数をチェックしていることに気付きました。Rがコールの開始時に欠落した引数をチェックしないのはなぜですか?

例:

f <- function(x, y) { 
    Sys.sleep(3) 
    return(x + y) 
} 
f(1) 

関数は、関数呼び出しの開始時にそのかなり不足している引数を失敗し、報告して3秒かかります。そのような実装の利点は何ですか?

編集:

私はforce()とmissing()を認識しています。私は、関数呼び出しの開始時ではなく、評価の直前の引数にmissing()の利点があるかどうかを知りたいと思います。そのような実装には必要な理由はありますか?

F2に「高価な」コール(

f2 <- function() { 
    Sys.sleep(3) 
} 

f <- function(x, y) { 
    if (missing(y)) stop("y missing") 
    print(x) 
} 

f(1, f2()) 

不自然な例としては)まだ遅延評価によって回避されるが、そのmissingnessは評価せずに確認することができます。

EDIT2:私はあなたはそれがデフォルト値を生成するためのより多くの柔軟性を与えていると主張することができます推測

チェック引数が関数呼び出しの直後に行われた場合、他の不自然な例では

f <- function(x, y = 1:3) { 
    if (missing(x)) { 
     x <- y 
    } 
    x 
} 

f() 

このようなコードは失敗します。しかし、このコードはfunction(x = y, y = 1:3)と書かれています。私はそのような機能はコードベースではないと思われる数で使用されていると思いますが、今の動作を変更することは価値があるよりも面倒です。

+1

をRは、スクリプトではなく、コンパイルされ、言語です。他の多くのものは、実行時にのみ失敗する。タイプの安全問題。そして、私が[あなたのサンプルスクリプトを実行する](http://rextester.com/QWSQVQ35038)私は何が起こったのかを教えてくれる間違いのフィードバックを間違いなく受け取ります。 –

+0

申し訳ありません私は質問を明確にするために編集します。私は変数yが実際に関数の本体で評価されるまで失敗しないという事実を指摘しています。なぜなら、引数の欠落が関数呼び出しの開始時にチェックされない理由が何も見えていないからです。 – shians

+2

レイジー評価は機能です。多くの呼び出しを高速化します。 – Roland

答えて

3

Rはレイジー評価を使用します。つまり、関数の引数は、 まで必要です。これにより、 引数が不要なことが判明した場合、時間とメモリの両方を節約できます。 非常にまれな状況では、評価されていないものがあります。 forceを使用すると、怠惰を回避できます。

Burns、Patrick。 «Rインフェルノ»。 http://www.burns-stat.com/pages/Tutor/R_inferno.pdf

ので、この次のコードはより速く失敗します。

f <- function(x, y) { 
force(y) 
Sys.sleep(3) 
return(x + y) 
} 
f(1) 

または

f <- function(x, y) { 
    if(missing(y)) stop("missing y") 
    Sys.sleep(3) 
    return(x + y) 
} 
f(1) 
+0

私の質問は本当に実装されているため、手動で行方不明チェックを行う必要がありますが、なぜ機能の開始時の自動チェックがデフォルトの動作でないのか不思議です。私は、この選択に関連したどんな種類のメーリングリストの議論も探していると思います。 – shians

+0

また、それは機能です。場合によっては、引数のない関数を呼び出すことができるという利便性が必要な場合があります。これを可能にする多くの機能が実装されています。 – Roland

+0

これらの多くの機能の例を回答として掲示し、それがなぜ必要なのかを教えてください。 – shians

関連する問題