読者です 読者をやめる 読者になる 読者になる

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が ともに正確数であれば、結果は正確数のリストになります。そうでなければ 結果は非正確数のリストです。

ちなみに語源はギリシャ語のイオタらしい。

Scheme iota手続きの語源

the index generator → index → i → ι → iota

iotaの由来(素数夜曲)

素数夜曲」、書店で目立つので存在知っていたけど数学的な本で難しそうと思ってスルーしていた。 これタイトルにLISPとあるけどサンプルコードはSchemeだったのか。


追記: Gauche作者のShiroさんからリプライ頂きました


使用例

冒頭のお題を解くのは簡単。

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行でサクッと済ませられそうだなと思ったので、ぼくが少なからず書ける言語でどう書くか試してみた。

Ruby

(1..10).select &:odd?

Python

[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')