2017-02-05 4 views
3

ハドレーの「Advanced R」では、ファンクションプログラミングと「ファンクション演算子」の可能なアプリケーションについて簡単に説明します。しかし、私の心配は、これらのコードがどのように単純化されているかを完全には理解していないか、他のソリューションを使用して悪い習慣に従わないことです。ファンクションオペレータとファンクションラッピングR

入力が関数であることを期待する演算子を作成する代わりに、式を引数として受け取り、(呼び出される必要のある関数ではなく)完全な出力を返すラッパーを作成します。例:

# function operator 
delay_by <- function(delay, f) { 
    function(...) { 
    Sys.sleep(delay) 
    f(...) 
    } 
} 

# simple wrapper 
delay_by2 <- function(expr, delay) { 
    Sys.sleep(delay) 
    eval(expr) 
} 

delay_by(1, sqrt)(2) 
delay_by2(sqrt(2), 1) 

operator <- delay_by(1, sqrt) 
wrapper <- function(x) delay_by2(sqrt(x), 1) 

operator(2) 
wrapper(2) 

このアプローチでは、機能(サプリーなど)に入力してメモを適用することができます。また、%>%の配管もサポートしています。

lapply(1:10, function(x) sqrt(x) %>% delay_by2(1)) 

このソリューションの潜在的な欠点は、それが機能の状態を維持する変数を格納するための永続的な実行環境を作成していないということですが、これらは<<- new.env()で明示的に作成することができます。

私のアプローチが劣っていると考える理由はありますか?私は不要なネスティングを避けようとしています。

+1

評価方法では、プリコホール処理が許可されていません。これは、コード・インジェクション・シナリオでも使用される可能性があります。しかし、これらは非生産コードに対するマイナーな懸念事項です。 –

+0

安全性の問題について - 関数演算子がチェックを実行しない場合、与えられた関数がホワイトリストに載っている場合、 'eval()'には何のメリットもないと言っていますか? – mjktfw

+0

実際、あなたが 'eval(,,) 'を使用していて、' eval(parse(..))ではない場合、多分私の反対は成立しません。 –

答えて

3
  • 一つの重要なソフトウェアエンジニアリングの側面は、式ではあまりない、機能をテストし、パッケージに 簡単であるということです。したがって、 関数アプローチを使用する場合は、単体テストを記述してパッケージに入れることができます。 評価アプローチでは、あなた自身のREPLテストに限定されます。明らかに、私たちはすべて、少なくとも生産計画上では "テスト駆動開発"を実行しなければならず、 と経済的に可能なコードの多くをカバーする単体テストのセットなしでは、何もドアの外に出てはならない。これにより、いつでも変更を加える必要があるユーザーの皆様(あなたも含めて) の方が生活がはるかに楽になります。

  • また、関数全体で実行できるコンパイラの最適化がありますが、式ではできません。それは他の言語でも となるでしょうが、Rのコンパイラ がどういうことを言っているかについては分かりません。

  • 私に起こる別の点は、評価ルートが本当にスケーラブルではないということです。つまり、ある程度の複雑さを表現するためには までです。一方、関数を使用すると、 ロジックを実用的なサイズに拡大することができます。

  • 最後に、evalは非常に強力なものですが、トラブルの原因になるものは、高出力レーザーを使用したようなものです。 カット紙。しばしば実装が容易なので、多くの 言語に存在しています。なぜそれが危険であるかについて、ネット上に多くの記事があります。あなたはそれらを見なければなりません。そのような高出力レーザーのように、実際には を必要な場所以外で使用する習慣に入れてはいけません。