LoginSignup
4
4

More than 5 years have passed since last update.

Rでプログラムスライシングに負けない関数をつくる

Last updated at Posted at 2016-01-18

概要

ただのおあそびです。
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)が許されるのは小学生までだよねーキャハハハハハハ
※すみません嘘です。

おしまい

既存関数から類似の処理を作成したり、デバッグにも使えそうですね。便利で非常に面白いです。

たのしめ!

4
4
7

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
4
4