tag:blogger.com,1999:blog-9089624119221753010.post8341019073791638978..comments2023-11-30T19:05:15.988+09:00Comments on vallog: scheme(gauche)でもsleep-sortvalvallowhttp://www.blogger.com/profile/08767555476671212941noreply@blogger.comBlogger2125tag:blogger.com,1999:blog-9089624119221753010.post-78277964984784035112011-05-21T14:03:52.093+09:002011-05-21T14:03:52.093+09:00shiroさんコメントありがとうございます!
> 意図としては、「マクロ展開後には既にソート...shiroさんコメントありがとうございます!<br /><br />> 意図としては、「マクロ展開後には既にソートされている定数リストになってて欲しい」んですよね?<br />はい、その通りです。<br /><br />evalを使う場合とevalを使わない場合の問題がよくわかりました。<br />特にevalを使わない場合にどんな手段があるのかわからなかったので勉強になりました。<br />ありがとうございます!valvallowhttps://www.blogger.com/profile/08767555476671212941noreply@blogger.comtag:blogger.com,1999:blog-9089624119221753010.post-64828663201353033352011-05-21T06:10:34.894+09:002011-05-21T06:10:34.894+09:00引数の式を評価した結果をごにょごにょするマクロなら、evalを使わずに「結果を評価してapplyする...引数の式を評価した結果をごにょごにょするマクロなら、evalを使わずに「結果を評価してapplyするような式」に展開するのが定石です。でもそれだと今回の場合、こうなっちゃいます:<br /><br />(define-macro (macro-sleep-sort2 num-expr)<br /> `(apply sleep-sort ,num-expr))<br /><br />意図としては、「マクロ展開後には既にソートされている定数リストになってて欲しい」んですよね?<br /><br />原則として、マクロはコンパイル時に展開され、普通の式の値は実行時に求められます。コンパイルは実行の前に起きるので、マクロ展開器は「与えられた式の値」を使うことはできません。マクロ展開器に見えるのは「与えられた式そのもの(S式)」だけです。<br /><br />で、その原則を破るのがevalってわけです。原則破りなので、色々注意が必要です。例えばvalvallowさんのコードは、macro-sleep-sort2が別のモジュールに定義されててimportして使ってる時にはうまくいきません。current-moduleはコンパイル時のモジュールになるので、常にmacro-sleep-sort2が定義されているモジュールでevalされちゃいます。<br /><br />evalを使わない場合は、リスト生成の機能そのものをマクロでできるようにするという手があります。これは任意の式を受け取るようにはできないんですが、num-exprの式が(make-rand-list K) であることを調べてマクロ内で自分でK要素のrandom listを生成するとか、そういう手です。(これを完全に汎用的にしようとすると、自分でevalを作るのと同じことになります)。shirohttp://blog.practical-scheme.net/shironoreply@blogger.com