備忘ログ

チラシの裏的備忘録&メモ

R 4.1.0で導入された`function`関数の短縮形としての`\`についてちょっと見てみた

R 4.1.0でfunction関数の短縮形として\関数(関数?functionのhelpドキュメントにはThese functions と書かれている)が導入されたのでちょっと見てみた。

自分なりに調べた範囲のメモ。

とりあえず、次のような与えられた値に1を加えるfと同じ挙動をするf2関数を作る。

f <- function(x) x + 1
f2 <- \(x) x + 1

どちらもちゃんと同じ挙動をする。

f(2)
## [1] 3
f2(2)
## [1] 3

RStudioの標準で右上のGlobal Environmentをみるとどちらもfunctionsのところで、つぎのように表示され見分けがつかない。

GE

printprint.function)関数で中身をみるとちゃんと違う。

print(f)
## function(x) x + 1
print(f2)
## \(x) x + 1

RStudio(Version 1.4.1106)のSourceのPanelでみるとデフォルトでは次のように\を使うとunexpected tokenと表示されて赤波線が引かれる(今後対応されるかもしれないし、もしかしたらすでに設定があるかもしれないがよくわからなかった)。

token

(追記)

Preview版のRStudio v1.4.1712-1 Preview

Support for the upcoming R 4.1.0 release, including the new |> pipe, \(x) function shorthand, and new graphics engine.

とあったので、RStudioの次期リリースからサポートされると思われる。

(追記終わり)

functionではなく、functionの代わりに\で書いた関数もパッケージ化できたし、R 4.1.0だったらちゃんとインストールできた。

R 4.0.5以前では\functionの短縮形として認識されていないので、\で関数を作ったパッケージはソースコードからインストールことはできない(\がよくわからないよというエラーが出る)。Windowsであれば、R 4.1.0でzipでバイナリを作成すればR 4.0.5でインストールすることができ、意図した挙動ができた。

R 4.0.5以前ではwindowsならバイナリでインストールできるがmacLinuxはzipバイナリからのインストールができないので、混乱を避けるために\で関数を作っているものをパッケージ化する場合はDependentで4.1.0以上を指定したほうがよいかと思う。または\じゃなくて、functionで書くとか。個人的には後者のほうがパッケージ化するなら良いのではないかと思う。

CRANに登録する場合に\でも行けるのかどうかはCRANのポリシーがどうなっているかまでは調べてないないのでよくわからない。

functionのhelpドキュメントに

The shorthand form \(x) x + 1 is parsed as function(x) x + 1. It may be helpful in making code containing simple function expressions more readable.

と書いてあるので、単純なコードの場合は読みやすくなるかもしれない。

ただ、上記のようにパッケージ化する場合には注意を要するし、コードが長くなる場合や文字列処理でバックスラッシュでエスケープかけているコードでは、functionと書いてあると「あぁ、ここから関数ね。」とわかりやすそうなので適所があるのかもしれないと思う。使ってみないと分からない。

蛇足だが、R 4.1.0の新機能であるbase版のパイプの|>を使って\で無名関数を作って

2 |> (\(x) x + 1)
## Error: function '(' not supported in RHS call of a pipe

という(R 3.6xから見たら怪文書的な)コードがかけそうだがエラーがでる。これは別に\が問題なのではなくて、functionでも同じエラーがでる。

解決策としては

2 |> (\(x) x + 1)()
## [1] 3

とするのが一つの解決策となる模様。他にも解決策的なのはある様子。

これはどうも、カッコなしで関数を呼び出すのを|>がサポートしていない模様のための様子。調べていたら、Peter Dalgaard氏がR 4.1.0リリースしたよというTwitterに画像で投稿したコード(2 |> \(x) x + 1)が動かないというものを見つけた。

ちなみに、古い開発バージョン(release版よりもちょっと前のバージョン)のRではPeter Dalgaard氏のコードでも動く様子(だからどうしたという話ではある)。

{magritter}%>%はそういうの(カッコなしで関数呼び出し的なの)サポートしているので、

library(magrittr)

2 %>% (\(x){x + 1})
## [1] 3

でも動く。だからどうしたというところはある。

sessionInfo()を併記しておく。

sessionInfo()
## R version 4.1.0 (2021-05-18)
## Platform: x86_64-w64-mingw32/x64 (64-bit)
## Running under: Windows 10 x64 (build 19042)
## 
## Matrix products: default
## 
## locale:
## [1] LC_COLLATE=Japanese_Japan.932  LC_CTYPE=Japanese_Japan.932   
## [3] LC_MONETARY=Japanese_Japan.932 LC_NUMERIC=C                  
## [5] LC_TIME=Japanese_Japan.932    
## 
## attached base packages:
## [1] stats     graphics  grDevices utils     datasets  methods   base     
## 
## other attached packages:
## [1] magrittr_2.0.1
## 
## loaded via a namespace (and not attached):
##  [1] compiler_4.1.0    tools_4.1.0       htmltools_0.5.1.1 yaml_2.2.1       
##  [5] stringi_1.6.2     rmarkdown_2.8     knitr_1.33        stringr_1.4.0    
##  [9] xfun_0.23         digest_0.6.27     rlang_0.4.11      evaluate_0.14

R 4.1.0の正式版がリリースされたので誰か新機能をフォローアップしている賢い人がいい感じにR 4.1.0についてまとめてくれるだろう(他力本願)。