Skip to content

Instantly share code, notes, and snippets.

@y2q-actionman
Last active October 8, 2021 02:56
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save y2q-actionman/357586f5ea37782425346f3e6588e054 to your computer and use it in GitHub Desktop.
Save y2q-actionman/357586f5ea37782425346f3e6588e054 to your computer and use it in GitHub Desktop.
Re: (ご意見募集)Common LispのASDF3のここが気に入らない・難しい に向けて

原典 : https://blog.3qe.us/entry/2019/04/15/194201

ASDF難しい

わかる。正直いって全然わからん。

どうでもいい実験を書くときや、手元で動けばいいスクリプトを書くときには、そもそも defsystem を書いたりしない。 「CL:LOAD で順に読む」というだけで十分なので。 (まあそもそも、 asdf がやってることも「いい感じに compile / load する」のだと考えられるが。)

その段階を超え、「あーなんかソース管理するか・・」と思うと defsystem を書き始める。 この時につくる asdf はもはやテンプレを使い回している。

一方、 Allegro Common Lisp を使うときは Allegro 付属の excl:defsystem を使ってたりする。 こっちの方が文法も概念も簡単なのだが、 Allegro 以外で使えないのが悲しい。 https://franz.com/support/documentation/current/doc/defsystem.htm

modules難しい

実はあまり気になったことがない。一つの system に module が複数入るような構成になる前に system 切ってる気がする。 (・・というより、 module ってよくわからないので使わないようにしてるのかもしれない。)

package-inferred-system 難しい

僕も難しすぎると思う。

  • package 名, ファイル名, ファイル配置、 package 配置を一致させなければいけない。ずれたらエラー。検証する方法は load してみるしかない。
  • 一体何がどうやって load されるのかを知るには、全ての lisp ファイルを見る必要がある。

まだ asd にファイルを並べて書いてたほうがマシだと思ってる。

今時のLL言語みたいに,packageとpathが合致している挙動がやりたいだけなのに・・・

ファイルを書くのがめんどくさいというのはある。これもわかる。 しかし、 package と path が同じようにあるというのは前提におけない。

Lisp の場合は、コンパイル済みの fasl を作り置きし、それを頒布し、 load することができる。 この場合、 path なんてものは失われている。 *compile-file-pathname**load-pathname* も一般的に違う。

(個人的に package-inferred-system に思う不思議な点はこのあたりで、  Load したら消え失せる pathname の情報を、 Load した後も残るパッケージ名に埋め込まないといけない点に違和感がある。)

package と path が独立してるのは、個人的には柔軟性の発露だと思っているけど、まああんまり fasl 運ぶこともしないので面倒が多い説もある。 一方でそれを規約で繋いだ package-inferred-system では、全貌が全くつかめない。 (package-inferred-system のソースってどこから読むのか分からない。ただ load できるだけ、という印象。)

どうなんでしょうね、という。

slime-package-fu では、 slime-export-symbol-at-point すると、 export されると同時に対応するファイルの defpackage も更新されるわけだけど、 それみたいなのが asdf に出来たら嬉しいんじゃないかなあ。。と昔思った気もする。

ふだんはperlやってるので,今時ビルド順序を指定とかしたくない

Lisp の場合はマクロのせいでそうもいかない、らしい。

以下では、マクロ展開を *macroexpand-hook* で頑張って追跡しているらしいが、 readtable が書き換えられるとか困り事例がとっても多いらしい。 https://github.com/fare/asdf-dependency-grovel

一方で、他の言語みたいに import とか書きまくることをあてにするのなら、いっそそういうビルドシステム立ち上げちゃってもいいんじゃないの? という気もしてきた。

ビルド順序手で指定したほうがいいほどの難しいことしない

相互依存しないもの同士ならやりたい放題ともいえる。 完全にローカルで、相互依存しないファイルなら・・ デカpackageを定義した後で (mapc #'load (directory "*.lisp")) なんてやって他のはざっくり読んじゃえばいいじゃん説まである。

wild-package-inferred-system とかあるけどどうなんだろ。 https://github.com/privet-kitty/wild-package-inferred-system

処理系でなんか動作がぶれる

そうかな。。今の所、 Allegro と SBCL で動作がぶれて困ったことはない気がする。 ただ、以下のことには気をつかっている。

  • asdf を使う場合、 *compile-file-pathname**load-pathname* 相対でファイルにアクセスしないようにする。

    asdf が ~/.cache/ などのディレクトリでファイルをコンパイルするので、上記 の path も当然 cache のディレクトリになり、 結果そこから相対的に探しても該当ファイルは見つからない。 asdf:defsystem 相対で読まないといけない。

  • namestring のパースに依存すると大抵パスがずれるので、 #.(make-pathname :directory '(:relative "test")) とか明示的に書く。

    例えばSBCLは (merge-pathnames #p"hoge.txt" #p"/var/tmp")#P"/var/hoge.txt" を返す。 後者が '/var' ディレクトリの 'tmp' という名前のファイルだ、と解釈されるからで、まあ 事前知識がなくて、 さらに realpath を取らないなら仕方ないのだが、それでもハマる挙動ではある。。 #p"/var/tmp/" とやると tmp がディレクトリと見なされるのでいいのだが、こんな tweak に依存してられないので、 最近は make-pathname を直書きしている。

( Common Lisp の意図に従うなら、 logical-pathname を使うべきなのかもしれないけど・・)

動作がぶれるというなら、 asdf のバージョンの問題の様な気もする。

マニュアルが難しい

わかる。何度か目を通したけど、例えば後半の "Controlling where ASDF searches for systems" は読んだことがない。 標準の場所で困ったことが今の所ないので・・

defsystem の文法は、まあ「そう書くのか」くらいだけど、 asdf のオブジェクトシステムはよく分からない。 asdf:test-system を使う部分だけは勉強したけど、後は・・いつ読むのか・・ (ビルド時に asdf でフックしてやりたいことが今の所あまりない、というのもある)

みなさんはASDFとどうやってうまく付き合っていますか??

うまく?は付き合っていない。 「順にファイルを読んでくれる奴」以上のものを期待していない。

でも excl:defsystem や mk-defsystem や quickbuild を差し置いてデファクトスタンダードなので勉強しています, という程

@y2q-actionman
Copy link
Author

y2q-actionman commented Apr 23, 2019

そのうち書く: asd-generator を使うといい感じになる説
quicklisp + asdf-install (local-projects に入れる) は今でも意味がある気がする

require 依存とか

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment