0
美しいlispの書きかた~コーディングルール事始め~
自己紹介github.com/insanity です。ときおりWiki{pedia,books}に出没します。得意な方言はScheme です。 今年で使い初めてから4年目です。 Gauche が便利過ぎてしねる。 ちなみにこのスライドもlibc...
自己紹介 (続き)エディタはいつもvimを使っています。 .el を書くまでもなく、その場のコマンドで定型作業をサクッと終 える作りが好きなのです。というわけで、今回の話はemacsに全部お任せでOKという結論ではないです。
今日の話題せっかくなら、読みやすいlispを書きたい。マクロ展開形やVMの中間表現を少しでも読みやすく表示したい。過去に書きなぐったコードを、見栄えだけ良くしたい。元ネタRiastradhs Lisp Style Rules by Taylor...
名前づけ
常識ですが... variable-with-long-nameLispの変数はハイフンでつなぎます。日本語キーボードで変換キーをハイフンを割り当てると便利です。(linuxならxmodmap) *global-variable*グローバル変数...
コードレイアウト(スペースの入れ方)
はじめにS式のコードの見た目は、スペースと改行の入れ方でほとんど決まります。だから、スペースと改行の入れ方は大事です。
タブか、スペースかlispではインデント揃えを使うので、タブ幅で悩まないスペースがおすすめです。どうしてもタブがいい人は、タブ幅を書いてくれると(僕が)うれしい。; -*- tab-width: 8 -*-; vim:ts=8
ネスト(cdr  (assq     banana     ( (banana . 138)        (apple . 80))))普通、括弧はまとめて閉じます。
インデント量はスペース1つでも大丈夫ですが,(インデント量が   (多すぎると、       (すぐに             (横幅を                    (使い切ってしまい                       (困...
ネスト (続き)項目の一覧表では、((item "banana") (item "apple") (item "orange") )と閉じ括弧だけの行を残すと、項目の追加がやりやすくなります。見栄え的にはちょっと微妙ですが。
ネスト (続き)誤解のおそれのないときは、深さを省略しても大丈夫です(多分)。( define (get-continuaction)   (call/cc (lambda (cont)     (cont cont))))Scheme ではl...
閉じ括弧を優雅に見せようとして、( define (any pred lst) ( cond    ((null? args) #f)    ((pair? args) (or (pred (car lst))                 ...
縦モードと横モード 横モード普通は横につなげて書きます。(map * (1 2 3) (iota 3 2 0.1)) 縦モード括弧の中身が長くなったときは、括弧の中身を縦につなげます。(map *     (1 2 3)     (iota 3...
縦モードと横モード (続き)横モード → 縦モードへの移行は可ですが、それ以外は不可です。
例( let1 ht (make-hash-table)   body ...)( if (not (is-a? language lisp))   (error "Please speak it in Lisp!.")   (eval inp...
平行四辺形コードは、上から下へ流れるように読めるので、ネストの多いS式は、最初から縦モードで書くのがおすすめです。 例外:keyword value の組や、arc のように括弧が書略されている時は横に並べたほうが見やすいです。
深さインデントと、揃えインデント深さインデントは、純粋に括弧の深さでスペースの量を決めます。( define (is-a? obj type)   (eq? (car obj) type))( defun is-a? (obj type)   ...
揃えインデントは、第一引数の位置に、それ以後の引数の位置を合わせる方式です(list (apply average lis)      (apply min lis)      (apply max lis))揃えインデントの方をCanonic...
cond, caseの書きかた条件部を見やすく揃えるのが大事です。( cond   ((pred   a) ...)   ((pred   b) ...)( cond   ((pred   a)      ...      ...   )   ...
空行基本的には、トップレベル定義の区切り、internal defineの区切りにのみ使います。ただし、「手続き型」の関数で、コメント行の前に空行を入れるのはありだと思います。( define (test)   ( define (test-a...
Upcoming SlideShare
Loading in...5
×

kyotolisp#1 LT3 美しいLispの書き方 (1)

5,329

Published on

kyotolisp#1 (kyotolisp.github.com) で発表した内容です。スライドは(2)に続きます。

Published in: Technology
0 Comments
6 Likes
Statistics
Notes
  • Be the first to comment

No Downloads
Views
Total Views
5,329
On Slideshare
0
From Embeds
0
Number of Embeds
7
Actions
Shares
0
Downloads
12
Comments
0
Likes
6
Embeds 0
No embeds

No notes for slide

Transcript of "kyotolisp#1 LT3 美しいLispの書き方 (1)"

  1. 1. 美しいlispの書きかた~コーディングルール事始め~
  2. 2. 自己紹介github.com/insanity です。ときおりWiki{pedia,books}に出没します。得意な方言はScheme です。 今年で使い初めてから4年目です。 Gauche が便利過ぎてしねる。 ちなみにこのスライドもlibcairo on Gauche with c-wrapper で レンダリングされています。 現状カオスなコードですが一応 github/insanity/lightcontain er で晒してます。
  3. 3. 自己紹介 (続き)エディタはいつもvimを使っています。 .el を書くまでもなく、その場のコマンドで定型作業をサクッと終 える作りが好きなのです。というわけで、今回の話はemacsに全部お任せでOKという結論ではないです。
  4. 4. 今日の話題せっかくなら、読みやすいlispを書きたい。マクロ展開形やVMの中間表現を少しでも読みやすく表示したい。過去に書きなぐったコードを、見栄えだけ良くしたい。元ネタRiastradhs Lisp Style Rules by Taylor R. Campbell(http://mumble.net/~campbell/scheme/style.txt)
  5. 5. 名前づけ
  6. 6. 常識ですが... variable-with-long-nameLispの変数はハイフンでつなぎます。日本語キーボードで変換キーをハイフンを割り当てると便利です。(linuxならxmodmap) *global-variable*グローバル変数です。グローバル変数は副作用によって変更されるかもしれない、という警告の意味で(多分)、強調します。定数を表すときもあります。SOME-CONSTANTよりかは読みやすいと思います。 +some-constant+と書く流派もあるようです。
  7. 7. コードレイアウト(スペースの入れ方)
  8. 8. はじめにS式のコードの見た目は、スペースと改行の入れ方でほとんど決まります。だから、スペースと改行の入れ方は大事です。
  9. 9. タブか、スペースかlispではインデント揃えを使うので、タブ幅で悩まないスペースがおすすめです。どうしてもタブがいい人は、タブ幅を書いてくれると(僕が)うれしい。; -*- tab-width: 8 -*-; vim:ts=8
  10. 10. ネスト(cdr (assq banana ( (banana . 138) (apple . 80))))普通、括弧はまとめて閉じます。
  11. 11. インデント量はスペース1つでも大丈夫ですが,(インデント量が (多すぎると、 (すぐに (横幅を (使い切ってしまい (困ります))))))そもそも読みにくいと思います。
  12. 12. ネスト (続き)項目の一覧表では、((item "banana") (item "apple") (item "orange") )と閉じ括弧だけの行を残すと、項目の追加がやりやすくなります。見栄え的にはちょっと微妙ですが。
  13. 13. ネスト (続き)誤解のおそれのないときは、深さを省略しても大丈夫です(多分)。( define (get-continuaction) (call/cc (lambda (cont) (cont cont))))Scheme ではlambda をやたらめったら使うので、ネストがすぐに深くなるのでちょっと横着しています。map for-each では、手続きとリストを区別するために、省略しない方が読みやすい。
  14. 14. 閉じ括弧を優雅に見せようとして、( define (any pred lst) ( cond ((null? args) #f) ((pair? args) (or (pred (car lst)) (any pred (cdr lst)))) ) )と書く人[Gassanenko,2001]もいるそうですが、論理的に矛盾しています。(なのでemacsマクロが必須だとか。視覚的情報は括弧に頼らず、インデントの深さで判断するようにするのがベストと思っています。
  15. 15. 縦モードと横モード 横モード普通は横につなげて書きます。(map * (1 2 3) (iota 3 2 0.1)) 縦モード括弧の中身が長くなったときは、括弧の中身を縦につなげます。(map * (1 2 3) (iota 3 2 0.1))
  16. 16. 縦モードと横モード (続き)横モード → 縦モードへの移行は可ですが、それ以外は不可です。
  17. 17. 例( let1 ht (make-hash-table) body ...)( if (not (is-a? language lisp)) (error "Please speak it in Lisp!.") (eval input env));XXX(http-post http-client server port path `((id ,(sanitize (get-config user-id)) ((timeout 2000) (follow-redirect #f))
  18. 18. 平行四辺形コードは、上から下へ流れるように読めるので、ネストの多いS式は、最初から縦モードで書くのがおすすめです。 例外:keyword value の組や、arc のように括弧が書略されている時は横に並べたほうが見やすいです。
  19. 19. 深さインデントと、揃えインデント深さインデントは、純粋に括弧の深さでスペースの量を決めます。( define (is-a? obj type) (eq? (car obj) type))( defun is-a? (obj type) (eqp (car obj) type))))
  20. 20. 揃えインデントは、第一引数の位置に、それ以後の引数の位置を合わせる方式です(list (apply average lis) (apply min lis) (apply max lis))揃えインデントの方をCanonicalとみなす人が多いようですが、多用するとコードがすぐに右へ飛んでいってしまうので、個人的には深さインデントが好みです。letの束縛部、and, or, list, 四則演算に限って使うことにしています。
  21. 21. cond, caseの書きかた条件部を見やすく揃えるのが大事です。( cond ((pred a) ...) ((pred b) ...)( cond ((pred a) ... ... ) ((pred b) ... ... ))どちらかに統一するといい感じです。
  22. 22. 空行基本的には、トップレベル定義の区切り、internal defineの区切りにのみ使います。ただし、「手続き型」の関数で、コメント行の前に空行を入れるのはありだと思います。( define (test) ( define (test-aux-1) ... ) ( define (test-aux-2) ... ) body ... )
  1. A particular slide catching your eye?

    Clipping is a handy way to collect important slides you want to go back to later.

×