2018年12月31日月曜日

2018年決算

 本:41冊
映画:29本
WIND:6日/57.9km
TVアニメ/TVドラマ:526話(36本)/141話(10本)

2018年12月29日土曜日

アーロンチェア

 アーロンチェアが到着したのは2018年9月1日のことだった。
 以前から欲しいとは思っていたのだけれど、ほとんど使わないだろうし——パソコンを使うときはマクドナルドとか、スタバとか、ファミレスとかに出かけていたので——、値段を考えると、買うこともないだろう、と。
 それがどういうわけか、衝動的に購入してしまった。
 到着したアーロンチェアが玄関を通らなかったりしてけっこう、往生してしまったが1

 それ以来、外へでかけることがめっきり減ってしまった。
 元々、土日は部屋にこもっていることが多いのだけれど、ちょっと出かけるということもしなくなってしまった。何をやっているのか、というと。
 アーロンチェアに座っているのである。
 ぼーぜんとしているのである。
 ぼんやりしているのである。
 パソコンを使うとき、外へ出かけていたのは今まで使っていた椅子がよくなかったからだったらしい。それもあってモニタを新調する気にもなったのだけれど。

Footnotes:

1

最終的には外で梱包を解いて椅子単体を部屋に入れた。

2018年12月27日木曜日

Beelink S1メインマシン化計画:頓挫

 直接、MacBook Airのアプリを使うことはあきらめて。
 Ubuntuから使う方針でUbuntuの環境をいじりはじめる。
 GnuCashはOK。MacBook Airのデータを読みこんで更新できた。
 Emacsのフォントが汚なかったので新しいフォントをインストールした。Emacsの環境に頭を悩ませているうちに疲れてきて布団に入る。
 とたん思いつく。——そもそも。
 どうしてUbuntuをメインマシンにしようとしているんだっけ?
 普通に使えるから。
 だから使おうとしたわけなんだけど1、よくよく考えたらMacBook AirをDELLモニタに繋げば、いいわけで。どうしてそうしないんだったんだっけ?

 しばし沈思黙考。

 ああ、そうか。
 MacBook Airはモニタがフラットになるまで開かない。
 だからDELLのモニタと画面がかぶるので、それが嫌だったのだ。それに目一杯開いたMacBook Airのモニタが電灯の光を反射してしまうから。しかし、それならMacBook Airにキーボートとトラックパッド2をつなげてしまう、という手もあるじゃないか3
 つまりMacBook AirをiMac miniのように使うのだ。
 で、試しにbluetoothのMac用のキーボードとトラックパッドを借りてきた。
 でも使ってみるといまいち。
 あれ。どうしてだろう? DELLモニタに違和感があるのはまだ、馴れてないからだろうけど、キーボードが妙に使いづらい4……Apple純正なんだが。
 それならbluetoothのHHKを購入するか……。
 MacBook Airのキーボードは馴れていることもあってだいじょうぶなのだから、直接、DELLのモニタにつなぐのがやはりいいようだ。トラックパッドもそのまま使えるし。
 ところでMacは外付けモニタをメインモニタにできるんだろうか。
 Windowsならできる。
 ミラー、拡張、外付けのみと選べる。
 MacBook Airには外付けのみ、の選択肢がなかった。
 あれ、もしかしたら外付けをメインにできないの? でも拡張にしてメインモニタにすることはできるんだよな。モニタに火は点ったままだけど。Windowsだと外付けメインを選択して消すことができる。
 たしかにモニタの輝度を最低にすれば、いいだけなんだけど。どうせMacBook Airのモニタは電灯の写り込み防止でハンカチをかぶせてしまうけど。ただ、拡張モードだと立ち上げたウィンドウやカーソルがそっちにいったときにいちいちこまってしまう——そっか、ミラーモードにすれば、いいんだ。それで普通に使えた。
 でもWindowsだとそうしないな、どうしてだろう。そういえば、たしかWindowsだとミラーモードにすると、画面密度が小さい方に合わせられて外付けを大画面にしても無駄だったはず。だから外付けメインにするしかなかった。
 ところがMacBook Airはそうじゃないぞ。
 外付けの方のサイズに合わせられているみたいだ5。ああ、それで外付けメインという選択肢がなくても問題ないんだ、Macは。

 ということは。
 結局、メインマシンは今までどおり、MacBook Airということじゃないか。
 買ったマウスはどうすれば、いいんだ6

Footnotes:

1

個人的にはWindowsより使えると思えるから。

2

ジェスチャーがあるのでマウスという選択肢はないのだった。

3

実際にはキーボードとマウスをつないで、クラムシェルモードとしてMacBook Airを閉じても使える。使ってみてちょっと感動した。Mac、すげえ。

4

どうやら大きさが微妙に馴れているMacBook Airのキーボードよりも小さかったようだ。打鍵感もなじめなかった。

5

その分、MacBook Airの画面が小さくなっている。

6

ちなみにインターネットラジオはVLSを使えば、MacBook Airから視聴できることがわかった。しかも今まで使っていなかったMacBook Airのスピーカが使える、というおまけつき。

2018年12月25日火曜日

Beelink S1メインマシン化計画:試行錯誤

 ただUbuntuをメインにすると、MacBook Airとのデータのやりとりが厄介だ。
 やりとりすること自体はだいじょうぶなのだけれど1、問題はデータが二重管理になることだ。よくある問題で、昔からこの手のことには頭を悩ませてきた。
 ここはやはり、DELLのデスクトップマシンとThinkPadを使っていたころの解決策を使うべきだろう。デスクトップで使うときはノート側を外部ディスクにしてしまうのである。さいわいsshでUbuntuからMacBook Airをmountできる2
 画面共有という手もあるけれど、これは体感速度的に許容できなかった。

 あとは、UbuntuのEmacsからどうやってMacBook Airのファイルを使うか3

 待てよ。

ssh -Y ホスト名 emacs

 で、いけるんじゃね?
 これでMacBook AirのEmacsをUbuntuに表示できるんじゃね? そうしたら万事解決じゃね? GnuCashだって表示できるかもしれない。
 そうした。
 そうしてみた。
 MacBook AirのEmacsは起動できた。
 ところがUbuntuに表示されない。MacBook AirのXサーバに表示されてしまう。いろいろやってみた結果、どうやらCocoaが原因らしい4——と判断。
 というのも起動すると一瞬、Macに表示されるのだ。
 そのあと、Xサーバに表示されなおす。
 ということはCocoaではなく、X11をバインドしたEmacsならうまくいくんじゃないだろうか。それだとMacBook Airで使うときにこまる予感がするけど5

 うーむ、だめか。

Footnotes:

1

ssh、NFS——基本、なんでもありだ。

2

Emacsならssh経由でリモートのファイルをローカルと同じようにあつかえる。

3

pathがちがうのでbookmark機能とか、orgのagendaとか、ちょっと面倒。

4

MacBook AirのEmacsはCocoaを使用している。

5

ほとんどEmacsの世界にひきこもっているので問題ないかもしれない。

2018年12月23日日曜日

Beelink S1メインマシン化計画:端緒

 なんだかんだ使い道がねぇなぁ、と思っていたBeelink S1——Ubuntuだったけど、気に入ったアプリがひとつだけあった。——「Rhythmbox」。いわゆるインターネットラジオなんだろうけど、中にバンドルされているambientのラジオ1が気に入った。
 それを聞きながらつらつらと、Ubuntuのショートカットキーの定義とかをながめていたらけっこう、マウスなしでいろいろと操作できるようになっていることに気づいた。
 とくに、ウィンドウをディスプレイの右とか、左に半分だけ置く機能。
 Windowsでディスプレイの端にぶつけるようにウィンドウを移動すると、なるやつだ。同じことができる上、キーボードで操作。これはいい——というか、MacとWindowsをくらべたとき、この操作だけはWindowsの勝ちと思っている。
 Macでもディスプレイの左右に別々のウィンドウを並べることはできるけれど、操作がやや煩雑なのだ。左右の割合を調整するのはMacの方が簡単だけど。
 そもそもUbuntuはけっこう使える。
 いや、というよりも普通に使えるのだ。
 必要なソフトは基本的にあるし、日本語のフォントもWindowsより全然、きれいだし2。HFS+のディスクもmountできるし。
 なんだ。いいことずくめじゃないか。
 これはDELLのモニタにつないでUbuntu——Beelink S1をメインマシンにするべきじゃないだろうか。

 そう思ってAmazonでマウスを買った。

Footnotes:

1

Ubuntuが提供している?

2

VirtualBoxのフォントの汚なさにWindows版は使う気が失せた。

2018年12月21日金曜日

えっ、うそ。VirtualBoxでMacOSが動くの。

 ひさしぶりにFreeBSDをいじってみようか、とtrueOS1をあまったハードディスクにいれた。VirtualBoxでインストーラーを動かしてお立ち台に接続したハードディスクへインストールするいつものやり方だ。
 もしかしたらこれでBeelink S1で動くかも、というわけだ。以前はうまく動かせなかったけれど。
 その過程でふと気づく。
 新規につくる仮想マシンのOSのタイプにMacOSという選択肢が増えている。えっ、うそ。
 あわててググってみたらなんと、WindowsのVirtualBoxでMacOSを動かした、というページにぶつかった。たしかに、ずいぶん前にMacOSは無料になっているけれど……待てよ。それならBeelink S1でMacOSが動かせるかもしれない。
 と思ったのだけど、よくよく考えると、Beelink S1でVirtualBoxのゲストOSにまわせるメモリは2Gしかない。さすがに無理か……。

 ちなみにBeelink S1へもっていったtrueOSは起動した。しかし起動はしたのだけれど、trueOSのロゴがでたところで固まってしまう。いつまでもそのままだった。あかん。だめだ。
 ちなみにMacBook Airでは動いたんだけどなぁ。

Footnotes:

1

FreeBSDから派生したPC-BSDの後継

2018年12月19日水曜日

from HFS+ to APFS

 「macOS Mojave」へアップデートしたとき、APFSはLinuxで使えると知って1、外部ディスクとして使っている3TBをAPFSにしたいな、と思っていた2。それでうだうだ、考えた。余っているハードディスクにcopyして——でも3TBも入らないよな——別々にばらさなきゃ、いかんし——どうしよう。
 で、ふと気づいた。
 OSのアップデートのとき、HFS+から変換してくれたんだから直接、変換できるんじゃね?
 ググったらでてきた。
 なるほど、ディスクユーティリティを使えば、いいのか。
 ところが。
 ところがである。
 3TBではAPFS変換が選べない。

 なんでよ、なんで。ググっても対応方法は見つからず。
 調べてみるうちにLinuxからHFS+をmountできることを知る(そもそもAPFSへ変換する意味がなくなった)。FreeBSDからはうまくいかなかった記憶があるのでだめだ、と思いこんでいた。
 それならAPFSにしなくていいか。
 そうなったら手を思いつくもので。
 commandレベルからならできるんじゃね? APFS変換。
 「man diskutil」を見てみると、できるっぽい。しかもdryrunが可能。
 試してみる。

