Hatena::Groupcadr

わだばLisperになる このページをアンテナに追加 RSSフィード

2004 | 12 |
2005 | 01 | 02 | 07 | 10 | 11 |
2006 | 06 | 07 | 08 | 09 | 10 | 11 | 12 |
2007 | 01 | 02 | 03 | 04 | 05 | 06 | 07 | 08 | 09 | 10 | 11 | 12 |
2008 | 01 | 02 | 03 | 04 | 05 | 06 | 07 | 08 | 09 | 10 | 11 | 12 |
2009 | 01 | 02 | 03 | 04 | 05 | 06 | 07 | 08 | 09 | 10 | 11 | 12 |
2010 | 01 | 02 | 03 | 04 | 05 | 06 | 07 | 08 | 09 | 10 | 11 | 12 |
2011 | 01 | 02 | 03 | 04 | 05 | 06 | 07 | 11 |

2008-03-11

CLOSでL-99 (P09 連続して現われる要素を纏める)

| 19:32 | CLOSでL-99 (P09 連続して現われる要素を纏める) - わだばLisperになる を含むブックマーク はてなブックマーク - CLOSでL-99 (P09 連続して現われる要素を纏める) - わだばLisperになる

なんだかあまり面白くないパズルの様相を呈して来ました。こういうのではなくて、まともにCLOSの勉強をしなくては(笑)

