その2以降は無いかもしれないです。
当方の環境は以下です。
OS OSX Catalina
開発環境 JuliaPro 1.4.2-1
従って ATOM + Juno + Julia 1.4.2 とほぼ同等になります。
1."|>" をソースコードから楽しむ
フォーラムなどではいつの間にか普通に使われていたオペレーターに “|>”があります。
Piping とかPipe Opratorと呼ばれておりました。
ディスカッション・フォーラムの投稿を見て
df = CSV.File(“Test.csv") |> DataFrame
等という使い方をしていたのですが、今回、念の為にドキュメントとソースコードを調べてみました
PDFには、12.6 Operator Precedence and Associativityに纏めて記載がありますが、詳細では無いです。
まずは、REPLからHELPモードに移行 −> “?”を入力
help?> |>
search: |>|>(x, f)
Applies a function to the preceding argument. This allows for easy function chaining.
**(拙訳)**先行する引数に関数を適用する。これで関数の連結が簡単になります。Examples
≡≡≡≡≡≡≡≡≡≡julia> [1:5;] |> x->x.^2 |> sum |> inv
0.01818181818181818
と出てきた。
ま、その通りですね。
有る意味、Unix系のシェルでは当たり前の” |" に近い考え方が使えるという事です。
なぜ、” |” を使わないかというと、既に使っているからですね。
で、マニュアルを見ると
Function chaining (sometimes called "piping" or "using a pipe" to send data to a subsequent function) is when you apply a function to the previous function's output:
**(拙訳)**関数連結(時に”Piping "や “Pipeを使う”と呼ばれる後続の関数にデータを送る)とは、前の関数の出力を関数を適用する。
julia> 1:10 |> sum |> sqrt 7.416198487095663
Here, the total produced by sum is passed to the sqrt function.
**(拙訳)**ここでは、sumによって生成された合計がsqrt関数に渡される。
The equivalent composition would be: julia> (sqrt ∘ sum)(1:10)
(sqrt ∘ sum)(1:10)
7.416198487095663
注:このブロックは後の"∘" でも説明します。
The pipe operator can also be used with broadcasting, as .|>, to provide a useful combination of the chain- ing/piping and dot vectorization syntax (described next).
**(拙訳)**pipe演算子は、.|>のようにブロードキャストと一緒に使用でき、chain- ing/piping構文とドットベクトル化構文の便利な組み合わせを提供します(次で説明)。
julia> ["a", "list", "of", "strings"] .|> [uppercase, reverse, titlecase, length] 4-element Array{Any,1}:
"A"
"tsil"
"Of"
7
拙訳なので、大体の意味が合っているというレベルで勘弁してください。
で、早速ソースコードを確認。どの言語でもオペレーターの実装の確認は楽しみです。
base/operator.jlに有りました
該当部分のコメントを除いて本体だけ見ると
|>(x, f) = f(x)
あー、シンプルですね。
そうかぁ、 Juliaではオペレーターをこうやって宣言するのか。
例えば、 **30 |> sin は、sin(30)**と同じというになります。
という事は他のオペレーターはどうなるのか?
試しに
julia> +(1,2)
3
julia> -(4,3)
1
julia> *("AAA","BBB")
"AAABBB"
なるほど、じゃ、という事で
|>("TEST",println)
TEST
おー、面白い
2.Operatorを定義して楽しむ
REPLから定義してみた
>Julia> ~(x,f)=f(x)
~ (generic function with 1 method)
>julia> 30 ~ sin
-0.9880316240928618
>julia> ["a", "list", "of", "strings"] .~ [uppercase, reverse, titlecase, length]
おー、動いた。オペレーターを定義出来た。うれしい
ちゃんと動く。
試しに
~~(x,f)=f(x)
ERROR: syntax: "(x ~ f)" is not a valid function argument name
2文字は駄目だった。多分2文字目の~が通常のBitwise notと解釈されている模様。
ついでに
julia> |~(x,f)=f(x)
ERROR: syntax: "|" is not a unary operator
あー、もしかすると単項演算子、2項演算子が絡んでいるのかもしれない
(unary operatorは単項演算子、binary operatorが2項演算子)
よくあるオペレーター文字?は色々とバッティングするので、別の文字でアプローチをしてみる。
julia> 💩(x, f) = f(x)
💩 (generic function with 1 method)
julia> 💩(30,sin)
-0.9880316240928618
よし!!来い!!🎴!!
julia> 30 💩 sin
ERROR: syntax: extra token "💩" after end of expression
駄目だった。
変数や関数名にはUnicode文字は使えるけど、オペレーターには使えない模様。
これを修正するには、もっとparser内部まで入り込まないと難しいと推定(諦めたとも言う)
ソースコードを見ると
julia/src/support/utf8.cあたりから追いかけないといけないかもしれない。
元気なUncode文字使いたかったな。
一番楽な使い方は、
df = CSV.File(“Test.csv") |> DataFrame
かなぁ。ディスカッションフォーラムでも変数の型変換とか、こんな使い方が一番多いようです。
#3.” ∘ ” (\circ) をソースコードから楽しむ
“|>”の説明の所にもありましたが、“|>” の記述部分の直下に、もう一つ面白そうなオペレーターの記述を発見
” ∘ ” \circで入力できます。(\circまで入力してTAB入力で変換される)
全角文字の”・"では無いので注意。
説明としては
f ∘ g
Compose functions: i.e.(f ∘ g)(args...)
meansf(g(args...))
. The∘
symbol can be
とある。
1.14.2のPDFマニュアルを見ると15.15 Function composition and pipingにもう少し詳しい使い方がある。
使い方は割と簡単で
julia> sin(cos(tan(45)))
-0.04893972631137305
julia> (sin ∘ cos ∘ tan)(45)
-0.04893972631137305
と記述できる。()の数を間違える可能性が減ります。
PDFには、(sqrt ∘ +)(3, 6)の例もあります。
これは、sqrt(3+6)と等価となる訳ですね。
うーん、自分では使わないな。
オペレーターが定義できる事が判明したので拡張したいのですが、
力尽きたので、以上です。
Julia内部構造の話ばかりで申し訳ないです。