* [2022-09-30 金]
** fusion! :lisp:
昔ドラゴンボールというアニメをよく見ていた。
その中に合体するフュージョン!っていう技がある。
ちなみにこのfusionという単語、
調べると融合との事。
昨日だけど、自分が作った関数の名前にしてみた。
#+BEGIN_SRC lisp
(defmacro fusion (&rest lsts)
`(mapcar #'(lambda (x) (if (> (length x) 1)
x
(car x)))
(mapcar #'remove-duplicates (mapcar #'list ,@lsts)))) #+END_SRC
正直いって、mapcarを3つも使っていてめちゃくちゃダサい。
で、on lispにたしか高階関数をまとめられるツール
あったなぁと思ってそれ使って作ってみたのがこれ。
#+BEGIN_SRC lisp
(defun fusion2 (lst1 lst2)
(mapcar (compose #'(lambda (x) (if (> (length x) 1) x (car x)))
#'remove-duplicates #'list) lst1 lst2))
#+END_SRC
見た目はすっきり書けたけど、時間計測したら、
mapcar3つのダサいバージョンに負けてた笑
これは自分でも意外だった。
しかも、最初はlistを2つだけしか引数に取れない仕様にしてて、
2つ以上リストを持てるmapcarの機能を十分に活かし切れてないと
思ったので、引数の設定のところも変えてある。
まぁ、ここまで書いたらこれ一体何の話?
何に使うの?おいしいの?これ?
と思うので、説明を入れると
上にも書いた通り合体するのだ!。。。
何と何が合体するのかというとS式とS式。
そんなもん、appendってもんがあるじゃないか!
と思うかもしれないけど、
まぁまぁ、そうカッカせず、ちょっと具体例をば。
以前S式日記システムを作っていたのだが、
例えば
#+BEGIN_SRC lisp
(:date [2022-09-30] :contents "hoge")
(:date [2022-09-30] :contents "fuga")
#+END_SRC
こういったようなS式のデータがデータベースに蓄積されていく。
で、上記のように同じ日付の日記を作成したとして、
appendしたとしたら
#+BEGIN_SRC lisp
(setq a '(:date [2022-09-30] :contents "hoge")
b '(:date [2022-09-30] :contents "fuga"))
(append a b)
#+END_SRC
まぁ、当たり前って言えば当たり前の結果ですね。
S式の中身が重複データでいっぱい。
この中で残したいのは"hoge"と"fuga"というテキストだけ。
あとは重複しているからダブらないようにしたい。
そんな都合のいいように合体させるのがfusion
#+BEGIN_SRC lisp
(setf a '(:date [2022-09-29] :contents "hoge")
b '(:date [2022-09-29] :contents "fuga")
c '(:date [2022-09-29] :contents "pogya")
d '(:date [2022-09-29] :contents ("foo" "bar")))
(fusion a b c d)
#+END_SRC
見てもわかるように複数contentsをまとめるために
括弧を使っているので、fusionしたものをまたfusion
ってやり方をするとどんどん("foo" "bar")みたいに
中に括弧だらけになる。
そうなった時はflattenみたいな関数を使えばいいかと。
それか翌日になってからfusion一回だけするみたいな
使い方がいいのではないかと思ってる。
まぁ、これは日記システムという具体例を上げながら
説明したけど、アイディア次第でいろんなS式データベース等を
圧縮するのに使えるのではないかと思っている。
ポモドーロ関係のツールも作ろうかなと考えいるけど、
多分そこにも使えるかなと。
ちなみに昨日のlisp meetupのLTネタとして
考えてて間に合わなかったというのはこれじゃないです。
まだ出来てません笑 org-modeに使おうかなと思ってるツール
なんで、それは後日また。