3
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 3 years have passed since last update.

JuliaのソースコードからOperatorを読み解いてみた その1

Posted at

その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...) means f(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内部構造の話ばかりで申し訳ないです。

3
1
2

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
3
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?