bash-3.2$ diskutil APFS convert /dev/disk4s2 -dryrun
Rehearsing the conversion of the volume on disk4s2 to an APFS Volume on an APFS Container
Started APFS operation on disk4s2 3TB
Dry run of HFS Volume conversion to an APFS Container with a single APFS Volume
The target is the Journaled HFS+ volume "3TB" backed by the GPT partition disk4s2
The target is a data disk; it is not a macOS system disk
Found APFS EFI driver /usr/standalone/i386/apfs.efi to install into the APFS Container
The target is not encrypted
Unmounting disk4s2
Starting dry run test of conversion from HFS to APFS
Performing apfs_hfs_convert --dry-run --watchdog=1800 -x --verbose=0x400 /dev/disk4s2
Reporting pre-conversion statistics
Reporting post-conversion statistics
Successfully finished dry run of conversion from HFS to APFS
Dry run mode so will not touch type
Not mounting APFS Volume
Exiting conversion operations with error code 0
Finished APFS operation on disk4s2 3TB
bash-3.2$

 おっ、できそうだ。

Footnotes:

1

wikiにも書かれていた。

2

何か、あったとき、Beelink S1のUbuntu経由でレスキューできる。

2018年12月17日月曜日

Dell 27 Monitor(2)

 Apple TVをDellのモニタにつないで音声を別にだすには次の二つの手が考えられる。

  1. Apple TVのoptical audioを利用して出力する。
  2. HDMIの音声分離機を使用する。

 どちらにしても追加投資が必要だ。
 いろいろ調べていたら面倒臭くなってしまった。
 そもそもネット配信されているものが観れれば、それでいいのだ。それならパソコンのブラウザを使えば、いいだけじゃん。イヤホン端子もついているし。しかもBeelink S1はHDMI出力できる。
 ただ、MacBook Airではうまく再生されなかった。
 Beelink S1を試してみる。
 Firefoxはだめだった。Chromeはいけた。
 あれ、待てよ。MacBook AirがだめだったのはSafariだったからかも。案の定でChromeだとうまくいった。
 「ソードアート・オンライン オルタナティブ ガンゲイル・オンライン」のアクションシーンを観比べてみたところ、軍配はMacBook Airにあがった1。あれ、そうすると、新しいモニタを買った意味がなくね?
 まぁ、MacBook AirをDELLモニタにVGA接続すれば、いいだけなんだけどさ……。

 結局、Beelink S1の使い道はなく、それだと悲しいのでいちおうHDMIにつないでおくことにした2。マウスとキーボードなしの状態なので何もできないけど3, 4
 ショックなのは直販で購入したDELLモニタよりもAmazonで買った方が安かったことだ……。しばらくうだうだしそうだ。

Footnotes:

1

接続方法の差か、OSの差なのか、マシンの差なのかは不明。

2

プリインストールされているWindowsをUpdateしたら5時間たっても終わらなかった……。

3

VNCでMacBook Airにつないでみたけれど、遅すぎて使いものにならなかった。

4

synergyを使う手もあるけれど——昔、Mac miniを使っていたころ、使っていた——、いつのまにか、有料になっていてBeelink S1を使う頻度と値段を考慮した結果、今回は見送り。

2018年12月14日金曜日

Dell 27 Monitor - SE2719H - Dell Sシリーズ SE2719H 27インチワイドモニター

 27inchのモニタを使う機会があり、最初は画面の大きさに目がびっくりしていたけれど、馴れると、いいな、と思うようになってしまった。調べてみたら値段的に手頃だったので買うことにした。実は最近のモニタにはHDMIがついているのでApple TVをつなげてやれば、テレビのかわりになるのではないか、とさもしいことを考えたのだ。
 視聴はネット配信が中心だし。
 このあいだ、買ったBlue-rayの再生専用機も使えるだろうし。
 まぁ、オーディオ出力についてはあとで考えよう。
 どうせいつもはイヤホンなのだし。
 それにもしかしたら買っただけのBeelink S1にも何かいい使い道ができるかもしれん1

 買ってすぐにApple TVをつけてみる。
 うん、いいんじゃね?
 音はでないけど。

Footnotes:

1

モニタは邪魔なので押し入れにいれっぱなしなのだった。

2018年12月12日水曜日

ABCL

 あれ、CL-DBIはOrcleに対応してないのか1
 探せば、どこかにあるかもしれないけど、つらつら考えてそういや、ABCLってjava上で動くCommonLispなんだよな。それならjavaを使って(ojdbc.jarを使って)Oracleにアクセスできるんじゃね?
 「Class.forName("oracle.jdbc.driver.OracleDriver");」をやっただけではうまくいかなくて、けっこう苦労したけれど、いちおう、動いたような気がする。ざっくり。
 錯覚かもしれないが。

(in-package :cl-user)

(defpackage y-dbi
  (:use :cl :java))

(in-package :y-dbi)

(add-to-classpath "ここにojdbc.jarを指定")

(defvar oracle (jnew "oracle.jdbc.driver.OracleDriver")
  "oracleのドライバをロード")

