Gaucheで指定した数の数字の配列を作るiota
「1から10までの配列から奇数だけを取り出す」というお題を見てGaucheだとこう書くかなって考えた時に、Gaucheで「数字を指定して範囲を取り出す関数って何だっけ」となったのでメモ。
iota
iota
だった。最初range
とかtimes
とかの単語でドキュメント引いて見つからなくてアレってなった。
Function: iota count :optional (start 0) (step 1)
[SRFI-1] startから始まり、stepずつ増加する、 count 個の要素からなる数値のリストを返します。countは 非負の整数でなければなりません。startとstepが ともに正確数であれば、結果は正確数のリストになります。そうでなければ 結果は非正確数のリストです。
ちなみに語源はギリシャ語のイオタらしい。
the index generator → index → i → ι → iota
「素数夜曲」、書店で目立つので存在知っていたけど数学的な本で難しそうと思ってスルーしていた。 これタイトルにLISPとあるけどサンプルコードはSchemeだったのか。
追記: Gauche作者のShiroさんからリプライ頂きました
@kanno_kanno lazyなリストを作るlrangeとかliotaってのもあります。リストが巨大になる時は一度に作るとメモリの無駄なので。あと、iotaというのはAPLの演算子から来ています。C++のstd::iotaも同様。
— Shiro Kawai (@anohana) May 13, 2017
使用例
冒頭のお題を解くのは簡単。
gosh> (filter odd? (iota 10 1)) (1 3 5 7 9)
カッコを入れ子にしたくなければ$を使うと良い。
gosh> ($ filter odd? $ iota 10 1) (1 3 5 7 9)
$ arg …
関数適用をチェインするマクロです。Haskellの$にヒントを得ました (意味は異なりますが)。 マクロ引数arg …中に$が出現すると、それが 関数の最後の引数の区切りとなります。例えば次のコードでは、 関数fの最後の引数が(g c d …)となります。
おまけ: 他の言語での解答
この程度だとほとんどのスクリプト言語で1行でサクッと済ませられそうだなと思ったので、ぼくが少なからず書ける言語でどう書くか試してみた。
(1..10).select &:odd?
[x for x in range(1, 10) if x % 2 != 0]
Perl。半年ぶりぐらいなのでちょっと書き方忘れてた。
grep { $_ % 2 != 0 } (1..10);
PHP。ちょっとつらい。
<?php array_filter(range(1, 10), function($n) { return $n % 2 != 0; });
Vim script。久々すぎて「Vim ScriptだっけVim scriptだっけ」ってなった。
filter(range(1, 10), 'v:val % 2 != 0')