【GNU】Emacs Lisp 【Elisp】
if とか and って special form だとおもうんだけれど、これ無しの普通の関数のみで条件によって実行するしないを含むようなプログラムって書ける? haskell みたいに、遅延評価を行えば可能らしいけれど。 聞く場所間違ってたらすまん >>183 リストとして渡して内部でeval すりゃいいんでないの。 (defun xwhen (pred body) (when pred (eval body)) 関数だと引数は全部実行というか評価されてしまうが、 マクロでなんとでもなる (defmacro myif (pred good bad) (list 'if pred good bad)) もしくは略記法として (defmacro myif (pred good bad) `(if ,pred ,good ,bad)) とすると、 (myif t (insert "ok") (insert "ng")) と書ける。こうやってS式を返すような関数と同様にmyifを「マクロとして」定義すると、 (myif ...)というフォームはまず最初に「展開」されてから実行される。ここだと (if t (insert "ok") (insert "ng")) と最初から書いてあったのと同じことになって、 nbの部分は実行されないという寸法。これはつまらない例だが。 もうちょっと面白い例だと、 (defmacro awhen (pred &rest body) `(let ((it ,pred)) (when it ,@body))) とすると条件式の結果を本体(body)の中でitとして使えるとか (awhen "hogehoge" (message it)) special formとマクロの違いは組み込みかどうかぐらい。 こんな感じで色々制御構文を作ったり、遅延評価のを実装したりもできるが、 あんまり濫用すると自分でもわからなくなってくる諸刃の剣 長文御免 >>184 when は確かに special form ではなく、マクロなのですが、内部では cond を使っていて、私の望むものではありませんでした。条件があいまいで済みませんでした。 >>185 感覚的には無理なように感じていたのですが、当方あまり lisp や関数型言語に対して俯瞰がなく確証が持てなかったため質問したものでした。 >御二方 理解が深まりました。 ありがとうございます。 special form を使わずに if 実装って elisp では可能なんだろか… macro 使ったとしても結局 if 的なことするためには置き換え先で special form 使うことになるよね。 ID 変わってるかもですが 183 です。 >>186 内部的に特殊形式を利用しているので、申し訳なくも私がもともと期待していたものとは違うのですが、 特殊形式であっても独自拡張可能というのは面白いですね。 私は主に Python や C/C++ の世界に住んでいるので、例えば条件付トレースなど、 可能であれば条件式によって引数を評価せずに処理をしたいときにあきらめてしまうことがあります。 (書かなくてもわかるかとも思いますが) Python の例で言えばこんな感じです。 def conditional_trace(ctrl, msg): if ctrl: print msg return conditional_trace(True, heavy_message_generate()) そもそも Python の世界なんて、コストは大して気にしない場合が多いのですが、 貧乏性でして。あと heavy_message_generate に副作用があったりすると困ります。 こういう意味では C/C++ のプリプロセッサのほうが自由度が高いですね。言語の外にあるだけあって。 条件後出しで申し訳ないです。でも、macro の威力がわかってとても良かったです。ありがとうございます。 ちなみに、when もマクロであって、マクロの展開では評価されないことに依存したものですね。 基礎的な機能であっても、special form をたくさん作るよりはマクロで構文糖衣するということで、これも面白いです。 >>188 そうそう。それです。教えていただいた結果、私の疑問もそれになりました。 true, false ではなく、car, (lambda (x) (car (cdr x))) を渡すことになりますが、 macro を遅延評価代わりに使って、分岐っぽいものが実現できるようです。 (defmacro cdrif (idx good bad) (funcall idx (list good bad))) (cdrif car (insert "ok") (insert "ng")) ok (cdrif (lambda (x) (car (cdr x))) (insert "ok") (insert "ng")) ng あとは、任意の(真偽)値から car, (lambda (x) (car (cdr x))) に変換できれば、 elisp で if を自作できることになるんですかねぇ。 ちょっと自信が無いですが。 (defmacro cdrifx (bool good bad) (funcall (car (cdr (assq bool (list '(t car) '(nil (lambda (x) (car (cdr x)))))))) (list good bad))) cdrifx (cdrifx t (insert "ok") (insert "ng")) ok (cdrifx nil (insert "ok") (insert "ng")) ng assq を使ってしまえば出来ました。(assq は C built-in function.) 仮に lisp のみで assq を実装すると if が必要になるかもしれませんが、 概念的には単なる写像というか単純なマッピング関数なのでありなのかなぁ。 チラ裏になってしまい申し訳ない。 symbol-property-listでの力技を作ってしまおうかと思ったら先を越されてた。 >>189 もとの疑問を離れてその目的ならということだけど、 単純にその重い処理を関数として渡してしまうのがいいのでは。 よくthunkと言われる方法。 (defun conditional-trace (x thunk) (when x (funcall thunk)) としておいて (conditional-trace t (lambda () (heavy-message-generate)) とか (conditional-trace t #'heavy-message-generate) とか。 そのpythonの例でも同様に def conditional_trace(ctrl, func): if ctrl: print func() return conditional_trace(True, lambda:heavy_message_generate()) conditional_trace(True, heavy_message_generate) 遅延評価する言語も中身はこういう感じの実装だったと思う。 C/C++は関数が第一級データ型じゃないので相当面倒になるが、 頑張ればできるはず…(最近のC++にはラムダ式入ったみたいだけど)。 C/C++のプロプロセッサだと動的に条件を変えたくなったら困らない? デバッグオプション付きで走らせた時だけトレースが欲しいとかもできなく なっちゃうし。 あとちょっと複雑なことやろうとすると急速に黒魔術化するイメージがある。 >>191 はーなるほど。assq で判定させるとは考えつかなかった。 おもしろいねえこれ。 最低限組み込みで実装しなきゃいけない部分はどこまでで あとはその組み合わせで自己記述可能になるとかは lisp の教科書読めばわかるのかな。 純Lisp(pure Lisp)ってのだとcond使わざるを得なくなるから特殊形式は使わざるを得ないんじゃないかな >>192 もし、面倒でなければ「symbol-property-listでの力技」っていうのも見てみたいです。 thunk の例示ありがとうございます。python でも高階関数を使わないわけではなく、 lambda で評価を遅延させるようなことも時々はやるのですが、 必要に応じて関数の引数で使うという発想は無かったです。私にとって新しい概念です。 新しい言語を勉強すると、元の言語でも世界が広がる良い例ですね。楽しいです。 C/C++ ですが、最近の C では、可変引数マクロが使えるので、 #define TRACE(cond,...) if(cond){ printf(__VA_ARGS__); } とすることで、引数を制御構造に組替えられます。 http://codepad.org/uX2WaTqT この実現の仕方は elisp での defmacro に近いですね。 C++ の lambda も上手く例が作れれば後程。 >>193 あんまり lisp っぽくないですかね。 Python など、他のパラダイムが強い言語で関数チックに 書こうとすると、写像できるような要素は便利なので良く使います。 ちなみに、JavaScript でよくあるような bool 化 idiom である !! を援用して、 自前 if は最終的に以下のようになりました。 (defmacro macroif (any-symbol good bad) (funcall (car (cdr (assq (null (null any-symbol)) (list '(t car) '(nil (lambda (x) (car (cdr x)))))))) (list good bad))) (cdrifx t (insert "ok") (insert "ng")) ok (cdrifx () (insert "ok") (insert "ng")) ng (cdrifx (list 1 2 3) (insert "ok") (insert "ng")) ok >>195 lisp は関数指向でも書けるけれど、そもそもマルチパラダイムなのが、 その規定の時点から現れているように思えます。 最小要素とするのに、macro による制御構造の書換えと 一箇所で特殊な振舞いをするという cond どっちが最小かと言えば cond のが小さそうです。 >>196 力技というほどのものでもなかった (put t 'cdrif-value #'car) (put nil 'cdrif-value #'cadr) (defun convert (x) (get x 'cdrif-value)) (defmacro my-if (idx good bad) (funcall (convert idx) (list good bad))) いや、本当はさらに (put nil 'convert-value t) (defun to-t-or-nil (x) (not (ignore-errors (get x 'convert-value)))) (defun convert (x) (get (to-t-or-nil x) 'cdrif-value)) とかいう力業っぽいことを考えてたんだけども、 ignore-errors が反則だったと気づいた。 こっちの反則版だとnil以外のどんな値を渡しても ちゃんとt扱いされるという利点はあるけど… C/C++プリプロセッサ、そういうことか。条件付きコンパイルを想像していた。 #define DEBUG(level) if(level>=verbosity){printf(_VA_ARGS_);} みたいなことは一回やったことがある。 完全に文字列として変形するからlevelのところに関数呼び出しのコンマがあると 変なことになるという罠があるが、こういう用途だと大丈夫だしね。 自由度という点では何も考えずに言語全体を使えるlispマクロは特異に高いと思う。 elispじゃなくてcommon lispになっちゃうがland of lispとか読むと楽しいかもしれない。 >>198 なるほど、こっちはプロパティを写像に使うのか いろいろ考えつくもんだなぁ >>198 ありがとうございます。取り急ぎお礼を申し上げ乙。 setqと同等の機能を実現する関数は定義できますか 図書館で毎日ナンパして地下食堂のトイレでマン汁まみれで腰動かすんだよぉ いーまっくすはじめようとしたらしょしんしゃはこれやっとけのところでえらーになったのでもうねます 初心者です 以下の文を電話で伝える場合、どのように話せばよいか教えて下さい。 (assq bool (list '(t car) '(nil (lambda (x) (car (cdr x)))))))) 例: かっこ始まり、えいえすえすくー ぶーーと かっこ始まり・・・・・・・・ みたいな感じでお願いしまつ すみません。前の質問の補足ですが、なんで電話で伝えるかなのですが、 有料サポートで、おぺれーたーのお姉さまから、エラーのでる行を読み上げて下さいと言われたのですが、答えられない事があって、こんどこそ上手く説明しようとおもっています。 全部一文字ずつ読みあげれ 電話で済むことをいちいち不便な掲示板使うな 1分3000円とかかかるなら別だが 電話サポートとかぼったくり以外の何物でもないんじゃ… そもそもエラーの出る行が問題とは限らないし普通はメールかチャットでしょう windows機しか持ってなくて、今までCygwinについてくるvi使ってたんだけど、emacsを使ってみてるんですけど、ターミナル上でemacs使おうと思ったらいちいち-nwオプション付けないといけないんですか?それともみんなターミナルとは別ウィンドウで使ってるんですか? >>220 そんなの人それぞれ。 -nw付けるのが面倒なら、aliasすればいい >>220 cygwinで-nw付けないで実行するならWindows上にX11サーバ立てないと ntemacsとかならWindowsのUI上で実行されるよ。 >>217 elispで有料サポートしてる日本語窓口に興味ある アレグロとかならまだわかるけど >>219 普通はコードの内容の確認までするの? 確か大学生を鴨にしてる有料サポートがあった気がする 普通に指導員(大学院生のバイト)に聞いた方が早いし無料だし正確じゃんと思った覚えがある 10年以上前のものなんですが、seimei.el というfjに流れていたelispを探しています。 どこかに残ってないでしょうか? ご存知の方いらしたら教えて下さい load-historyにFILE-NAMEがnilのエントリーがあるかも、とヘルプにあるんですけど、そのエントリーがどのタイミングでどこから書き込まれてるか教えてください(eval-regionのブレークポイントつけても引っ掛からなかったです)。お願いします >>228-230 過疎スレなのになんか気持ち悪いな。。。 バーカ >>231 よく知らないが、リファレンスマニュアルを見た限りではそこは eval-region じゃないんじゃ……という気がする。 "emacs-lisp" "load-history" でググったらそれらしいのが出てきたよ。 >>233 ありがとうございますマニュアル見直してみたらeval-bufferかもしれないです。もう1回やってみます 僕の知り合いの知り合いができたパソコン一台でお金持ちになれるやり方 役に立つかもしれません グーグルで検索するといいかも『ネットで稼ぐ方法 モニアレフヌノ』 147M7 elispと若干違うけどスレがないので質問させてください C-x C-hとやるとC-xから始まるコマンド一覧はでるのですが モードごとのコマンド一覧を出すコマンドもあったと思うのですが何だか分かる方いますか ruby-modeを入れたのですがどんなコマンドがあるのか調べたいです C-h b あと、メニューバーを見れば基本的なキーバインドは確認できる 消してる場合は C-右クリ emacs 24.5.1を使用しています。 ttp://www.miura-takeshi.com/etc/genkou.el 上記のプラグインを使用してバッファの文字列を原稿用紙換算したいのですが、 モードラインへの表示ができません。 文字列のカウント処理は問題なく動作しているので、下記のモードライン更新処理の 記述に問題があるようなのですが、何が悪いか分かる方いらっしゃいませんでしょうか? (defun genkou-mode-line () "モードラインを書き換える" (let ((tmp-list)) (setq genkou-mode-line-string (format "--%d枚%d行" genkou-page-num genkou-line-num)) (make-local-variable 'mode-line-format) (setq tmp-list (copy-sequence default-mode-line-format)) (setq mode-line-format (append (delete "-%-" tmp-list) (append (list genkou-mode-line-string) (member "-%-" default-mode-line-format)))) (force-mode-line-update))) https://masatoi.github.io/2017/05/11/hy-tutorial M-x hy-mode -> hy-font-lock--kwd->comint-kwd: Invalid function: ((matcher . match-highlights) kwd) サクラエディタの代わりにLinux上で簡易なテキストの正規表現やコピべマンとして ボリュームがvi以上vscode未満ということでEmacs採用したけどまともに使うまでにでもマゾ過ぎないかこれ Emacsってのは、すみずみまでいじり回して遊びたい人のための、組み立てキットみたいなものなんだよ。 改造しやすいってのが最大の売りで、各自で好みに合うように作り変えるのが大前提。 素のままでも一応は使えるけど、そんなに便利には作られてない。 魔改造とかする気がないなら、他に適したエディタがあると思う。 wine使ってサクラエディタが動くから試してみたら? Emacsは何かの代わりに使おうとすると、操作体系が違い過ぎて挫折する 2つ質問します。 1. 選択範囲を削除するけれど、kill-ringに入れないという設定を教えて下さい。 kill-ringの一番新しいものをそのままにしておきたいからです 2. yankした際に、yankされたものの末尾にカーソルが飛ぶのですが、 カーソルが移動しないようにする設定を教えて下さい。 お手数をおかけしますが、お願いします。 >246 1は M-x delete-region シェルスクリプトからemacs ―batch で処理した結果をprintすると \\. \\. \\“ みたいの沢山でてくる エスケープなしで表示された通りの文字列を得るにはどうすれば良いのでしょう princにすると \\, が \, になったのですが , にする方法はないのでしょうか >>252 princ が引数の文字列に含まれていない \ を勝手に印字することはないから、 その「処理」とやらで \ を追加しているのでは または emacs への入力の時点ですでに \ を含んでいるとか >>252 読み込む時にreadしてんじゃないか? Windows の Emacs 日本語入力しようとして 半/全 キー押してしばらくしたら Emacs ウィンドウ全部落ちた バグ? (point) って 4GB 以上のファイルでも安全? >>255 windows 10 64bit emacs 26.3 64bit また再現した emacs 以外も含めて(同時起動中のソフト) windows 10 全体の ime が モードが変になったり勝手に改行されたり狂い始める このまま使い続けるとそのうち emacs が落ちるんだと思う task manager から ctfmon.exe を殺したら治ったっぽい emacs って 8MB 以上のテキストファイルで警告出るω 最近の大きめの xml とか json とか yaml とか怖くて編集出来ないωωω それじゃなにか?きみは「ここから先は18歳以下は閲覧できません」っていう 警告がでたからといって見たいエロ動画も見ずにすごすごと帰る、というそんな腰抜けなのか! Emacs 26.3 (build 1, x86_64-w64-mingw32) of 2019-12-31 漢字キーを押して 「でるた」 で変換始めると 重たくなって しばらくしたら落ちる 日本語入力はもう諦めた 単にコードや英文に記号使いたいならdigraph覚えるのをオススメする \C-c k D *で対応するギリシア文字凾ンたいな dならδ、->で→、数学記号も不足なし あとかなはkaでカナはNaだったり 国際規格があるので覚えとけば汎用性がある (比べる訳じゃないが少なくともvimでは標準機能) (global-set-key (kbd "C-c k") (define-prefix-command 'alistから記号拾ってくる関数 )) 自分用elも転がってたけど網羅的でないかったので、ググって一番に出てくるvimヘルプのテーブルをコピペして整形した melpaに無いと思い込んでたんだけど、今調べたらevilとかいうevilなのが出てきた、多分名前でスルーしてたわ ひらがなかたかなときごうとalphabetのぶんしょうなら、マップがローマ字にゅうりょくとたいおうしているので、いっそdefine-keyしてしまえばじっしつIMEいらずだぞ! 字はうてなかった、かたておち… まあ、げんきかくまではみてないのでもしかしたらかんじもあるかも Bash on windows(Ubuntu)のemacs Windows 10に scoop install emacs した環境 どっちも環境変数homeを見にいくのでciderがどっちかの環境で動いてくれない emacs lispでC++のコメントを削除(行コメント//だけを行ごと削除)する方法を教えてください (defun comment-traversal (beg end func) (save-excursion (let (spt ept) (goto-char beg) (while (and (< (point) end) (setq spt (comment-search-forward end t))) (setq ept (progn (goto-char spt) (unless (or (comment-forward) (eobp)) (error "Can't find the comment end")) (point))) (funcall func spt ept))))) (defun not-comment-traversal (beg end func) (save-excursion (let (spt (ept (1- (goto-char beg)))) (while (and (< (point) end) (setq spt (comment-search-forward end t))) (funcall func (1+ ept) spt) (setq ept (progn (goto-char spt) (unless (or (comment-forward) (eobp)) (error "Can't find the comment end")) (point)))) (funcall func ept (min end (1- (point-max))))))) 最初のはコメントを抜き出すコード 次のはコメント以外を抜き出すコード バッファー内のコメントを消していくのは難易度が高い コメント以外を出力してリダイレクトするのが簡単だろう ↓こんな感じ (not-comment-traversal (point-min) (point-max) (lambda (beg end) (print (buffer-substring beg end)))) ちなみにコメントはEmacsが把握してるので、このコードは言語非依存だ そういうつまらないものはchatgptに作らせればいい Emacs Lispのコードなんてまともに学習できないよw うん、だから、ChatGPTはバカだな こんなものに時間をそそいでいる人類はバカ そういうのはキーボードマクロが向いている //をインクリメントサーチして、c-a,c-k,c-k で名前を付けて登録 登録したマクロを10000000回ぐらい実行すればいい read.cgi ver 07.5.1 2024/04/28 Walang Kapalit ★ | Donguri System Team 5ちゃんねる