ほんとのこと知りたいだけなのに。

夏休みはもうおわり。

Emacs Lisp のリスト操作オペレータの一覧

Common lisp をやっていると Emacs Lisp が結構つらい。

なぜならオペレータが微妙に一緒で微妙に違うからだ。
これがなかなか覚えられなくて毎度こまる。

本日はリスト操作にストレスを感じたので一覧にしてみた。 一覧は 5. リスト から抜粋した。

リスト操作オペレータの一覧

5.3 リスト向け述語

type operator
Function consp object
Function atom object
Function listp object
Function nlistp object
Function null object

5.4 リストの要素の参照

type operator
Function car cons-cell
Function cdr cons-cell
Function car-safe object
Function cdr-safe object
Function nth n list
Function nthcdr n list
Function safe-length list
Function caar cons-cell
Function cadr cons-cell
Function cdar cons-cell
Function cddr cons-cell

5.5 コンスセルとリストの構築

type operator
Function cons object1 object2
Function list &rest objects
Function make-list length object
Function append &rest sequences
Function reverse list

5.6 既存のリスト構造の修正

5.6.1 setcarによるリスト要素の変更

type operator
Function setcar cons object
Function setcdr cons object

5.6.3 リストの順序を変更する関数

type operator
Function nconc &rest lists
Function nreverse list
Function sort list predicate

5.7 集合としてのリストの利用

type operator
Function memq object list
Function delq object list
Function member object list
Function delete object list

5.8 連想リスト

type operator
Function assoc key alist
Function rassoc value alist
Function assq key alist
Function rassq value alist
Function assoc-default key alist test default
Function copy-alist alist

おわり

Common Lisp のオペレータが使えるようになるライブラリもあるけどバージョンアップや我田引水的なものに付き合うのは莫迦らしいので使わない。

Emacs Lisp が使えるようになれば良いのだと思う。

が、道は長いね。。。

続:Windows で trival-ssh が出来ない件

前回UIOP のところで止っていたのでその続き。

ASDF をローカルに持ってきて quicklisp でロード対象にする。

ASDF こっから clone する。

(ql:uninstall 'asdf)ASDF 自体をアンインストールする。

asdf.asd のショーットカットを作成して自分の好きなところに配置して (ql:quickload :asdf) を実行してインストール(っていうの?)する。

場所を確認して成功を確認。

CL-USER> (ql:where-is-system :asdf)
#P"C:/Users/yanqi/prj/asdf/"

バージョンは 3.2.1 でした。

CL-USER> (asdf:asdf-version)
"3.2.1"

UIOPのバージョン(かな?)も同じ模様。

CL-USER> uiop:*uiop-version*
"3.2.1"

run-program を眺めてみる。

(defun run-program (command &rest keys
                    &key ignore-error-status (force-shell nil force-shell-suppliedp)
                      input (if-input-does-not-exist :error)
                      output (if-output-exists :supersede)
                      error-output (if-error-output-exists :supersede)
                      (element-type #-clozure *default-stream-element-type* #+clozure 'character)
                      (external-format *utf-8-external-format*)
                    &allow-other-keys)
  (declare (ignorable input output error-output if-input-does-not-exist if-output-exists
                      if-error-output-exists element-type external-format ignore-error-status))
  (apply (if (or force-shell
                 (and (stringp command)
                      (or (not force-shell-suppliedp))))
             '%use-system '%use-launch-program)
         command keys))

UIOP/RUN-PROGRAM::%USE-LAUNCH-PROGRAM をコールしている模様。

%USE-LAUNCH-PROGRAM を眺めてみる。

うーん長いね。。。。

(defun %use-launch-program (command &rest keys
                            &key input output error-output ignore-error-status &allow-other-keys)
  (when (member :stream (list input output error-output))
    (parameter-error "~S: ~S is not allowed as synchronous I/O redirection argument"
                     'run-program :stream))
  (let* ((active-input-p (%active-io-specifier-p input))
         (active-output-p (%active-io-specifier-p output))
         (active-error-output-p (%active-io-specifier-p error-output))
         (activity
           (cond
             (active-output-p :output)
             (active-input-p :input)
             (active-error-output-p :error-output)
             (t nil)))
         output-result error-output-result exit-code process-info)
    (with-program-output ((reduced-output output-activity)
                          output :keys keys :setf output-result
                                 :stream-easy-p t :active (eq activity :output))
      (with-program-error-output ((reduced-error-output error-output-activity)
                                  error-output :keys keys :setf error-output-result
                                               :stream-easy-p t :active (eq activity :error-output))
        (with-program-input ((reduced-input input-activity)
                             input :keys keys
                                   :stream-easy-p t :active (eq activity :input))
          (setf process-info
                (apply 'launch-program command
                       :input reduced-input :output reduced-output
                       :error-output (if (eq error-output :output) :output reduced-error-output)
                       keys))
          (labels ((get-stream (stream-name &optional fallbackp)
                     (or (slot-value process-info stream-name)
                         (when fallbackp
                           (slot-value process-info 'bidir-stream))))
                   (run-activity (activity stream-name &optional fallbackp)
                     (if-let (stream (get-stream stream-name fallbackp))
                       (funcall activity stream)
                       (error 'subprocess-error
                              :code `(:missing ,stream-name)
                              :command command :process process-info))))
            (unwind-protect
                 (ecase activity
                   ((nil))
                   (:input (run-activity input-activity 'input-stream t))
                   (:output (run-activity output-activity 'output-stream t))
                   (:error-output (run-activity error-output-activity 'error-output-stream)))
              (close-streams process-info)
              (setf exit-code (wait-process process-info)))))))
    (%check-result exit-code
                   :command command :process process-info
                   :ignore-error-status ignore-error-status)
    (values output-result error-output-result exit-code)))

一旦動かしてみる。

読むのが面倒なので一度 (ql:quickload :trivial-ssh) してみる。。。。。っと通りました。。。。

CL-USER> (ql:quickload :trivial-ssh)
To load "trivial-ssh":
  Load 1 ASDF system:
    trivial-ssh
; Loading "trivial-ssh"

(:TRIVIAL-SSH)

おしまい。

なんかバージョンが古いだけ問題っぽいですね。

とりあえずイケたので、これはこれで良しとします。

次回でバージョンを確認しようかな。