#はじめに
こんにちは、meganeoです。
sugarというNimの面白い標準モジュールを見つけたので紹介します。
環境
Nim 1.4.2
#sugarとは
sugar
は、Nimの標準モジュールの1つです。
macroを使い、複雑なものを簡潔に書けるようにしています。
##import
import sugar
=>
=>
は、JavaScriptでいうところのアロー関数です。
無名関数を簡潔に書くことができます。
proc TwoFunc(f: proc(int, int): int): int =
f(2, 2)
TwoFunc((x, y) => x + y)
#->
->
は、↑のような高階関数を定義するとき、引数を簡潔に書くことができます。
proc TwoFunc(f: (int, int) -> int): int =
f(2, 2)
#dump
dump
は、引数に入れた式とその結果を出力します。
let
x = 10
y = 5
a = "a"
b = "b"
dump(x + y) # output: x + y = 15
dump(a & b) # output: a & b = ab
#capture
caputure
は、ループ内で任意の条件に当てはまる場合に、グローバルスコープに値を返すのに便利です。
# グローバルスコープで関数型の変数を先に定義しておく
var MyClosure: proc
for i in 3..5:
for j in 4..8:
if i * j == 28:
capture i, j: #キャプチャーしたい値を引数にする
MyClosure = () => dump(i * j)
MyClosure() # output: i * j = 28
当たり前ですが、当てはまる条件が複数の場合は最後にループした方が優先されます。
var MyClosure: proc
for i in 3..5:
for j in 4..8:
if I * j in [28, 32]:
capture i, j:
MyClosure = () => dump(i * j)
MyClosure() # output: i * j = 32
#dup
dup
は、引数として渡した変数を内部で変更してしまう関数(いわゆる破壊的メソッド)を、元のデータに影響なく使うことができます。
import algorithm
var a = @[5, 4, 3, 2, 1]
echo sorted(a) # output: @[1, 2, 3, 4, 5]
echo sorted(a) == a.dup(sort) # output: true
#collect
collect
は、Pythonの内包表記のように、配列を元に配列や辞書を生成できるマクロです。
collect
のブロック内の最後の式が評価され、その配列が指定した関数(ここではnewSeq)に渡されるようです。
つまり、自作のコンテナ型のコンストラクタも使うことができるということです。
let nineNum = @[1, 2, 3, 4, 5, 6, 7, 8, 9]
let oddNum = collect(newSeq):
for i in nineNum:
if i mod 2 == 1: i
echo oddNum # output: @[1, 3, 5, 7, 9]
let evenNum = collect(newSeq(4)): # 長さ指定もできる
for i in nineNum:
if i mod 2 == 0: i
echo evenNum # output: @[2, 4, 6, 8]
また、table
の{key:value}
やset
のmySet.incl
のようにtable
とset
を生成するには、ブロック内の最後の式を次のように書きます。
import sets, tables
let nineTable = collect(initTable(9)):
for i, d in nineNum.pairs: {i: d} # {key: value}のように書く
echo nineTable # output: {}
let nineSet = collect(initHashSet):
for d in nineNum.items: {d} # 入れたい値を {} で囲う
#まとめ
アドベントカレンダーに参加すること自体初めてなので至らない点もあるかと思いますが、これをきっかけに、少しでもNimに興味を持っていただけたら嬉しいです。最後までお読みいただきありがとうございました!