(pack '(a a a a b c c a a d e e e e))
;=> ((A A A A) (B) (C C) (A A) (D) (E E E E))

(defmethod pack ((lst null)) () )
(defmethod pack (lst) (pack1 lst () () ))

(defmethod pack1 ((lst null) acc res)
  (nreverse (cons acc res)))
(defmethod pack1 ((lst cons) (acc null) res)
  (pack1 (cdr lst) (cons (car lst) acc) res))
(defmethod pack1 ((lst cons) acc res)
  (if (equal (car lst) (car acc))
      (pack1 (cdr lst) (cons (car lst) acc) res)
      (pack1 lst () (cons acc res))))

QiでL-99 (P09 連続して現われる要素を纏める)

| 16:47 | QiでL-99 (P09 連続して現われる要素を纏める) - わだばLisperになる を含むブックマーク はてなブックマーク - QiでL-99 (P09 連続して現われる要素を纏める) - わだばLisperになる

ちょっと複雑になると途端にどうしたら良いか分からなくなってしまいます。

そろそろチュートリアルをきちんと読まねば…。

(pack [a a a a b c c a a d e e e e])
\=> [[a a a a] [b] [c c] [a a] [d]]
\

(define pack
    [ ] -> [ ]
    X -> (pack* X [ ] [ ]))

(define pack*
    [ ] Acc Res -> (reverse (cons Acc Res))
    [H | T] Acc Res -> (pack* T (cons H Acc) Res) where (or (empty? Acc) (= H (head Acc)))
    Lst Acc Res -> (pack* Lst [ ] (cons Acc Res)))

ArcでL-99 (P33 互いに素であるかを判定する)

| 16:18 | ArcでL-99 (P33 互いに素であるかを判定する) - わだばLisperになる を含むブックマーク はてなブックマーク - ArcでL-99 (P33 互いに素であるかを判定する) - わだばLisperになる

今回のお題は、互いに素であるかを判定せよとのこと。自分は数学には滅法疎いので、Wikipediaの説明を元にgcdの結果を1と比較しているだけです。

前回のgcdも良く考えれば、modを使えば簡単に書けるので書き直しました。

(def coprime (x y)
  (is 1 (gcd x y)))

(def gcd (n m)
  (if (is 0 m)
      n
      (gcd m (mod n m))))

繰り返し構文からみる自分のコーディングスタイル (2)

| 17:22 | 繰り返し構文からみる自分のコーディングスタイル (2) - わだばLisperになる を含むブックマーク はてなブックマーク - 繰り返し構文からみる自分のコーディングスタイル (2) - わだばLisperになる

前回反響が少しでもあるとは全く考えていなかったのでデータについては適当にしていましたが、☆が2個付いたし折角なので、文字のデータですが公開してみることにしました! 見難いですが、とりあえず色々あります。これらから一体何が読み解けるのかは、全くの謎です!

見慣れない構文名があるので、変なものをざっと解説すると、DO-FOREVERはその名のとおり無限ループ用です。個人的には是非復活して欲しいですね(笑) Lispマシンでは人気がありましたが、Common Lisp以降どっかにいなくなりました。DO-NAMED系は、DOのブロックに名前が付いていて脱出時に指定します。これもCLで、BLOCKとして統一されたので姿を消してしまいました。

全然関係ないですが、ループ系の構文の名前を考える、ということでは、RRRSのメーリングリストで名前付きLETに適切な名前を付けよう!、というのが熱くて面白いです。もの凄く沢山の案が提案されているのですが、結局採用されずに今に至るという流れが特に好きです(笑)

現在の主なフリーの処理系

  • SBCL
構文名 総数 総行数行数/構文最大行数
DOLIST 1073 9956 9 152
DO 702 7463 10 170
MAPCAR 547 2082 3 45
LOOP 514 3574 6 57
DOTIMES 359 2161 6 88
LABELS 156 5339 34 306
DO* 65 821 12 81
MAP 53 340 6 103
MAPC 47 152 3 14
MAPCAN 23 229 9 64
PROG 7 568 81 366
MAPLIST 1 7 7 7
  • CLISP
構文名 総数 総行数行数/構文最大行数
DOLIST 382 4016 10 332
MAPCAR 304 1345 4 176
DO 282 4110 14 117
DOTIMES 144 729 5 62
LOOP 102 993 9 206
DO* 94 1871 19 250
MAP 70 184 2 12
MAPCAN 60 333 5 26
LABELS 52 4073 78 1233
MAPC 35 155 4 36
PROG 12 256 21 131
MAPL 8 45 5 35
MAPLIST 4 31 7 26
MAPCON 2 2 1 1
  • CMUCL
構文名 総数 総行数行数/構文最大行数
DOLIST 1570 12602 8 90
DO 1243 13010 10 179
DOTIMES 710 4565 6 91
MAPCAR 612 2361 3 47
PROG 424 7489 17 377
LOOP 405 2554 6 56
DO* 175 3335 19 132
LABELS 161 5755 35 230
MAPC 104 191 1 14
MAP 58 148 2 12
MAPCAN 18 88 4 11

古い処理系

  • Franz Lisp 1985頃?
構文名 総数 総行数行数/構文最大行数
DO 371 4462 12 195
PROG 205 5377 26 575
MAPCAR 69 213 3 16
MAPC 53 303 5 41
DOLIST 41 280 6 32
LOOP 24 104 4 11
MAPCAN 10 61 6 17
MAPLIST 3 33 11 11
DOTIMES 2 2 1 1
MAP 1 6 6 6
MAPCON 1 5 5 5
  • Rutgers PDP-10 CL 1985年頃
構文名 総数 総行数行数/構文最大行数
DO 368 3451 9 78
DOLIST 157 964 6 68
DOTIMES 78 361 4 28
DO* 74 874 11 61
MAPCAR 62 176 2 13
PROG 31 687 22 62
LABELS 11 244 22 59
MAPC 6 19 3 6
MAPCAN 6 37 6 8
LOOP 2 4 2 3
MAPL 1 4 4 4
構文名 総数 総行数行数/構文最大行数
DO 902 9181 10 251
PROG 359 14913 41 603
MAPC 275 1597 5 52
MAPCAR 184 628 3 29
MAPCAN 51 322 6 52
LOOP 30 166 5 28
DOTIMES 16 238 14 46
MAP(MAPL) 15 118 7 25
DOLIST 13 35 2 7
MAPLIST 6 19 3 6
MAPCON 3 5 1 2
DO* 1 1 1 1

Lispマシン系

  • LMI K-Machine 1986年頃
構文名 総数 総行数行数/構文最大行数
DO 614 5653 9 146
DOTIMES 392 2658 6 121
DOLIST 355 2441 6 62
MAPCAR 235 626 2 13
LABELS 137 1754 12 98
LOOP 92 303 3 16
MAPC 89 257 2 15
DO-FOREVER 46 548 11 58
DO* 42 571 13 56
MAP 26 43 1 6
PROG 16 333 20 58
MAPCAN 10 68 6 9
DO*-NAMED 6 48 8 9
MAPL 5 7 1 3
MAPCON 2 16 8 8
MAPLIST 1 5 5 5
DO-NAMED 0 0 0 0
  • LMI Lambda 1982年頃
構文名 総数 総行数行数/構文最大行数
DO 4018 46904 11 156
DOLIST 2049 12879 6 142
LOOP 1308 11002 8 119
DOTIMES 1127 5761 5 151
MAPCAR 662 1882 2 92
PROG 607 17999 29 404
DO-FOREVER 257 3782 14 183
MAPC 250 2581 10 1719
DO* 97 1716 17 114
MAP 84 255 3 44
MAPCAN 68 325 4 20
DO-NAMED 36 933 25 97
DO*-NAMED 6 27 4 9
MAPL 2 2 1 1
MAPCON 2 4 2 2
MAPLIST 0 0 0 0
  • MIT CADR 1979年頃
構文名 総数 総行数行数/構文最大行数
DO 2321 27545 11 142
DOLIST 806 4632 5 72
PROG 665 15177 22 253
LOOP 457 3360 7 54
DOTIMES 316 1775 5 142
MAPCAR 155 390 2 12
MAPC 114 306 2 17
DO-NAMED 46 1094 23 74
MAPCAN 16 56 3 9
MAP 12 17 1 5
MAPCON 2 4 2 2
  • Gigamos 1987年頃
構文名 総数 総行数行数/構文最大行数
DO 622 7827 12 140
DOLIST 362 2358 6 50
LOOP 233 1808 7 119
DOTIMES 191 1112 5 121
MAPCAR 151 380 2 48
LABELS 65 1949 29 199
PROG 64 2297 35 167
MAPC 56 126 2 25
DO* 21 267 12 32
DO-FOREVER 16 196 12 34
MAPCAN 9 49 5 8
DO-NAMED 7 283 40 90
MAP 4 4 1 1

コードの量が少ないので参考データとして

  • Peter Norvig (LTD) 1995年頃
構文名 総数 総行数行数/構文最大行数
LOOP 32 133 4 17
MAPCAR 29 64 2 7
MAP 8 17 2 6
DOLIST 7 42 6 13
LABELS 4 47 11 32
DO 3 3 1 1
MAPC 3 7 2 3
MAPCAN 3 9 3 7
MAPLIST 1 1 1 1
MAPCON 1 1 1 1
DOTIMES 1 9 9 9

繰り返し構文からみる自分のコーディングスタイル

| 01:50 | 繰り返し構文からみる自分のコーディングスタイル - わだばLisperになる を含むブックマーク はてなブックマーク - 繰り返し構文からみる自分のコーディングスタイル - わだばLisperになる

Common Lispせよ、Schemeにせよ繰り返しの構文は豊富に用意されているかと思うのですが、どんな構文を自分は好んで使っているのか、ふと、知りたくなりました。 ということで、DOやMAP、PROG等のめぼしい構文を抜き出して各々の構文の数を勘定するコードをCLで書いてチェック。自分が書いたメモ書きからスクラッチのごみのようなものまで含めて約4万行を対象にしてみました。グラフはGoogleDocsにお任せしました。ほんとはCLで完結させたかったんですが…。 主観的には自分は繰り返しにはDO構文を良く使っていて、LOOPはあまり使ったことがない、と思っているのですが、意外なことにMAPCARを一番多く使っていて、大体同じ位DOを使用。そして使ってない筈のLOOPも普通に使ってました(笑) 最近、LOOPで書く練習をしていて、できるだけLOOPで書くようにしているからかも知れません。PROGが多いのはレトロコンピューティングな趣味が反映されたものだと思われます。 ついでに、SBCL 1.0.15のソースコードも調べてみました。 DOLIST、DO、MAPCARで7割弱。何でもかんでもLOOPだろうと勝手に思っていたので意外でした。 ■ それで調子に乗って古い処理系から最近のCLの処理系まで色々調べてみたのですが、最近の傾向としては、ちょとした違いはありますが、DOLIST、DO、MAPCARの順で6割強を占めるようです。この35年位を通じDOは首位で安定している様子で、LOOPは大体4番手か5番手位。CMUCLでは、LOOPよりPROGが多かったりして何となく処理系の歴史を感じさせます。 また、調べてみてMacLISPのような古い処理系では、DOLISTの代わりにMAPCが好んで使われていたことが分かりました。MAPCは、Schemeで言えば、for-eachで、副作用主目的としたmapです。機能としては、あまりDOLISTと変わらないのですが、Lispマシン時代からDOLISTに取って代わられ始め、現在では殆んど使われなくなってしまいました。 また、LOOPはLispマシンから出て来ただけに、Lispマシンでは今より好んで使われていた様子で、今のCommon Lispの処理系より全体に占める割合は多いようです。これも意外でした。 ちなみに、再帰は、統計を取るのが面倒なので、LABELS位にしています。処理系のソースという性質もあるとは思いますが、眺める限りはLispマシン以前では殆ど使われずCommon Lisp以降から少しずつ増え始めている感じです。 以上、非常に下らないですが、統計を取ると存外色んなことが分かって来たりするもんだと思いました。 …分かってくると言っても、全く本質的でない事項だとは思いますが(笑)

ゲスト



トラックバック - http://cadr.g.hatena.ne.jp/g000001/20080311