R6RS Scheme で Erlang のビット構文
Erlang にはビット構文という素敵な仕組みがあって、簡単に pack/unpack することができる。
1> Color = <<Red:5,Green:6,:Blue:5>>. 2> <<R:5, G:6, B:5>> = C.
こういうの。
直感的で分かりやすくてうらやましい。Scheme ならマクロで書けそうだなと思い。unpack だけ簡単なものを書いてみました。
途中で面倒になって汎用版は投げ出してしまった。
当然ながら今は、最適化とかしていないので遅いのだけど、やっぱり読みやすい。ネットワークパケットとかと相性が良かったりしないかな?
ちゃんとしたものを書いて、comp.lang.scheme に投稿してみるのも面白いかも。
(import (rnrs) (srfi :64)) (define-syntax :bit (lambda (x) (syntax-case x () [(_ ([a m] [b n]) v body ...) (and (fixnum? (syntax->datum #'m)) (fixnum? (syntax->datum #'n)) (zero? (mod (+ (syntax->datum #'m) (syntax->datum #'n)) 8))) #'(let ([bits (+ n m)]) (let ([a (bitwise-arithmetic-shift-right v (- bits m))] [b (bitwise-and v (- (expt 2 n) 1))]) body ...))]))) (test-begin "Example of the bit syntax") ;; unpack (:bit ([x 2] [y 6]) #b10101110 (test-eqv 2 x) (test-eqv 46 y)) (test-end)
追記
id:leque さんが汎用版を書いてくださいました。
Scheme で Erlang のビット構文 - 月の塵。
let-bit というネーミングセンスが良いですねー。