Julia Advent Calendar 2016 です。12月9日の記事を 12月27日に投稿しました。
Julia でも、Ruby のようなオブジェクト指向の構文で書きたい。その要望に Lazy.jl
パッケージが応えます。
(その1) 文字列置換
文字列を置換するには replace
を使います。
julia> s="123"
"123"
julia> s=replace(s,"2","b")
"1b3"
julia> s=replace(s,"3","c")
"1bc"
replace
は、元の文字列を更新しません (文字列は immutable だから)。ですので、文字列置換を複数回行うには、s=replace(s,from,to)
を繰り返して適用することになります。面倒ですね。
Ruby では、これをメソッド・チェーンできれいに書けます。一時変数も不要です。
# Ruby
"123".sub("2","b") # => "1b3"
"123".sub("2","b").sub("3","c") # => "1bc"
Julia では、 Base.|>
を使って function chain を書けますが、無名関数を書く必要があり、いまいちイケていません。(別記事へのコメント )
julia> "123" |> (x -> replace(x,"2","b")) |> (x -> replace(x,"3","c"))
"1bc"
さて、クリスマス・プレゼントに、Lazy.jl
パッケージを頂きました。
@>
マクロを使えば、Julia でも似たように書けますよ。
julia> Pkg.add("Lazy")
julia> using Lazy
julia> @> "123" replace("2","b")
"1b3"
julia> @> "123" replace("2","b") replace("3","c")
"1bc"
繰り返し文字列置換を適用できて、大満足です。
(その2) map, foreach
Julia の map
は map(func, collection...)
という引数をとります。func を do...end
ブロックで後置する構文もあります。いずれにせよ map
から始まります。
julia> map(x-> sin(x), [1,2,3])
3-element Array{Float64,1}:
0.841471
0.909297
0.14112
julia> map([1,2,3]) do x sin(x) end
3-element Array{Float64,1}:
0.841471
0.909297
0.14112
Ruby のmap
は、配列に対する操作を簡潔に書けますね。
# Ruby
[1,2,3].map do |x| Math.sin(x); end
# => [0.8414709848078965, 0.9092974268256817, 0.1411200080598672]
Ruby がうらやましい ?
いやいや、@>>
マクロを使えば、Julia でも似たように書けますよ。
julia> @>> [1,2,3] map() do x sin(x) end
3-element Array{Float64,1}:
0.841471
0.909297
0.14112
計算結果が不要なら foreach
を使いましょう。
julia> @>> [1,2,3] foreach() do x println(sin(x)) end
0.8414709848078965
0.9092974268256817
0.1411200080598672
種明かしは初夢で
Lazy.jl
のドキュメントをどうぞ。
https://github.com/MikeInnes/Lazy.jl#macros
(その3) map を連結できる
2017/01/03 追記
( 初夢を見ました。まだ種明かしはしませんが )
# Ruby
[1,2,3].collect{|x| Math.sin(x)}.collect{|x| x+1 }
# => [1.8414709848078965, 1.9092974268256817, 1.1411200080598671]
Julia でも map
を連結できます。
julia> @>> [1,2,3] map() do x sin(x) end map() do x x+1 end
3-element Array{Float64,1}:
1.84147
1.9093
1.14112