概要
ただのおあそびです。
R でプログラムスライシング #rstatsjに負けない関数を作ります。
※fix_slicing関数の内容等については、上のリンク先を参照してください。
そもそものモチベーション
ifの中でprintしたりするとどうなるのかな、ということを思ったわけです。本当に最初に思ったのは、副作用はどうなるんだろう、ということだったんですが。
unnaturalFunction0
> unnaturalFunction0 <- function(a,...){
+ if(T | print(a))
+ a
+ }
> fix_slicing(unnaturalFunction0(a=1:2))
function (`a = 1:2`, ...)
if (T | print(1:2)) 1:2
むむむ、意外とかしこい(?)
他にも結構いろいろ試してみた結果、結構かしこいということがわかりました。
かくなる上は…ということで、逆転の発想で、プログラムスライシングに負けない関数を作ることにしました。
できあがった関数
unnaturalFunction1
> unnaturalFunction1 <- function(a,...){
+ add <- function(a,b){
+ a + b
+ }
+ add(a,a)
+ }
> fix_slicing(unnaturalFunction1(a=1:2))
function (`a = 1:2`, ...)
{
add <- function(a, b) a + b
add(1:2, 1:2)
}
{}等がちょっと変わっているものの、addの部分が生き残りました。やったー。
ちなみに、これ、addを使わないと、賢く処理されてしまいます。
naturalFunction1
> naturalFunction1 <- function(a,...){
+ a + a
+ }
> fix_slicing(naturalFunction1(a=1:2))
function (`a = 1:2`, ...)
c(2L, 4L)
「ああああnaturalFunction1さま…!あのような痛ましいお姿になって……!」
と言わんばかりに無残に見事にスライシングされてしまいました。
もっと意地悪をする
要するにfunction()
まで最適化はできない、という感じなので、こういうこともできます。
unnaturalFunction2
> unnaturalFunction2 <- function(a,...){
+ t <- function(a){
+ if(T) a
+ }
+ t(a)
+ }
> fix_slicing(unnaturalFunction2(a=1:2))
function (`a = 1:2`, ...)
{
t <- function(a) if (T)
a
t(1:2)
}
if(T)
が許されるのは小学生までだよねーキャハハハハハハ
※すみません嘘です。
おしまい
既存関数から類似の処理を作成したり、デバッグにも使えそうですね。便利で非常に面白いです。
たのしめ!