Common Lispの系譜を継ぐマイコン上のuLispをラズパイPico2上で練習中です。前回は指数、対数系の演算関数を練習。計算精度を除けばCommon lisp とuLispに違いなし、平穏無事。今回は、乱数、最大最小、丸めなどやってみます。概ね一緒ではあるものの、コマケー違いがあるんだ、今回は。
※Lispと一緒 投稿順 index はこちら
※実機確認は Raspberry Pi Pico2で行ってます。
※使用させていただいとります uLisp のバージョンは 4.6b (Arm用)です。
※uLispとCommon Lispとの動作比較のために使わせていただいている処理系は以下です。
SBCL 2.2.2 (SBCL = Steel Bank Common Lisp )
乱数、random
random関数は第1引数のみで乱数を「振り出して」いる分には、Common Lisp でも uLisp でもプログラミング的には差がありませぬ。しかし、Common Lispと uLispでは、「そもそもの」乱数に対するスタンスが大きく異なっているみたい。uLispでは存在せず、Common Lispに存在する *random-state* 変数を見るとそれが理解されます。
おお、何だか分からんけど、Common Lispのrandomの計算の裏にはこんなステートが隠れているのね。当然プログラマが介入可能です。一方、uLispの方は、Arduino IDEから呼び出せる処理系の乱数関数に依存。
見掛けじゃ変わりないけれども。まずはCommon Lisp。
どちらも第1引数に与えた数を超えない非負の数を返してくれるようです。引数が整数なら整数、浮動小数なら浮動小数で返ります。
float
数値を浮動小数点数に変換してくれる float関数については、「コマケー違い」があります。Common Lispの場合、浮動小数点数といってもフォーマットは1種類ではなく、複数存在。変換先も複数あるということです。一方 uLispの場合はどうも単精度浮動小数の一択。よって
-
- Common Lispの場合、第2引数に浮動小数点数を与えることで返る値を第2引数と同じフォーマットにできる。第2引数は無でも可。
- uLispの場合、第2引数など無い。指定するとエラーになる
最大、最小
Common Lispでも uLisp でも、整数、浮動小数まぜてもちゃんと最大最小を返してくれます。ただし、uLispは分数(レシオ)が無いのでサブセット的です。
ceiling、floar、trancate、round
丸め系の一族?4兄弟は、フツーに使っている分には Common Lispと uLispの差は感じられないかと思います。しかし奥深いところで大きく違ってます。
Common Lispでは、こいつらは「多値を返す」関数群です。2番目の戻り値に「余り」に相当する値を返してきます。ただし2番目の値を取り出すためには専用のマクロなどを使って受け止めないとならないので、1番目の戻り値だけが返るつもりでプログラム書いてもエラーにならない筈。
一方、uLispでは、そもそも「多値を返す」ような仕組みなど無いみたいなので、Common Lispの2番目の戻り値は使えませぬ。
ううむ、使い込まないと見えてこない差であるような。Lisp素人老人は使わんよな。