Lock in $30 Savings on PRO—Offer Ends Soon! ⏳

scheme-silver-paren.pdf

Niyarin
September 26, 2019

 scheme-silver-paren.pdf

Niyarin

September 26, 2019
Tweet

More Decks by Niyarin

Other Decks in Programming

Transcript

  1. Schemeの仕様1 R7RS ・Schemeの現在主流の仕様 small(コアの部分) :2013- large(たくさんの機能追加): Red(2016) , Tangerine(2019) …

    ・ライブラリとして小分けされている Samll (scheme base) (scheme file) (scheme load) (scheme repl) … Red (scheme list) (scheme sort) (scheme hash-table) … ・基本の(scheme base)ライブラリ以外は提供の選択は自由 → R7RS large以降の処理系ごとの差はさらに広がるかも
  2. Schemeの仕様2 SRFI ・Schemeのライブラリ、言語拡張の仕様(非公式) 。 各機能ごとに番号がつけられている 例:SRFI1 : list ライブラリ  

    SRFI62: S式コメント SRFI106:socketライブラリ いくつかはRnRSにマージされている 例:SRFI1 listライブラリ → R7RS large (scheme list) SRFI62 S式コメント → R7RS small 処理系作者が好きなものを選んでいれる
  3. Schemeのfeatures 処理系の機能をシンボルのリストで持っている > (features) (srfi-111 srfi-106 srfi-95 srfi-60 srfi-43 srfi-26

    srfi-17 srfi-8 srfi-1 srfi-0 r7rs little-endian lp64 x86-64 gnu-linux unix posix ieee-float picrin) ・処理系の名前、バージョン  picrin , gauche , gauche-0.9.8 ・OS環境 windows gnu-linux linux … ・文字コード full-unicode ・ライブラリ r7rs , srfi-111 , ffi , crypto 特に規定はないが、概ね↓のようなものが提供される
  4. Schemeのcond-expand2 test部にはもう少し複雑なことが書ける (and or not library) (cond-expand ((or unix gnu-linux

    bsd) Unix系に依存したなにか ) ((library (srfi 1)) SRFI1に依存したなにか) ((library (scheme list)) Scheme listに依存したなにか))
  5. Silver Parenでの外部表現 ◦パッケージ名の構造 (package-xxx (features gui full-unicode) (version 1.0)) ◦コマンドライン上での表現

    ・二重引用符で囲ったリスト VS 他の表現 sip gosh install package-xxx :feature gui :feature full-unicode :version 1.0
  6. 実装する上で不足している”標準”Scheme機能1 ・ディレクトリ周りの仕様が存在しない 処理系固有のものは当然ある Gaucheの(file util)やSagitarriusの(util file)など → 特定の処理系に依存しないということに反する R7RS largeに期待する Green

    Docket(非ポータブルなライブラリ群) system command か ディレクトリライブラリのどちらかは入るはず だいぶ先になりそう Red(2016) → Tangerine(2019)→Orange(2022?)→Amber(2025?)→ Yellow(2028?) → Green(2031?)
  7. Scheme内で解決することを諦めた Shell Scriptの中で呼び出して、コマンドを受けとる #!/bin/sh function do_command(){ if [ $cmd =

    "create-dir" ]; then target_dir=`eval "echo $opt"` mkdir $target_dir elif [ $cmd = "restart" ]; then restart fi } function read_loop(){ for output in `$TARGET_SCHEME $SILVER_PAREN_PATH/sip-main.scm $OPT $OUTSOURCING_OPT` do if echo $output|grep "^Silver-paren-out-command:" >/dev/null ; then expression=`echo $output|sed "s/^Silver-paren-out-command://g"`; do_command $expression else echo $output fi done } read_loop
  8. R7RSマクロ1 Schemeのマクロ R7RSのマクロ syntax-rules (define-syntax my-let (syntax-rules () ((_ ((name

    value) ... ) body ... ) ((lambda (name ... ) body ... ) value ... )))) ・高水準マクロ(lisp評価を使わない、別言語 ) R6RS(一つ前の仕様) 、 処理系依存のマクロ syntax-case , implicit-renaming , explicit-renaming , syntactic-lambda など (define-syntax my-let (ir-macro-transformer (lambda (form rename compare) (let ((bindings (cadr form)) (bodies (cddr form))) `((lambda ,(map car bindings) ,@bodies) ,@(map cadr bindings))))))
  9. R7RSマクロ2 syntax-rulesで扱いにくいマクロ (ore-quote (1 (1 2 3 4 5) (6

    7 8 9))) ; → (quote (1 (5 4 3 2 1) (6 7 8 9))) (ore-quote (2 (1 2 3 4 5) (6 7 8 9))) ; → (quote (1 (1 2 3 4 5) (9 8 7 6))) ※quasi-quoteに展開すれば楽だけど。 このようなマクロ ore-quoteを考える 引数のCAR部が1なら次の要素をreverseする 2なら次の次の要素をreverseする
  10. R7RSマクロ3 reverse (define-syntax ore-reverse (syntax-rules () ((_ "INTERNAL" (robj ...)

    ()) (robj ...)) ((_ "INTERNAL" (robj ...) (obj1 obj2 ...)) (ore-reverse "INTERNAL" (obj1 robj ...) (obj2 ...))) ((_ (obj ...)) (ore-reverse "INTERNAL" () (obj ...)))))) 展開 (ore-reverse (1 2 3)) → (ore-reverse “INTERNAL” () (1 2 3)) → (ore-reverse “INTERNAL” (1) (2 3)) → (ore-reverse “INTERNAL” (2 1) (3)) → (ore-reverse “INTERNAL” (3 2 1) ()) → (3 2 1)
  11. R7RSマクロ4 ore-quote(失敗) (define-syntax ore-quote (syntax-rules () ((_ (1 ls1 ls2))

    (quote (1 (ore-reverse ls1) ls2))) ((_ (2 ls1 ls2)) (quote (2 ls1 (ore-reverse ls2)))))) 展開 (ore-quote (1 (1 2 3) (4 5 6))) → (quote (1 (ore-reverse 1 2 3) (4 5 6))) quoteの中はリテラルであってlisp式でないのでこれ以上展開されない
  12. R7RSマクロ5 CPSマクロを使う マクロを展開を内側からできればうまくいく → CPSマクロ 次にすることを明示的に渡すマクロ記述スタイル (define-syntax cps-macro-example (syntax-rules ()

    ((_ 次に展開したいマクロ 引数1 引数2 …) (次に展開したいマクロ 展開結果)))) 例えば、今回のケースだと、reverseした後quoteで囲いたい → reverse-CPSマクロは 次に展開したいマクロである”quoteで囲うマクロ”を受け取る
  13. R7RSマクロ5 CPSマクロの動作 (%reverse (syntax-lambda (it) it) (1 2 3 list))

    →(list 3 2 1) 次になにもすることがない(一番外側)の場合 (%reverse (syntax-lambda (it) (quote (1 it (4 5 6))) (1 2 3)) →(quote (1 (3 2 1) (4 5 6))) quoteで囲う例
  14. R7RSマクロ6 syntax-lambdaとは syntax-lambdaにどうやって結果をいれているのか →syntax-lambdaはマクロの機構ではなく勝手につくっただけ → syntax-lambdaをマクロに変換して適用できるようにする (syntax-rules () ((_ (syntax-lambda

    (c-arg) c-body) 引数 1 引数2 …) (let-syntax ((cont-syntax ;↓syntax-lambdaからマクロに変換 (syntax-rules () ((_ c-arg) c-body)))) (cont-syntax ;変換されたsyntax-lambdaに結果を適用 (結果 …) )))
  15. R7RSマクロ7 %ore-quoteはどうなったのか (define-syntax %ore-quote (syntax-rules (syntax-lambda) ((_ (syntax-lambda (c-arg) c-body)

    (1 ls1 ls2)) (let-syntax ((cont-syntax (syntax-rules () ((_ c-arg) c-body)))) (cont-syntax (%ore-reverse (syntax-lambda (it) (quote (1 it ls2))) ls1)))) ((_ (syntax-lambda (c-arg) c-body)(2 ls1 ls2)) (let-syntax ((cont-syntax (syntax-rules () ((_ c-arg) c-body)))) (cont-syntax (%ore-reverse (syntax-lambda (it) (quote (2 ls1 it))) ls2))))))