(defun connect(&key server database user password)
  (let ((connect
  (concatenate 'string "jdbc:oracle:thin:@" server ":1521:" database))
 (properits (jnew "java.util.Properties")))
    (jcall "put" properits "user" user)
    (jcall "put" properits "password" password)
    (jcall "connect" oracle connect properits)))

(defun disconnect(conn)
  (jcall "close" conn))

(defun execute(conn sql)
  "ResultSetを返却する"
  (let ((stmt (jcall "createStatement" conn)))
    (jcall "executeQuery" stmt sql)))

(defun fetch(rs)
  (jcall "next" rs)
  (when (not (jcall "isAfterLast" rs))
    (let ((rsmd (jcall "getMetaData" rs)))
      (loop for i from 1 to (jcall "getColumnCount" rsmd)
  append
    (list (intern (jcall "getColumnName" rsmd i) 'keyword)
   (jcall "getString" rs i))))))

(defun select(conn sql &optional limit)
  (let ((rs (execute conn sql)))
    (if limit
 (loop for i from 0 to (- limit 1)
    collect (fetch rs))
 (loop for row = (fetch rs)
    while row
    collect row))))

(defun column(list)
  (loop for x in list
     for i from 0
       append (when (evenp i) (list x))))
CL-USER> (in-package :y-dbi)
#<PACKAGE Y-DBI>
Y-DBI> (select (connect :server "XXXX"
   :database "YYYY"
   :user "ZZZZ"
   :password "PASS") "select * from dual")
((:DUMMY "X"))
Y-DBI>

Footnotes:

1

商用なのである意味、当たり前か。

2018年12月10日月曜日

ユークリッドの互除法

 一松信の「暗号の数理」を読んでいたら「ユークリッドの互除法」というものがでてきた。二つの正の整数m、nの最大公約数を求めるアルゴリズムである。下記のような手順だ。

  1. mとnを比較し、必要なら入れかえてm≧nとせよ。
  2. mをnで割り、商をq、余りをrとせよ。
  3. 余りrが0(割り切れた)なら、そのときの除数nが最大公約数である。これで完了。
  4. 余りrが0でなければ、除数nと余りrとをm、n,と置き直して、2.へ戻れ、

    この操作を反復すれば、いつか必ず3.に逹っして、完了するであろう。

     ——一松信「暗号の数理」より

 で、なんで、これで最大公約数が求まるのだろう……。
 ピンとこなくて考えこんでしまった。
 うーむ。
 n自身が最大公約数のとき、求まるのはわかる。では2周目はどうだろう。一回目のrが最大公約数の場合。もちろんそのときはrでnが割り切れるはずだ。もちろん、mも割り切れる(mはnとrに分解できるのだから)。
 あ、なるほど。そういうことか。
 あとは以下同文。

(defun Euclid(m n)
  "ユークリッドの互除法。m、nの最大公約数を求める。"
  (if (< m n)
      (Euclid n m)
    (progn
      (let ((q (/ m n))
     (r (mod m n)))
 (if (= r 0)
     n
   (Euclid n r))))))
(Euclid 25 5)
5
(Euclid 7 5)
1

2018年11月30日金曜日

新房昭之監督「続・終物語」

 テレビ放映で「終物語」を観て——原作の上中巻分——。
 iPhoneのアプリで「暦物語」を観て。
 劇場版の「傷物語」を観て。
 「終物語」の続きを楽しみにしていたら——「続・終物語」の予告編がYutubeにあがっていた。劇場版である。一瞬、「終物語」の続きを劇場版でやるのか、と思った。「傷物語」のように。
 しかし、どうみてもこの予告編はちがう。
 えっ、もしかしたら「終物語」の続きはもう放映されていたの?

 あわててwikipediaをチェックしたらやはり放映されたあとだった。一年以上も前に二夜連続二時間スペシャルという形で。
 しかもAmazonとかではまだ、配信もされていない。「憑物語」までだ。
 これはもう、DVDを買うしか、ないか、と頭を抱えながら<物語>シリーズのポータルサイトを確認したら「終物語」の後半も配信されるという。
 それで配信系にユーザー登録して観た。「終物語」の後半。
 そうしたら「続・終物語」を観たくなった。

 というわけで観てきた。

2018年11月27日火曜日

macOS Mojave

 「macOS Mojave」にしたら色々と動かなくなってしまった。

  1. VirtualBox

    最新版(5.2.22)をインストール

  2. GnuCash

    最新版(3.3)をインストール

  3. Git

    Git本体ではなく、xcodeのcommandLine toolがなくなっていたためらしい1。「xcode-select –install」で再インストール。

  4. TimeCapsuleのネットワークドライブがmountできなくなった。

    AFP(Apple Filing Protocol)が使えなくなったかららしい。おかげでTimeCapsuleのネットワークドライブがmountできない。ここの中にiTuneの音楽データをいれていたのに!
    頭を抱えてしまったが、「サーバへの接続」からならmountできた2のでとりあえずデータをレスキューしておく。
    いっそ音楽データはApple Musicへいれてしまうか。

  5. Time machine

    TimeCapsuleへのバックアップが遅くなったような気がする。

Footnotes:

1

そういえば、以前のメジャーアップデートのときも起きた。svnが動かなくなったのだった。

2

よくよく考えたらTimeCapsuleにはまだ、バックアップできるのだからAFP自体がなくなっているわけではなかったらしい。いつか、なくなってしまうだろうけど(TImeCapsuleは製品としてなくなってしまったので)。今はまだ、というところだろうか。

2018年11月21日水曜日

UbuntuのIPv6を抑止

 なんか、Ubuntuからうまくメール送信できない。
 へんだなぁ。MacBook Airからではできるのに。両方ともEmacsからのメール送信。試しにpingを打ってみて原因が判明する。
 DNSで返ってきてるの、IPv6じゃん。
 そういや、以前、macOSでも対応した
 というわけで、LinuxのIPv6を抑止する方法をググる。

 => Ubuntu Server 16.04 LTS でipv6を無効化したときの作業メモ

 たぶん、こうか。
 /etc/sysctl.confに下記を追加。

net.ipv6.conf.all.disable_ipv6 = 1
net.ipv6.conf.default.disable_ipv6 = 1

2018年11月19日月曜日

アップデート

 新しいMacBook Airが発表された。
 13inchだけだけど、物欲が刺激されてしまった。欲しい。でも高い。前回の轍を踏まないように、次はフルスペックにするつもりだった。けれど、そうすると、けっこうな額になる。二の足を踏む。
 それでほかのものを目がいってしまった。
 ——「GPD Pocket
 いかんいかん。
 完全に物欲が昂進してしまっている。やばい。ポチってしまいそうだ。家には使っていないパソコンがあるというのに。

 そんなとき、寝起きの寝惚けた頭で衝動的にMacBook AirのOSをアップデートしてしまった。「macOS Mojave」にへ、である。正確にはしようとした。ディスク容量が足りなくて失敗した。
 ラッキーである。
 動いているアプリが動かなくなることがあるのでなるべく、メジャーアップデートは避けていたのだ。「macOS High Sierra」ときも見送った。
 なのに。
 カッとなってファイルをガシガシ消している自分がいた。何をやっておるのか。まぁ、バックアップはあるので元には戻せる、とは思っていたけれど。——「macOS Mojave」をインストールしてしまった。

 なんか、インストールに時間がかかるなぁ、と思っていたらどうやらファイルシステムを変換していたらしい。HFS+からAPFSへ。ためしに「df -h」してびっくりした。何だよ、このifreeが「9223372036853272673」って。
 inodeが64bitに拡張されていたのである。

 ま。いずれにしてもOSが刷新されたので、気分もかわってなんとか、物欲もおさまった。これでしばらく戦える(だれと?)

2018年11月12日月曜日

directory-files-recursively

 findのない環境でEmacsを使うとき、(find-lisp-find-dired DIR REGEXP)を使用していたのだけれど、この関数はヒットしたファイルの、diredのバッファを作成してくれるだけで、listを返してくれない。
 しかたないのでファイルのlistを返却するようにラッパー関数をつくった。
 けっこう遅いけれど。でもこれで(eshell-poor-mans-grep ARGS)を簡単に呼び出せるぜ、と思ったら。
 (directory-files-recursively DIR REGEXP &optional INCLUDE-DIRECTORIES)という関数を見つける。ラッパーをつくった直後に。Infoで。これならヒットしたファイルのlistを返してくれる。
 昔、探したときには見つけることができなかったんだなぁ。
 見落としていただけなんだろうか?
 それにしてもあいかわらずの間の悪さよ。

2018年11月9日金曜日

アンドレイ・タルコフスキー監督「惑星ソラリス」

 AmazonのPrime Videoで「カプリコン・1」を検索してブルーレイがあることを知ったことをきっかけにふと、過去に感銘を受けた映画を見直したくなった。時々、そういうことをしていたのだけど、好みが偏っているのか、大概、見つからなくてあきらめていた——まぁ、見つかることもあったけれど。「狼は天使の匂い」とか。
 で、どんな映画があったっけ、と思って思い出したのが、アンドレイ・タルコフスキー監督「惑星ソラリス」だった。ハリウッドのリメイク版ではなく。あれは途中で観るのをやめてしまった。
 なんと中古だが、DVDがあった1
 当時2、ラストシーンには最初の「猿の惑星」と同じくらいあっと息を飲んだものだった。今回、見直して傑作の感をあらたにしたけれど、でもなんでそんなに驚いたのだろう。ラストシーンの前でちゃんとラストをふっていて気づいてもおかしくなかったのだが。

Footnotes:

1

さっそく注文して届いたのは円盤だけだった。あれ、箱は? と思った。まぁ、いいけど。

2

観たのはさいわい上京前だったので、未来都市のシーンに(首都高の映像が使われている)違和感はなかった。

2018年11月7日水曜日

orとreturn

 どうもLispは関数型だという意識がありすぎて、returnがどうしてあるんだろう、と思っていたらたとえば、returnがあれば、次のようなコードはあっさり書ける。

(block nil
  (when-let(w (処理1))
     (return w))

  (when-let(w (処理2))
     (return w)))

 実際に書いたのはelispのclでだけど。
 処理1が成功したらその返却値を返し、失敗したときは処理2を行なってその返却値を——というパターン。便利。というか、C言語とかではわりと使っていた記憶が……。さらにラップするマクロを書いてもいいんじゃないか、と思ったのだけれど、よくよく考えたらorで書けるんだった…orz。

(or (処理1)
    (処理2))

ただ、あとからソースを見直しとき、前者の方が見易いかもしれない。

2018年11月5日月曜日

ピーター・ハイアムズ監督「カプリコン・1」

 スティーヴン・キング「死の舞踏」によると、「カプリコン・1」は駄作らしい。えー、そんなことはないだろう。すくなくとも個人的には映画館で五回は見直しているし。
 公開当時、手塚治虫が書いていた小説(マンガではなく)のネタが「カプリコン・1」とかぶってボツにしたと悔しがっていたし、清原なつのの「花岡ちゃんの夏休み」の中の一編で——たぶん「早春物語」かな——背景の本棚のシーンで、「カプリコン・1」のセリフが落書きされていた。
 ——エリザベス、水がない。
 とか。
 ちなみに映画館で観たものとは訳が微妙にかわっていて——「エリザベス、水がない」はなくなっていた——ちょっと違和感だった。それにしてもエリオット・グールド演じる記者の尺はけっこうあったんだなぁ。というか、中心だった。すっかり忘れていたけれど。カーアクションのところなど、当時、「フレンチコネクション」のカーアクションみたいだ、と思ったことを思い出す始末だった。

2018年11月3日土曜日

&optional

 elispで関数の引数を&optionalにして、指定されていないときのデフォルトをいちいち「unless」で処理を書くとか、面倒だ。commonlispなら簡単なのに。
 そういえば、「cl-defun」とか、あったっけ……。

(cl-defun foo(&optional (x 123))
  x)
foo
(foo)
123
(foo 777)
777

 おっ、いけるじゃん。

2018年10月22日月曜日

keywordシンボル

 あれれ、そういえば、「:XXXX」っていうシンボルどうやってつくれば、いいんだ。cl-dbiのplistようなものをつくろうとして戸惑ってしまった。知らんぞ。シンボル自体は「intern」でつくれることは知っていたけれど。
 しばし、「intern」の呼び出しパラメータを見ていてふと気づく。
 そういえば、「:」つきのシンボルはkeywordパッケージに定義されるんだったっけ……。こうか。

CL-USER> (intern "ABC" 'keyword)
:ABC
NIL
CL-USER>

 ビンゴ。
 ちょっとうれしい。

2018年10月19日金曜日

今石洋之監督「キルラキル」

 どハマリした。
 「キルラキル」にである。
 Amazon Primeで観はじめて二日で全24話を観終える。ぼろぼろと涙をこぼしながら。ところがwikipediaによると、第25話がある、という。DVD収録にされているのみ。うわあ。
 これは買うしかないなぁ。というわけで収録されている9巻を購入した。いつもならDVD版なのだけれど、魔が刺したのか、Blue-rayを買う。到着したBlue-rayをいそいそとテレビのドライブへ挿入したまでよかった。けれど。
 ——再生されなかった。
 それどころか、イジェクトもされない。
 リセットしたり、電源断したり、ネットで見つけた対応方法を試してみたけれど、結果はすべてネガティブ。大枚はたいて購入したBlue-rayがテレビに喰われてしまった……。
 頭にきて夜中にテレビを分解した。
 取り出したBlue-rayドライブをさらにばらし、DISCをなんとかレスキュー。そのあと元通りにテレビを組み立てたのだけれど、なぜか、ネジが2本、あまる。なぜだ?
 いつもそうなる。
 不思議だ。

 結局、「キルラキル」の第25話はBlue-rayの再生専用機を購入して観た。

2018年9月18日火曜日

Emacs for Windowsでfind-grepっぽいことをする

 けっこうよく使うのはfindとgrepの組み合わせなのだけど、Windows環境だとそれが使えない。findとgrepがないからだ。もしかしたらエクスプロラーで同等のことができるのかもしれないが、無知でよくわからない。単純に動かすとファイル名で検索しているように見える。エクセルの中身を検索してくれるときとかもあるのだけれど。
 そのちがいがよくわからない。
 検索したいのは基本的にプレーンテキストなわけなのだから。
 それならEmacs for Windowsでfind-grepをすれば、いいんじゃないか。でもemacsのfindもgrepも外部コマンドが実行される。つまりWindows環境にfindとgrepがないとどうしようもない。
 grep単体ならeshellにelispで実装された「eshell-poor-mans-grep」があるし、findもelispで実装されたものがある。それをfind-grepのように組み合わせるにはどうしたいいんだ?
 試行錯誤の結果、たどりついたのが。

  1. find-lisp-find-diredでファイル検索
  2. その結果をdired-modeでmark1
  3. (eshell-poor-mans-grep (cons 検索文字列 (dired-get-marked-files)))を実行。

 一回、eshell-poor-mans-grepをかけると、対象ファイルはEmacsのバッファに読みこまれているので何回もやりなおすときには検索が早くなって都合がいい。全ファイルが展開されているせいでメモリを圧迫して苦しいときもあるけれど。

追記:
もっと簡単な方法があった

Footnotes:

1

「* %」でmarkして「C-u * %」でunmarkできるのでけっこういける。

2018年8月26日日曜日

Peter Seibel「実践CommonLisp」

 知らんことだらけ。
 そして、理解し切れんことだらけ。
 とくにコンディションについてはjavaとかのtry/catchと同じだと思っていたので目が点。あとdefgenericとか、いろいろ。奥が深すぎるぜ、CommonLisp。

 著者は「Coders at Work プログラミングの技をめぐる探求」と同じ人だった。ついさっきまで気づかなかったのだけれど、それにしても「Coders」を読んだときに得た「気づき」ってなんだろう。なーんも思い出せん。

2018年8月5日日曜日

HHK

 どうもタイピングで指にけっこう、力を入れているらしく、指の背面側の筋が張る。普通にしているときはあまり気づかないのだけど、ぎゅっと握り拳をつくってみると、はっきりとわかる。ちょっと痛い。
 昔はこういう疲れ方はしなかったような?
 これはあれだな。
 MacBook Airのキーが浅いから指先を叩きつけるようにしてしまっているからだな(仮説)。
 じゃ、深いキーボードにしてみるか。
 候補は以前、使っていたことがあるHHKあたり。小さいし。だた、音がなぁ、タイプ音がけっこう、うるさいんだよな。ほとんどタイプライターのようになってしまう。
 それであきらめていたんだけど、HHKのキーボードは20%静音になったという。じゃ、というわけで、使ってみることにした。でも以前はデスクトップだった。
 だから今だとこうなってしまう。

 ケーブルの挿しこみ口がちょっと計算外だった。

2018年8月4日土曜日

2018年8月2日(木):本栖湖FUNビーチ:晴れのち、薄曇り

* Sail:CORE 5.7(NEIL PRYDE) Board:NG ACP 260 Fin:9.5inch

-No- 時刻 時間 帆走距離 最高速 平均時速 P%
1 14:36-14:58 22分 2.3km 18.63km/h 6.25km/h 1.33
2 15:01-15:16 14分 1.5km 15.36km/h 6.44km/h 0.12
3 15:25-16:09 44分 2.1km 17.92km/h 2.90km/h 0.30
4 16:41-17:15 34分 1.9km 11.43km/h 3.40km/h 0.00

total 115分 7.9km 4.1km/h

 とにかく遠い。
 9時前に出立したというのに到着したのは13時半すぎ。
 めげる。
 風は入りはじめているらしく、ドラゴンビーチ、FUNビーチともにセイルが湖面にある。でもあまり、動いていない。セイルをセッティングしているうちに湖面がブローが入って白波がたつ瞬間があった。
 ——きたか?
 ところが出艇したときには陽が翳り、風はなくなってしまう。
 風上の吹き出し口付近だけプレーニングしているのでひたすらそちらへ上っていってみたけれど、風は全然、足りず。
 ノープレーニング1
 FUNビーチの上側の岸で休憩したらあまりの風のなさにビーチスタートすらできなくなくて身動きできなくなる。足をだれかがつついている。しかたないので腹をくくってセイルアップする。
 FUNビーチの下側へもどる。
 だめだ。今日はだめだ。
 4時ぐらいに風がふたたび、入りはじめた感じがあって出艇して沖ではまる。完全に風がなくなり、まわりにだれもいない状況。セイルアップもできず、道具を引いて泳ぐことしばし。
 ブロー。
 あわててボードによじのぼり、セイルアップ2
 岸を目指す。
 FUNビーチからプロ選手とおぼしき人たちが出艇してきた。吹き出したのか? 吹くのか? ボーナスタイムか? もう一度、沖へでてみたい気持ちにかられたけれど、どうせプレーニングできない、といいきかせて着岸。
 ふりかえると、5艇ほどが沖で止まっていた。

 ノープレーニングノーライフ、ふたたび。

Footnotes:

1

表のP%は速度15km/hをプレーニングとしている。実際にはフットストラップに足をいれることすらできなかった。

2

今日ほどセイルアップとタックした日はなかったような気がする。

2018年8月3日金曜日

gpx-menu

 というわけで
 以前つくったっきりだった速度リスト表示プログラムをupdate。
 なんだかんだと不満な点もあったので。

 JOSMで航跡を表示できるようにした。
 あと、現在のトラックポイントからひとつ前の速度のトラックポイントへジャンプする機能を追加1。ほか多少。

Footnotes:

1

ワンキーで最高速のトラックポイントへジャンプする機能は以前通り。

2018年8月2日木曜日

2018年8月1日(水):検見川浜:晴れ

 サーマルを期待して検見川浜へ。
 ほんとうは本栖湖へ行くつもりだったのだが、朝起きれず。
 いちおう吹いていた。カイト、デカスラ、フォイルなら走る風——それでもスラロームは走ったり、止まったりしている。
 しばらく海を眺めていたら縦横無尽に走っているカイトがひとり。やたら速い。なんじゃあ、と思っていたらカイトフォイルだった。すげー速い。あっという間に沖まで上っていってしまった。
 あれ、いいな。
 駐車場でうだうだ。
 夕方に吹いてきた感じがあり、海を見ると、さっきより走っているし、うみほたるの風速の実況は11m。これはいけるでしょ、と思ってボードをセッティングして波打ち際まで。
 が、思ったよりない。
 出艇しているセイルは小さいような気がするけど、きっと7.0m2はあるはず。最近のセイルはどれも小さく見えてしまうんだよね。
 30分ほど、波打ち際で太陽に照らされて海を見ていたけれど——これはだめだ、とあきらめて撤収。
 ノープレーニングノーライフ。
 まったく。

2018年8月1日水曜日

when-let

 lispでよく書くパターン。

(let ((w (XXX XXXX)))
    (when w (BODY...))

 というもので、取得した値があったら処理するというパターン。
 これこそマクロにするべきものだよな。
 名前は「when-let」あたりか。
 と思ったところではっ、と気づいて調べてみると、elispにはまさにそれがあった……。

(require 'subr-x)

2018年7月30日月曜日

branchって便利

 いったん動いているプログラムはあまり、いじりたくない。
 elispならとくにそうで、プログラムがEmacsで動作するのでロードエラーがでるような状態にしてしまうと、通常の業務1に支障がでてしまう。というわけで、なおしたいなぁ、と思っていても放っておいてしまっていた。

 でもgitのbranchを使えば、いいんじゃね?
 新しいbranchを切ってそちらで修正をしておいて必要になったら。

git checkout master

 で、元にもどせば、いい。
 同じようなことはsubversionでもできたはずなのだけど、全然、思いつきもしなかった。何をやっておるのか。

 というわけでこれからがんがん、プログラムがいじれる。
 いじれるはず。
 いじらないけど。

Footnotes:

1

何の業務だ?

2018年7月28日土曜日

slime-scratch

 REPLって便利なんだけど、Emacsのscratchバッファになれているせいか、どうも使いづらい。scratshバッファは平面だけど、REPLは一次元ということがあるのだろう。
 ダミーのlispファイルをひらいてそのバッファでコードを書いて——実際の動作はREPLで確認、ということをやっていた。
 slimeの関数を眺めていたらslime-scratchというのを見つけた。
 おっ。

2018年7月26日木曜日

スターン数列とフィボナッチ数

スターン数列は,f(0)=0、f(1)=1と二つの再帰的関係f(2n)=f(n)およびf(2n+1)=f(n)+f(n+1)で定義される.これを計算すると,数列は0,1,1,2,1,3,2,1,4,3,5,2,5,3,4と続く.

マーク・チャンバーランド「ひとけたの数に魅せられて」 P11

 何をいっているのか、わからない。

 スターン数列でググってみたけれど、ヒットしたサイトは本の説明をくりかえしているだけで何のとっかかりにもならなかった。日本語のwikiも見当たらない。
 まぁ、f(0)とf(1)はわかる。でもf(2n)=f(n)って何だ? イコールじゃないじゃないか。
 しばし、じっと見つめる。
 あれ?
 もしかしたらf(2n)って偶数のことじゃないか?
 すると、f(2n+1)は奇数か。
 じゃ、コードはこうか?

(require 'cl)

(defun wrk(n)
  (cond ((= n 0) 0)
 ((= n 1) 1)
 ((evenp n)(wrk (/ n 2)))
 ((oddp n)(+ (wrk (/ n 2))(wrk (+ (/ n 2) 1))))))

(mapcar 'wrk '(0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15))
(0 1 1 2 1 3 2 3 1 4 3 5 2 5 3 4)

 おっ、正しいみたいだぞ1
 プログラミングができてよかった。
 エレン、マフラーを巻いてくれてありがとうって気分だ。

 そういえば、フィボナッチ数のコードはよく見かけるけど2、実際に自分で組んでみたことはなかった。たしか、こんな感じ?

(defun wrk(n)
  (cond ((= n 0) 0)
 ((= n 1) 1)
 (t (+ (wrk (- n 1))(wrk (- n 2))))))

(mapcar 'wrk '(0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15))
(0 1 1 2 3 5 8 13 21 34 55 89 144 233 377 610)

 0から15ぐらいならすぐだけど、0から100までにしたら延々、もどってこない……。

Footnotes:

1

by elisp

2

再帰の例題としては定番。

2018年7月24日火曜日

竹内郁雄「初めての人のためのLISP」

 もっと早くに読んでおくべきだった。
 交互リストによるplistのことも書かれているし、keywordについても——CommonLispをはじめていろいろ疑問に思ったことの答えが書かれていた。
 もっともずっと以前に読んでいたらこれらのことは気づかずにふーんとスルーしていたにちがいないけど。

2018年7月22日日曜日

setf

 setfではassocを使えないんだね1

CL-USER> wrk
((1 2) (3 4) (5 6))
CL-USER> (setf (assoc 3 wrk) 123)
; Evaluation aborted on #<UNDEFINED-FUNCTION (SETF ASSOC) {1003D452D3}>.
CL-USER>

 でもこうすると、中身を変更できるんだ。

CL-USER> wrk
((1 2) (3 4) (5 6))
CL-USER> (setf (cadr (assoc 3 wrk)) 99)
99
CL-USER> wrk
((1 2) (3 99) (5 6))
CL-USER>

 これまた、RDBっぽい。
 ちなみにまちがって下記のように書いたらSBCLは即エラーになったけれど、ABCLは永久ループにはまりこんでしまった。

CL-USER> wrk
((1 2) (3 4) (5 6))
CL-USER> (setf (cadr (assoc 3 wrk)) wrk)

 elispはどうだろう。

(setf wrk '((1 2)(3 4)(5 6)))
((1 2) (3 4) (5 6))
(setf (cadr (assoc 3 wrk)) wrk)
((1 2) (3 #0) (5 6))
wrk
((1 2) (3 #0) (5 6))

 なんじゃ?

Footnotes:

1

setfできるassocがalexandriaにあるらしい。

2018年7月20日金曜日

delete

 listを操作する関数で破壊的なものはあまり使う気になれなかった。意外なところに影響がでたりするからだ。でもsetfは便利だな、と思っていて、そういえば、listの一部だけ削除するにはどうしたらいいんだろう。
 deleteを見つけて色々、試してみて思った。
 これってassocと組み合わせるとすごくね?

CL-USER> wrk
((1 2) (3 4) (5 6))
CL-USER> (delete (assoc 3 wrk) wrk)
((1 2) (5 6))
CL-USER> wrk
((1 2) (5 6))
CL-USER>

 RDBみたいじゃん。
 deleteのような破壊的関数ではなく、removeというのもあった。

CL-USER> wrk
((1 2) (3 4) (5 6))
CL-USER> (setq wrk2 (remove (nth 1 wrk) wrk))
((1 2) (5 6))
CL-USER> wrk
((1 2) (3 4) (5 6))
CL-USER> wrk2
((1 2) (5 6))
CL-USER>

 もしかしたら、と思って試してみたら。
 wrkとwrk2の要素は共有されていた。

CL-USER> (setf (caar wrk2) 123)
123
CL-USER> wrk
((123 2) (3 4) (5 6))
CL-USER> wrk2
((123 2) (5 6))

 おもしろい。
 elispでも同じことができるけど、deleteの比較はequalだった。eqのものはdelq。CommonLispはどうやらeqらしい。:testで変更できるけど。

2018年7月19日木曜日

2018年7月16日(月):検見川浜:晴れ

* Sail:CORE 5.7(NEIL PRYDE) Board:NG ACP 260 Fin:9.5inch

No 時刻 時間 帆走距離 最高速 平均時速 P%
1R 14:21-14:43 21分 2.9km 19.92km/h 7.85km/h 3.87
2R 15:03-15:32 28分 4.1km 31.47km/h 8.56km/h 5.89
3R 16:04-16:17 13分 1.3km 17.55km/h 5.43km/h 0.43

total 64分 8.2km 7.6km/h

 ほんとうは海へ行くつもりはなかった。
 GPVを見るかぎり、昨日より吹くとは思えない。昨日ですら微妙だったのだ。だから昨日、検見川へ行ったのに、今日も来てしまった。入庫待ちの車の列に並ぶ。さすがに昨日よりも早めだったので時間がかかってしまう。
 風は微妙。いや無理だろう。
 デカスラは走っているけれど。
 夕方のひと吹きを期待して海へでる。だめ。腹が立つのは自分が海からあがると、急に吹き出して走り出したように見えることだ。もちろん錯覚だ。そもそもプレーニングしている人間と自分が同じ腕前という前提がまちがっている。
 というわけで本日、プレーニングしたのは一本だけだった。

2018年7月18日水曜日

2018年7月15日(日):検見川浜:晴れ

Sail:CORE 5.7(NEIL PRYDE) Board:NG ACP 260 Fin:9.5inch

No 時刻 時間 帆走距離 最高速 平均時速 P%
1R 14:45-15:02 17分 1.5km 31.23km/h 5.07km/h 3.19
2R 15:06-15:18 12分 1.3km 19.62km/h 6.60km/h 2.28
3R 15:44-16:50 65分 8.4km 35.21km/h 7.74km/h 8.88
4R 17:07-17:23 16分 2.5km 34.69km/h 9.07km/h 13.72

total 111分 13.8km 7.4km/h

 30分待ちで駐車場に入れることができた。
 途中、道路から見える検見川浜は沖でデカスラっぽいセイルが走っていた。微妙に足りないんだろうなぁ、と思っていたら案の定で微妙に足りない風——ブローも微妙。
 スタボーはうねりにあわせてなんとか、プレーニングすることもあったけれど。ポートは乗り方を忘れていることもあってほぼ全滅。それでも二度ほどプレーニングした。
 ジャイブは、何それ、おいしいの? 状態。
 二時すぎにあった風はいったん落ちて五時ぐらいにやや強くなる。
 気温が下がって風が重くなったのかもしれない。
 夏の検見川浜のサーマルははじめてだったけれど、もうすこし大きめのサイズがないときびしいなぁ。
 それにしても身体が動かない。
 晩年の岡部幸雄のようにストレッチをした方がいいんだろうなぁ。

2018年7月17日火曜日

slime-eval

 CommonLispを使うようになってelispをプログラミングする気力がなくなってしまった。
 別にLisp四天王でelispが一番、最弱だから、というわけではなく、CommonLisp——SBCL——のレスポンスが速くてelispを使う気がしなくなってしまったのがひとつ。もうひとつは別プロセスで動くので、Emacsがかたまるということがない。こっちの方が理由としては大きいかもしれない。
 ただ、やはりエンドユーザとのインターフェイスをもっているというのは大きくてなんだかんだと選択肢はelispということになってしまう。
 じゃあバックグランドでCommonLispを動かしてしまえば、いいじゃん。
 S式でやりとりできるだろうし。
 roswellスクリプトをshell-commandで起動して……とか、考えて面倒くさっ、と思ってしまった。もっと簡単にできないものか。

 そもそもEmacsとCommonLispでやりとりしているわけだし。
 ——slimeに何か、あるんじゃね?
 そう思ってつらつらslimeのソースをながめていたら。
 「slime-eval」というものを見つけた。
 slimeを動かして*scratch*で——。

(slime-eval `(cl-user::+ 1 2 3))
6

 おおっ。
 eval自体はSWANK-IO-PACKAGEの中で動いているらしく、packageをフル指定しなければ、ならなかったけれど。
 listだって返ってくる。

(setq wrk (slime-eval `(cl-user::list 1 2 3)))
(1 2 3)
(car wrk)
1

 elispとシームレスにやりとりできるじゃないか!
 しかも非同期バージョンと思しき、「slime-eval-async」もある。
 「asdf::load-system」だってelispから動かせる。

 しかし、elispの変数の中身をわたすには——。

(setq wrk 4)
4
(setq wrk (slime-eval `(cl-user::list 1 2 3 ,wrk)))
(1 2 3 4)

 こうか。
 それにしてもこのやり方ってlispにしか、できない芸当だよなぁ1

Footnotes:

1

shellもできるか……。

2018年7月15日日曜日

(unintern 'function)

 けっこうdefmethodが好きだ。
 引数の型によって処理をディスパッチできるので同じ名称をつけることができる。ただ、REPLでdefunで定義したものをあらためてdefmethodにしようとするエラーになってしまう1。いちいち、restartさせなければ、ならず……ああ?
 まてよ、所詮、シンボル。
 もしかしたら。

(unintern 'function)

 で、いけるんじゃね?
 defmethodで定義できるようになるんじゃね?
 ——いけた2

Footnotes:

1

SBCLだけ?

2

追記。いけたと思っていたのだけど、だめなケースもあるみたいで
方法を探してみたところ

(fmakunbound 'function)

で、できるらしい。

2018年7月13日金曜日

nilってほんとうにNULLなのか!

 けっこうdefmethodが好きだ。
 というのも引数によって処理を分岐する関数をつくることが多いから。
 たとえば(下記はelispだけど)。

(defun y-string-to(x)
  "stringへ変換"
  (cond ((null x) "")
 ((listp x)(y-string-to (car x)))
 ((symbolp x)(y-string-to (symbol-name x)))
 ((stringp x) x)
 ((numberp x) (number-to-string x))
 ((vectorp x)(y-string-to (aref x 0)))))

 とか。
 defmethodを使えば、これらは全部、分けられる。

(defmethod y-string-to((x string))
      x)

(defmethod y-string-to((x number))
      (format nil "~D" x))

 とか。でもstringでもnumberでもないnilのときはどうすれば、いいねん、と思っていたら定義できるのだった。

(defmethod y-string-to((x null))
      "")

 nilってNULLってタイプなのか!

DEF> (type-of nil)
NULL
DEF>

2018年7月11日水曜日

Lispに型はないと思っていたら

 どうしてか、Lispには型がないとばかり思っていた。
 さすがに文字列と数値とかはあるだろうけど、と。

DEF> (type-of :ABC)
KEYWORD
DEF>

 ってやってみて驚いた。
 「:」付きってkeywordという型をなのか。
 あるじゃないか。型。
 以前からよくわからなかった「:」はkeywordという型指定ということになるのか、つまり。もしかしたらリーダーマクロで実装されているんだろうか?

 というか、根本的に勘違いしているじゃないか。

Lispはプログラムの実行時まで呼び出すべき変数のデータ型や関数の実体が決まらない動的束縛(late bindingともいう)の言語である。

竹内郁雄「初めての人のためのLisp [増補改訂版]」

2018年7月9日月曜日

みたび、package

 たとえば、次のようなpackageとclassを定義したとする。

(in-package :cl-user)

(defpackage abc
  (:use :cl)
  (:export :<abc>))

(in-package :abc)

(defclass <abc> ()
  ((abc :initarg :abc
  :reader get-abc
  :documentation "abc")))

(in-package :cl-user)
(defpackage def
  (:use :cl
 :abc))

(in-package :def)

(defclass <def> (<abc>)
  ((def :initarg :def
  :reader get-def
  :documentation "def")))

 で、defの中でinstanceを作成。

DEF> (setq wrk (make-instance '<def> :abc "111" :def "222"))

 まぁ、WARNINGは多少でるけれど、中身は設定されている。

DEF> (get-def wrk)
"222"
DEF>

 get-abcが効かないのは関数をexportしていないのでDEFから見えていないからだろう。

DEF> (get-abc wrk)
; in: GET-ABC WRK
;     (DEF::GET-ABC DEF::WRK)
; 
; caught STYLE-WARNING:
;   undefined function: GET-ABC
; 
; caught WARNING:
;   undefined variable: WRK
; 
; compilation unit finished
;   Undefined function:
;     GET-ABC
;   Undefined variable:
;     WRK
;   caught 1 WARNING condition
;   caught 1 STYLE-WARNING condition
; Evaluation aborted on #<UNDEFINED-FUNCTION GET-ABC {1003F36EE3}>.
DEF>

 ところがslot-valueでabcの中身を見にいってもエラーになる。

DEF> (slot-value wrk 'def)
"222"
DEF> (slot-value wrk 'abc)
; Evaluation aborted on #<SIMPLE-ERROR "~@<When attempting to ~A, the slot ~S is missing from the ~
   object ~S.~@:>" {10040EC8D3}>.
DEF>

 これがしばらく理解できなかった。
 というのもelispのEIEIOではうまくいくからだ。
 HyperSpecのdefpackageの説明を見ていてexportしているのはsymbol-nameだと気づいた。functionじゃないんだ……。つまりClassの中で定義しているslot-nameもexportしなければ、いけない。
 それならこれでも動くはず。

DEF> (slot-value wrk 'abc::abc)
"111"
DEF>

 実際にexportしてやっても動いた。

(defpackage abc
  (:use :cl)
  (:export :<abc>
    :abc))
DEF> (slot-value wrk 'abc)
"111"
DEF>

 EIEIOで動いていていたのはpackageがないからか……。
 でもslot-nameなんてばりばり競合してしまうでaccessorをexportするのが、吉なんだろうな……。accessorならmethodなので同じ名前が存在しても競合する可能性はきわめて低いから。

2018年7月7日土曜日

git clone

 Beelink S1とMacBook Airとのソースの同期はどうしよう。
 一発目は単純にscpしたけれど、これから色々とめんどうな予感がする。rsync?
 ああ、そうか。どうせMacBook Airのソースはgitで管理しよう、と思っていたんだった。それならBeeLink S1からgit cloneしてやれば、いいのか。

2018年7月6日金曜日

いろいろあかんようになっていた

 さすがに半年以上も放っておくと、色々と壊れてしまうもので。
 アクションカメラでウィンドの動画を撮影していたはずなのに、MicroSDカード壊れていて何も撮影されてなかった。そのうえ、GPSロガーとして使用していたiPhoneのアプリ——ZweiteGPSも以前と使い方が若干、変更されていてセイリング中だけではなく、検見川浜をうろうろしていた時までロギングされてしまった。
 そのログをgpsbabelに喰わせようとしたらgpsbabelが動かない。何? QTのライブラリが見当たらん、とは。そんな子だっけ、きみは。
 さらに自分がつくったelispプログラムの使い方もすっかり忘れていた。
 なんとか、そのあたりを解消したけれど、今度はVikingが動かない……。
 元々、ソースを持ってきてMacBook Airで強引にコンパイルしたものだ。すったもんだしたあげく、リンクしているX関係のライブラリがなくなっているのがわかった。それをなんとか、誤魔化して動くようにしたのだけれど——。
 地図が表示されない。エラー出まくり。
 しかたないので最新版をgit cloneしてきてまた、コンパイル。あれ? 最新版のはずなのにバージョンが1.6だ。嫌な予感。動かしてみると。
 やはり地図が表示されない……。虚しい……。

 OpenStreetMapのデータを取得できなくなっているような感じだ。APIのインターフェースがかわったとか、そんなところかもしれない。ソースをいじる気力はなく、ほかの使えそうなソフトを探す。

 TrailNote:

 登山用のためか、高度のデータの表示はできるけれど、あいにく速度表示はだめっぽい。

 JOSM:

 まぁ、これかな……。
 OpenStreetMapがらみのソフトで最初はこれでいい、と思っていたのだけど、javaをインスールしなければ、ならないので躊躇してしまった。javaをいれたら負け。そんな気持ち。でも背に腹は変えられず、インストールした。悪くはないのだけど、GPSエディタではなく、どうやら地図編集ソフトというべきものだった。
 それにしても画像出力の機能がないことには1頭を抱えてしまった。
 そのあたりはスクリーンキャプチャを使うことで解決したけれど。

Footnotes:

1

プラグインを探せば、あるかもしれないけれど、見つけ切れなかった。

2018年7月5日木曜日

2018年7月1日(日):検見川浜:晴れ

Sail:CORE 5.7(NEIL PRYDE) Board:NG ACP 260 Fin:9.5inch

No 時刻 時間 帆走距離 最高速 平均時速 P%
1R 15:33-16:14 41分 5.6km 32.32km/h 8.03km/h 21.39
2R 16:26-16:46 20分 3.7km 36.81km/h 10.91km/h 32.16
3R 16:58-17:47 49分 4.6km 33.21km/h 5.56km/h 9.53

total 111分 13.8km 7.4km/h

 ウィンドへ行くというのは一日がかりの作業だ。
 朝早くから起きだして車を運転して海、あるいは湖へ——それでも確実に風に当たるとはかぎらない。午後から行ければ、ヤボ用を午前中に済ませることができる。
 距離的に考えて検見川浜ならそれが可能ではないか。
 梅雨明け一週間で土曜と同じくらい吹きそうな日曜だった。筋肉疲労で鬱な気分だったけれど、昼すぎに車を出した。やはり疲れていたのだろう。駐車場が満車になる可能性はまったく頭に浮かばなかった。
 ——「満」
 ありゃあ、そうだよなぁ。
 空きができたら移動しようと、近くにある無料駐車場にいれたけれど、こちらは四時半まで。あまりにも中途半端。空きができたらと思う以前に次々に車がきてしまっている。で、見ていると、それらの車は十分ほどで入場しているじゃないか。
 しまった。
 それが正しい選択だったか。
 あわてて列の後ろに並びなおす。なのにそんなときにかぎってなかなか空きができない。何をやっておるのだ、おれは。来たときにそのまま、我慢していれば、OKだったのに。
 それでもなんとか、入ることができた。
 五時ぐらいには風がなくなる予報だったけれど、昨日よりも風はあった。
 なんとかプレーニングするぐらい。
 しかし、ポート側がむちゃくちゃへたくそになっていてちっともプレーニングに入れなかった……。身体で覚えたことは忘れないなんて絶対、嘘だ……。

2018年7月4日水曜日

2018年6月30日(土):検見川浜:晴れ

1 Sail:CORE 5.7(NEIL PRYDE) Board:NG ACP 260 Fin:9.5inch

No 時刻 時間 帆走距離 最高速 平均時速 P%
1R 11:05-11:27 21分 1.8km 14.07km/h 5.09km/h 0.00
2R 12:17-13:11 53分 2.8km 23.95km/h 3.13km/h 0.71
3R 14:39-15:05 25分 1.2km 20.20km/h 2.89km/h 0.78
4R 15:14-17:07 112分 8.4km 32.91km/h 4.45km/h 6.58

total 212分 14.2km 4.0km/h

 去年の今頃の検見川浜はとても臭かった
 赤潮が発生していて凄まじい生臭さで思わず、Uターンした。吹いていたのに。原因は急激な気温上昇だとか、なんとか。
 もしかしたら今年も同じパターンか。
 どきどきしながら赴いてみると、そんなことはなった。ただひたすら暑い。風はけっこう吹いているように見えた。午後になってから吹くと踏んでいたのだけれど。
 今年初である。
 気持ちはとても後ろ向きだった。何しろ、去年の最後にひどい目にあった場所なのだ——また、同じ目にあったらどうしよう。
 うだうだとセッティングして海へ出た。
 思ったよりも吹いていない。ノープレーニング。そして。去年ひどい目にあったエリアで沈。そのまま、風が足りず、ウォーターもできず。このまま、ブロックへ押し流されたら悪夢ふたたびだ。
 そうなったらおれは泣く。絶対、泣く。
 なんとか、ウォーターできて無事、帰着できた。
 吹いていそうで吹いていない日だった。
 風、来た来た、ずるずるぽっちゃんのくりかえし。
 引き潮が終われば、吹くのではないか。そう思っていたけれど、あまり風は上がらず。なんとかスタボーでうねりにあわせてプレーニングしたくらいだった。
 初回はこんなものか。
 それにしてもまぁ、身体が動かなかったことよ。

2018年7月3日火曜日

Lispには代入文がないんだね

 ふと気づいた。
 そういえば、Lispには代入という概念がないな、と。
 C言語にしろ、javaとかにしろ「=」で変数に値を代入する代入文の記法が存在する。シェルスクリプトにすら、ある。
 それなのにLispにはそういう記法がない。見たことがないだけかもしれないけど——もちろん変数への値の設定する方法としてset系の関数がある。でもそれはあくまでも関数であって、文法で定義されているわけじゃない。
 そもそも変数への値の代入なんて存在しないんじゃないのか?
 あ、そうか。
 シンボルへの値の束縛(bind)ってそういうことか。シンボルに値を紐づけることがLispでの変数への値の設定なのか。なんとなく、C言語のポインタと値の関係が逆転しているような感じだ。
 へー。
 道理で束縛、束縛とマニュアルにでてくるわけだ。

2018年7月1日日曜日

emacs -daemon

 sshで動かしているプログラムはターミナルを閉じると、中断してしまう。これをなんとか、動いたままにできないものか——やり方はいろいろ、あるのだろうが1、今はとりあえず、emacs -daemonをつかっている。

  1. sshでログイン
  2. emacs -daemonでemacsを起動
  3. emacsclientでemacsに接続
  4. emacsでプログラムを動かす
  5. emacsclientを閉じる

 これでemacsの中でプログラムは動いているのでターミナルを閉じてもだいじょうぶ2。そのあと、再度、emacsclientで接続しなおすこともできる。emacs自身に重い処理をさせていると、5.の段階で反応しなくなるけど。
 このときもターミナルを閉じても死ぬのはemacsclientだけだろうからプログラムは実行され続けているんじゃなかろうか……。
 試してないけど。

Footnotes:

1

昔はatコマンドを有効にして時間起動していた。

2

すくなくともslimeで動かしていたlispはだいじょうぶだった。

2018年6月29日金曜日

なんとEmacsが使える!

 重い処理をSLIMEからCommonLispをやらせていてちょっと感動した。
 なんとEmacsが使えるのだ1
 elispにやらせていたときはなーんもできんようになっていたのに。処理自体も全然、速いし。これからはelispではなく、CommonLispを使うようになるかも。

Footnotes:

1

よくよく考えたら当たり前

2018年6月27日水曜日

とりあえず、データ変換

 とりあえず、データを加工してごっそり変換するプログラムをつくった。
 DBに格納しておいてそれをあとで利用しようというわけ。
 ところが変換中、元々残りわずかだったMacBookAirのディスクスペースが満杯になってしまった。あわてて中断したけれど、いかんじゃないか、これは。
 まいった。
 あれだな、これはPostgreSQLを別のパソコンに持っていくのが吉か。
 そう思って全然、使っていないBeelink S1のUbuntuにPostgreSQLをインストールした。psqlも。基本になるデータをpg_dumpでつっこんでリモートアクセスできるように設定して。
 動かした。
 MacBookAirのCommonLispから。20年分近いデータだ。時間がかかるだろうなぁ、と思っていたらBeelink S1が固まった——固まったと思った。terminalが反応しなくなったのだ。
 これだから安物は。
 熱暴走か——Beelink S1は熱が溜りやすいとか、なんとかいう噂を耳にしていたのだ。たしかに筐体は熱くなっていた。けれど、何度か、試してみているうちに、原因はBeelink S1ではないことに気づいた。
 topコマンドでみると、「kswapd0」というプロセスで固まっている——ように見える。「kswapd0」とはなんぞ。ググってみてページングプロセスらしいことがわかる。そうやってtopコマンドの出力を見直してみると、たしかにswapメモリが0になっていた。Linuxのせいかよ!
 いやこんなに簡単に固まるようじゃ、世間様が使うわけはない1
 固まっているように見えるが、実は非常にレスポンスが悪くなっているだけで——何もできないけど。もしかしたら自分のせいじゃね?
 組んだプログラムが悪いんじゃね?
 でも。
 毎回、commitするようにしても固まるし。
 毎回、connectしなおすようにしたらsocketを取得できなくなってCommonLisp側がハングアップしてしまうし。
 あかんじゃないか。
 そりゃあ、プログラムを動かさなければ、固まらないさ。それじゃ、意味がない。swapを拡張しても1年分ほどで固まっているから問題の解決にはならんだろうし。

 たぶん状況から考えてリモート接続していると、PostgreSQLがメモリを食い潰しているのだろう(ローカルで動かしたpg_dumpはうまくいっているのだから)。そこでUbuntuにCommonLispの環境をつくってローカル接続からデータ変換するようにしたところ。
 うまくいった。
 swapメモリはまったく消費せずに2

Footnotes:

1

一瞬、FreeBSDをインストールしなおそうか、とは思ったけど。

2

腹立たしいことにそのあと、MacBookAirに変換したデータをつっこんでもディスクが満杯になるようなことはなかった。

2018年6月25日月曜日

カッコがあるからいいんじゃないか

 Lispでプログラミングしていると、粘土をこねているような感覚がある。
 ぐにゅぐにゅと、つくったものをくっつけたり、ちぎったりしているような感覚。ほかの言語ではそんなことはないのでおそらく、Lisp系の言語に固有な感じなのだろう——不思議なことにElispよりCommonLispの方がその感覚が強い。CommonLisp特有の機能を使っているわけじゃないのに。気持ちの問題かな?
 ほかのプログラム言語はもうすこし不自由な感じで——こねられない(感覚としていは切り貼りしているような感じ。粘土より硬い)——、何でだろう、とずっと疑問だった。
 もしかしたらそれはS式のおかげではないか?
 Lispが嫌われる大きな理由のひとつ。あのカッコだらけの姿。
 はじめてLispのプログラムを見たときはのけぞったあのカッコ。こんな言語、わけがわからん、と思ったのだけれど。

 これはぼくだけのことなのかもしれないけど、プログラムを組むとき、トップダウンに上から単純に組んでいくわけじゃない。かといってボトムアップともかぎらず、いきなり真ん中ということも多い。
 これは形が見えているところから組むからだろう。——重要なのは組んでみると、まちがいに気づくことが多々あるということだ。
 この形はよろしくない。
 で、プログラムをこねる。
 よくやるのがロジックを外出しすることだ。同じロジックを組みはじめると、イラッとする。それで共通関数にくくりだす。
 これがLispだと楽にできる。
 だってすでにカッコでくくられているから。Ctrl-Meta-kでkillしてyankするだけ。ほかの言語だと、行レベルでの範囲選択になるので範囲指定に頭を使うし、ちょっとほかの部分とまじっていたりしてひと手間かかる。もちろんLispの場合でもロジックがまじってしまっていることはあるけど、概ねだいじょうぶ。たぶんロジックがカッコでくくられているからだろう。まじっていない部分のみを取り出すのは容易だ。
 逆に、これは細かくしすぎた、と思ったときはカッコごと、ほかのカッコの中に移動させて、まぜる。

 こうやって考えると、LispがS式であることは重要。

2018年6月23日土曜日

HyperSpecをローカルで

 hyperspecのデータをどこぞからもってきてローカルの保存して「common-lisp-hyperspec-root」に場所を定義すれば、よいらしい。

common-lisp-hyperspec-root is a variable defined in ‘hyperspec.el’.
Its value is "http://www.lispworks.com/reference/HyperSpec/"

Documentation:
The root of the Common Lisp HyperSpec URL.
If you copy the HyperSpec to your local system, set this variable to
something like "file://usr/local/doc/HyperSpec/".

 となっていたのだけれど、ewwだと「file://usr/local/doc/HyperSpec/」にしていると、うまくいかなかった。ftpで接続へ行ってしまう。
 なので色々、試した結果。

"file:/usr/local/doc/HyperSpec/"

 「//」を「/」にした。

2018年6月21日木曜日

packageふたたび

 ソースを見ると、cl-dbiはdbiというpackageだった。

(defpackage dbi
  (:use :cl
 :dbi.error)
  (:nicknames :cl-dbi)
  (:import-from :dbi.driver
  :list-all-drivers
CL-USER> (cl-dbi::select "123")

; in: DBI::SELECT "123"
;     (DBI::SELECT "123")
; 
; caught STYLE-WARNING:
;   undefined function: DBI::SELECT
; 
; compilation unit finished
;   Undefined function:
;     DBI::SELECT
;   caught 1 STYLE-WARNING condition
; Evaluation aborted on #<UNDEFINED-FUNCTION SELECT {10065F6893}>.

 それに気づかずに、自分もdbiというpackageにしたら。

CL-USER> (defpackage dbi
  (:use :cl
 :cl-dbi)
  (:nicknames :keiba-dbi))

(in-package :keiba-dbi)

(defun select(sql)
  sql)
WARNING: DBI also uses the following packages:
  (DBI.ERROR)

【割愛】

  The ANSI Standard, Macro DEFPACKAGE
  The SBCL Manual, Variable *ON-PACKAGE-VARIANCE*
SELECT

 cl-cbiにselectが定義されてしまった。

DBI> (cl-dbi::select "123")
"123"
DBI>

 うわっ。
 これってcl-dbiを拡張してしまったってこと?1

 関数とか、conflictしたらどうするのよ、CommonLispって変、と一瞬、思ったのだけど2、よくよく考えたらC言語とかでも関数名がかぶったら片方が有効になるだけだった。
 そう思うと、javaの、あのディレクトリ構成にマップされた命名規則はconflictを避けるためのものなんだなぁ、といまさらながら。3

Footnotes:

1

プロンプトを見ると、何が起きたか、一目瞭然だった。

2

なんとなく、Lispってレキシカルって思った。

3

完全に避けることは不可能だろうけど。

2018年6月19日火曜日

ふぉー、まっと

 sql文を組み立てるため、formatを使った。
 CommonLispのformatは全然、ちがうというのは知っていたのだけれど、まぁ、「~S」が文字列だろう、と簡単に考えたら全然、ちがっていた。

CL-USER> (format t "あああ~Sかかか" "ABC")
あああ"ABC"かかか
NIL

 まさか「"」付きになるとは。

CL-USER> (format t "あああ~Aかかか" "ABC")
あああABCかかか
NIL

 「~A」か。
 しかも第一引数で出力先を指定している。nilでは標準出力になる。tで変数へ出力できる。まるでprintf()とsprintf()みたいだ。でもformatの構文は全然、ちがう。

2018年6月17日日曜日

あっ、ぷらい

 cl-dbiで返ってきたデータにはめんくらってしまったのだけど
 こんなデータ。

(:|date| 3281472000 :|place| "A7")

 DBのカラム名と値が交互にならんでいる。
 きっと何か、うまくやる方法があるんだとは思っていた。値をひっぱりだすのにgetfを使うというのは了解した。

CL-USER> (setq wrk '(:|date| 3281472000 :|place| "A7"))
(:|date| 3281472000 :|place| "A7")
CL-USER> wrk
(:|date| 3281472000 :|place| "A7")
CL-USER> (getf wrk :|date|)
3281472000

 きっとkeyとしても使えるにちがいない。それがよくわからなかった。applyかな、とは思っていたのだけど、うまく動かない。

CL-USER> (defclass <wrk> ()
    ((date :initarg :date)
     (place :initarg :place)))

#<STANDARD-CLASS COMMON-LISP-USER::<WRK>>
CL-USER> (apply #'make-instance '<wrk> wrk)
; Evaluation aborted on #<SB-PCL::INITARG-ERROR {10048A9723}>.
CL-USER>

 ふと気づく。

CL-USER> (defclass <wrk> ()
    ((date :initarg :|date|)
     (place :initarg :|place|)))

#<STANDARD-CLASS COMMON-LISP-USER::<WRK>>
CL-USER> (apply #'make-instance '<wrk> wrk)
#<<WRK> {1004641BE3}>
CL-USER>

 そっか。
 defclassの定義で「:date」としていたのが、まちがいだったのだ。
 CommonLispのsymbol名は基本、大文字小文字の区別がないのだけれど、「|」付の場合は区別しているという意味だった(それは一応は知っていた)。「|」付で定義すると、区別あり、と定義できるのだった(これには気づいてなかった)。DBのカラム名は普通、大文字小文字の区別があるのでこうなっているのだろう。

 これでcl-dbiからの返却値を一気にクラスに流しこむことができる。
 この「apply」を使うやり方に気づいてから一気にコード量が減った。ちまちまと値を設定しているところがごっそりなくなったので。
 applyって凄い1

 それにしても「:」付のsymbolってどうやってつくるんだろう?
 単純にinternしてもだめなんだよなぁ。

CL-USER> (intern "date")
|date|
:INTERNAL
CL-USER>

Footnotes:

1

いや、listが凄いのかも。

2018年6月16日土曜日

defclass

 データのかたまりはやはりstructか、classにした方がいいよな。
 EIEIOを使ったのときはクラスを定義した。
 あれが丸々、使えるんじゃね?
 そう思ってコピったところ、エラーになる。しかもdefclassのところ。何でよ。同じじゃないの。目を皿にしてようやく気づいた。EIEIOでは「:docment」だけど、CLOSでは「:documentation」だ……。

2018年6月15日金曜日

cl-project

 「~/.roswell/」の下をつらつら見ていると、「local-projects」というフォルダがあった。二カ所。

~/.roswell/local-projects/
~/.roswell/lisp/quicklisp/local-projects/

 ああ、ここの下に自分がつくりたいプログラムをいれておけば、いいんだな、と見当をつけてとりあえず、「cl-project」でprojectを作成した。

CL-USER> (cl-project:make-project #p"~/.roswell/local-projects/keiba/"
  :author 名前
  :email メールアドレス
  :license ライセンス
  :depends-on '(:cl-dbi :cl-ppcre))
writing ~/.roswell/local-projects/keiba/keiba.asd
writing ~/.roswell/local-projects/keiba/keiba-test.asd
writing ~/.roswell/local-projects/keiba/README.org
writing ~/.roswell/local-projects/keiba/README.markdown
writing ~/.roswell/local-projects/keiba/.gitignore
writing ~/.roswell/local-projects/keiba/src/keiba.lisp
writing ~/.roswell/local-projects/keiba/t/keiba.lisp
T

 (asdf:load-system :keiba)でsystemをロードすると、cl-dbiもロードされる模様。ふむ。なるほど。

CL-USER> (asdf:load-system :keiba)

; compiling file "/Users/yamada/.roswell/local-projects/keiba/src/keiba.lisp" (written 10 JUN 2018 09:29:31 AM):
; compiling (IN-PACKAGE :CL-USER)
; compiling (DEFPACKAGE KEIBA ...)
; compiling (IN-PACKAGE :KEIBA)

; /Users/yamada/.cache/common-lisp/sbcl-1.3.11-macosx-x64/Users/yamada/.roswell/local-projects/keiba/src/keiba-TMP.fasl written
; compilation finished in 0:00:00.005
T

 (ros::load-system "keiba")でも同じみたいだ。
 わからないのは

CL-USER> asdf:*central-registry*
(#P"/Users/yamada/.roswell/lisp/quicklisp/quicklisp/")

 なのに、#p"~/.roswell/local-projects/keiba/"をasdfが認識していること。qlが下記のようになっているのでRoswellはわからなくもないけど。

CL-USER> ql:*local-project-directories*
(#P"/Users/yamada/.roswell/local-projects/"
 #P"/Users/yamada/.roswell/lisp/quicklisp/local-projects/")

 不思議。

2018年6月13日水曜日

環境

 当たり前の話だけれど、REPLを立ち上げなおしたら1今までの作業がきれいさっぱり消えてしまった。あらためてちまちまとloadしなおさなければ、いけないとは思えず、たとえば、Emacsでいえば、load-pathみたいな仕組みがどこかにあるんじゃなかろうか?
 どうやらASDFとか、quicklispとかがその仕組みらしいのだけれど。

require, ASDF, quicklispを正しく使う

第6回 Common Lispライブラリを書く

 上記以外にもあちらこちらのサイトを読んで考えこんでしまった。なんか、情報が錯綜している。頭の中がごちゃごちゃになってしまった。defsystemってなんぞ2。そこで「SBCL」とか、「asdf」のinfoを読みなおしながら自分の環境のパス構成を確認。なんか、おかしい。
 「~/.sbclrc」とか、「~/common-lisp/」とか、見当たらない。
 それを作成して設定すれば、いいのか? でもなんか、根本で道を誤っているような気がする。
 あっ。
 思い出した。
 下記のサイトを見てRoswellを使ってsetupしたんだった。

Common Lispとリアル・ワールドを繋ぐ「Roswell」の紹介

 ということはそもそもRoswellを調べなきゃ、いかんのと、ちゃう3

Footnotes:

1

(slime-restart-inferior-lisp)

2

asdfが提供している何かですかね

3

manがあった。

2018年6月11日月曜日

plistなんて知らんがな

 それにしてもcl-dbiで返ってきたデータにはめんくらった。
 こんな感じのlistになっていたからだ。

(:|date| 3281472000 :|place| "A7" :|count| 3 :|day| 7 :|raceno| 1 :|umano| 1 :|name| "アドマイヤマドンナ" :|sex| "牝" :|age| 2 :|time| 1137/10 :|umaorder| 13 :|odds| 502/5 :|ninki| 13 :|stable| "南井 克巳" :|weight| 54 :|forecast| :NULL)

 中身のことは別にどうでもいい1
 「:|date|」の部分はテーブルのカラム名なのだろう、ということはわかるけれど、「:」と「|」には何か、意味があるのか? そもそもこんな形式で? mapcarで舐めてdateの次のものを値とあつかうなんて面倒じゃないか?
 たとえば、pg.elだと((data . 3281472000)(place . "A7")….)みたいな感じで返却されてきていた。alistというらしいが、これならassoc2で簡単に値を求めることができる。それがなんでまたこんな形式に?
 alistに変換する関数を書くか、と考えながらあちらこちら調べていたらgetf? 何、それ? おいしいの?
 返却されてきたlistは実はplistというものらしい。
 (getf list :|date|)
 で、値を求めることができた。
 getfは素のelispにはなく、cl.elに定義されていた。

 でも「:」と「|」の謎は解けていないのだった。

すこしわかった

Footnotes:

1

競馬のデータだ。

2

(nth 1 (assoc 'date list))みたいな感じで。

2018年6月9日土曜日

packageってなんぞ

 とりあえず、昔、インストールしておいたSLIMEでREPLは立ち上がる。

 まず、CommonLispからDBアクセスはどうしたらよいのか。
 対象はPostgreSQL。ググったら「CommonLispとRaspberryPiでデータベース~その1~」がひっかかった。つらつら。なるほど「cl-dbi1というものがあるらしい。
 さっそく例題にしたがってやってみる。
 あっさりとデータが返ってきた2
 へえ。
 コードをながめる。

;; Quicklispで「cl-dbi」をロード
(ql:quickload :cl-dbi)

;; パッケージ定義
(defpackage psql-package
(:use :cl

:cl-dbi))

;; パッケージに入る
(in-package :psql-package)

;; データベースへ接続
(defvar connection
(dbi:connect :postgres

:database-name "test"

:username "nobody"

:password "1234"))

;; クエリを実行
(let* ((query (dbi:prepare connection "SELECT * FROM hello"))
(result (dbi:execute query)))
(loop for row = (dbi:fetch result)
while row
do (format t "~A~%" row)))

 ——packageってなんぞ?
 いや、そういうものがあるらしいということは知っていたけど、腑に落ちてはいなかった。「in-package」があるってことは「out-package」もあるのか?3
 elispにはそんなものないし。
 ここでようやく気づく。
 思ったより敷居が高いぞ、CommonLisp。
 オライリー本が必要だ。でもM.D. ConradBarsk「Land of Lisp」ぐらいしか、ないよなぁ。そういえば、ポール・グレアムの「ANSI CommonLisp」をもっていたっけ。package。package。ふむふむ。よくわからん。でもなんとなく、わかった。
 やってみたところ、packageの中にpackageをつくるようなことはできないようだった4。平面にぼこぼこと溜池があるようなイメージかな。「in-package」というより「change-package」?

 いずれにしても1ファイル1パッケージにした方がよさそうだ。

Footnotes:

1

作者は日本人でLispハッカーとして有名な人だった。

2

その直後、pg.elが動かなくなっていることに気づいてあひょひょひょ〜、となった。

3

なかった。

4
CL-USER> (defpackage abc
       (:use :cl))
#<PACKAGE "ABC">

CL-USER> (in-package :abc)
#<PACKAGE "ABC">

ABC> (defpackage def
  (:use :cl))
#<PACKAGE "DEF">

ABC> (in-package :def)
#<PACKAGE "DEF">

DEF> (defun wrk() 999)
WRK

DEF> (in-package :cl-user)
#<PACKAGE "COMMON-LISP-USER">

CL-USER> (def::wrk)
999

CL-USER> (abc::def::wrk)
; Evaluation aborted on #<SB-INT:SIMPLE-READER-ERROR "too many colons in ~S" {1005C4D243}>.
CL-USER>

2018年6月7日木曜日

CommonLispはじめました

 というわけで、何年も前にインストールしていたCommonLispを使いはじめた。EmacsのSLIMEからちょこちょこいじってみたのだけど、ショックなことにslime-autodoc-modeがオンになっていると、空白キーがコンフリクトしてしまってSKKで漢字変換ができない。ひらがなは入力できるけど。
 local-set-keyで両方を呼ぶような関数をでっちあげて空白キーに割り当てただけど、どういうわけか、いつのまにか、slime-autodoc-spaceに上書きされてしまう。
 うーむ。

2018年6月5日火曜日

pg.elが動かなくなってしまった……

 まったくの出来心からMacBook AirのEmacsをバージョンアップしてしまった。Emacs24からEmacs25へ。いつものなら動かなくなってしまうのが嫌で極力、バージョンアップはしないようにしているのだが。パソコンを買い替えるタイミングで最新にするようにしていた。
 ついでに、と思ってHomwbrewをupgradeしたのが、そもそもまちがい。
 EmacsもPostgreSQLも何もかも動かなくなってしまった。Homebrewのパッケージのぼろぼろになってしまい、リカバリーするのに何日もかかってしまう——いっそ、TimeMachineで元に戻してしまおうか、と思ったくらい。
 ようやく元にもどった、と安心したのだが、EmacsからPostgreSQLへアクセスできなくなっていることが判明。pg.elからPostgreSQL10へのアクセスがプロトコルの問題でできなっていた。pg.elのバージョンアップは止まったまま……。
 はまった。
 PostgreSQLのデグレーションにも失敗し。
 かっとなって。
 psqlを起動してPostgreSQLのデータを取得する関数をつくる。

2018年6月2日土曜日

VNC for Ubuntu

 Ubuntuの画面共有にMacから接続できない。
 ディスプレイってけっこう邪魔だからVNC接続できるようにしておきたいんだが。——MacのVNCもだめだし、TigerVNCもだめで、RealVNCからもだめ。RaspberryPiへは接続できるんだからVNCサーバを同じものにしてやれば、いいか、と思ってふと思う。そもそも、UbuntuのVNCサーバって何?

dpkg -l

 で、見てみたら「Vino」とかいうやつだった。
 それでググってみたら理由がわかった。デフォルトでは暗号化して通信しているらしい。解決策も判明。

gsettings set org.gnome.Vino require-encryption false

 無事、Macの「サーバへ接続」から接続可能になった。

 ところが、Beelink S1で画面が開いていないと、VNCの画面は真っ暗なのだった……。やはりVNCサーバを切り替えるしかないみたいだ、結局。

2018年5月30日水曜日

RSSリーダー、ふたたび

 Firefoxで使えるRSSリーダーであるSageの記事のサマリー表示がされなくなってしまった。
 もともとFirefoxがメジャーアップデートしてSageが使えなくなっていたのだけれど、古いFirefoxを使いつづけていたのだ。なんか、制限がかけられてしまったのだろう。
 一時期、GnusでRSSを読んでいたこともあったけれど、Sageの快適さにはかなわなかった。サマリー表示が便利だったのだ。
 どうしてだか、GnusでRSSの更新がおそかったということもある。
 RSSなんてもうオワコンか、とも思ったけれど、次のRSSリーダーはどうしよう。
 どのアプリもピンとこないし、Gnusは遅い。そこでEmacsで動くRSSリーダーである「Newsticker」を試してみたのだが、これも更新が遅い。見ていると、blogspotでじっと待ってしまっている。なんだ? Emacs25ではGnusがTime outで落ちるぞ。
 Sageではそんなことはないのだが。
 原因はEmacs?
 いろいろやってふと思ってwgetで試してみた。

 やっぱり遅い。time outが起きている。blogspotのせい? よくよくwgetの出力を見ていたら記事がダウンロードされていた。あれ? time outしたのに?
 だいいたDNSのアドレス解決でIPアドレスの前にあるわけのわからん数値はなんだ……あっ、これ、ipv6が返却されてきているのか!
 そうか。ipv6でアクセスしにいってtime outしたあとにあらためてipv4でアクセスしなおしているんだ。
 それなら最初からipv4でアクセスするようにすれば、いいんだ、と思ったけれど、EmacsのURLパッケージに指定する方法を見つけ切れなかった。ググったり、考えたり、推理したりして答えを見つけた。
 MacOSはデフォルトでipv6からアクセスするようになっていたのだった。
 つまりMacBook Airのipv6を無効にすれば、よいのだった。

sudo networksetup -setv6off Wi-Fi

 結果、GnusもNewstickerの更新が馬鹿っ速くなった。

後日譚:といいながらSageをインストールしなおしたら動いてしまった。

2018年5月28日月曜日

2018年5月26日土曜日

置き場

 小さいというのも置き場にこまるもので、しかたないので画鋲で壁に貼りつけた。

2018年5月21日月曜日

Beelink S1

 週末にキーボードが届いたので「Beelink S1」の初期設定作業。
 Windows10。うーむ、見慣れん。

 次にあまっている128GのSSDにLinux系のCentOSをインストールを試みる。

 「Beelink S1」はOSがLinuxのものがあるので——日本ではWindows10のみの販売——、Linuxは動くだろうと踏んだのだ1
 ところがうまくインストールできない。FreeBSDも同じ。半日かけてあきらめる。「Beelink S1」のLinuxはたしか、Ubuntuだったことを思い出してそちらでインストールを試みてみると、こちらはあっさりとうまくいった。

 でもまぁ、今のところ、「Beelink S1」は使い道がないなぁ。

Footnotes:

1

 BIOSの設定画面の出し方がわからず、右往左往してしまった。結局、Escキーか、Delキーの押しっぱなしだった。