ハイポリグロット・リズプ:コモンリズプ、ラケット、クロージャ、エマックスリズプ。

2026/05/19 4:27

ハイポリグロット・リズプ:コモンリズプ、ラケット、クロージャ、エマックスリズプ。

RSS: https://news.ycombinator.com/rss

要約

日本語訳:

この参照シートは、Common Lisp、Racket、Clojure、および Emacs Lisp の間での重要な技術的な比較を提供し、具体的なバージョン(SBCL 1.2、Racket 6.1、Clojure 1.6、および Emacs 24.5)に対する検証結果を含んでいます。本書は、これらの関数型方言特有の構文スタイルと実行モデルを巡る開発者のための不可欠なガイド役を果たします。文書は、識別子のケース感受性における主要な違い(Common Lisp のケース不感 versus それ他言語のケース感)、変数バインディング慣習(例えば

defparameter
/
defvar
versus
define
)、および null 値のセマンティクス(Common Lisp、Racket、Emacs では
nil
/
'()
が同義語であるのに対し、Clojure では区別される)について明確にします。また、核心的な演算における重要な変異も詳述されています。これには、アリティミティック論理リテラル(
t
versus
#t
)、浮動小数点除算の扱い、およびファイル I/O パターンが含まれます。この参照は明示的にコンパイル戦略を対比しており、Common Lisp のバイトコードアプローチ versus Racket および Clojure のジャスト・イン・タイム(JIT)または Java ベースの環境について述べています。また、共通リッチにおける末尾呼び出し最適化の可用性があるのと Emacs Lisp にはないという実行モデルの違いも強調しています。エラーハンドリングの実装、マクロシステム、名前空間、およびデータ構造(例えば
cons
/
cdr
アクセッサ versus
first
/
rest
)について特定の実装を調査することで、エンジニアリングチームはマルチ言語スタックを構築する際の互換性課題を評価し、可搬性の高いコードを記述するとともに、変更可能および不変の設計におけるエコシステム固有のトレードオフを理解することを支援します。

本文

ca 並列参照シート

文法と実行 | 変数と式 | 算術と論理 | 文字列 | 正規表現 | 日付と時刻 | リスト | フィクストラム配列 | ダイクト(辞書型)| ユーザー定義型 | 関数 | 実行制御 | エラー処理 | ストリーム | Emacs バッファ | ファイル | ディレクトリ | プロセスと環境 | ライブラリと名前空間 | オブジェクト | Lisp マクロ | リフレクション | Java との連携


Common Lisp / Racket / Clojure / Emacs Lisp

注:以下の各セクションは、左から Common Lisp (SBCL)、Racket、Clojure、Emacs Lisp の順です。

バージョン情報

  • SBCL 1.2
  • Racket 6.1
  • Clojure 1.6
  • Emacs 24.5

表示方法:

  • $ sbcl --version
  • $ racket --version
    • REPL 起動時に表示される
  • $ emacs --version

文法と実行 (Grammar and Execution)

Common LispRacketClojureEmacs Lisp
コンパイラ
$ raco make module.rkt

または
M-x byte-compile-file
スタンドアロン実行ファイル
(sb-ext:save-lisp-and-die "executable" :executable t :toplevel 'function)
または
$ mzc —exe executable file
インタプリタ
$ sbcl --script foo.lisp

$ racket -r foo.racket

Clojure の JAR への完全なパスを指定:
java -cp clojure.jar clojure.main foo.clj
シェbang (Shebang)
#!/usr/bin/env sbcl --script

#!/usr/bin/env racket --script

Clojure の JAR への完全なパスを指定:
#!/usr/bin/env java -jar clojure.jar

Emacs Lisp:
#!/usr/bin/env emacs --script
単語の区切り文字 (Word Separator)
空白のみ
空白とカンマ
空白のみ
空白のみ
改行コメント (End-of-line comment)
(+ 1 1) ; adding
複数行コメント
(+ 1 #| adding #
1)

変数と式 (Variables and Expressions)

Common LispRacketClojureEmacs Lisp
識別子 (Identifier)
大文字小文字不敏感、数字では始まる不可。
除外文字: SP ( ) " , ' ` : ; # | <br>ユーザーマクロ用予約済み:? ! [ ] { }
照合は行われる
識別子
大文字小文字敏感、数字では始まる不可。
除外文字: SP ( ) [ ] { } " , ' ` ; # | <br>照合される
識別子
大文字小文字敏感、数字では始まる不可。
許可文字: A-Z a-z 0-9 * + ! - _ ?
特殊意味/予約: / . :
クォートされた識別子とエスケープ
(setq | white space symbol| 3)
(setq white\ space\ symbol 3)
(define |white space symbol| 3)
(define white\ space\ symbol 3)
なし
なし
(setq white\ space\ symbol 3)
ローカル変数
並列代入:
(let ((x 3) (y 4)) (+ x y))
順次代入:
(let* ((x 3) (y (* x x))) (+ x y))
並列代入:
(let [x 3 y 4] (+ x y))
順次代入:
(let [[x y] [3 4]] (+ x y))
(let [x 3 y (* x x)] (+ x y))
(lexical-let ((x 3) (y 4)) (+ x y))
(lexical-let* ((x 3) (y (* x x))) (+ x y))
グローバル変数
defparameter
*x* 3
defvar
*x* 3
定義済みなら変更しない:
(define x 3)

y はグローバルではない:
(define (double z) (define y 2) (* y z))
def
x 3
set
'x 3
setq
x 3
変数の削除
(makunbound 'x)
(namespace-undefine-variable! 'x)
(ns-unmap ns 'x)
(makunbound 'x)
Nothing (Nil)
nil
'<>()
null
'<>()
(Java と同じ値:
nil
)
null
'<>()
(Java と同じ値)
nil
'<>()
Null チェック
(null x)
(null? x)
(nil? x)
(null x)
(null x)
識別子を値として扱う
'x
(quote x)
'x
(quote x)
'x
(quote x)
識別子テスト
(symbolp 'x)
(symbol? 'x)
(symbol? 'x)
(symbolp 'x)
識別子の等価性テスト
(eq 'x 'x)
(eq? 'x 'x)
(= 'x 'x)
(eq 'x 'x)
参照なし識別子
:foo
#:foo
:foo:foo
識別子の属性
set/get/remove
(set 'x 13)
(setf (get 'x :desc) "unlucky")
(get 'x :desc)
(remprop 'x :desc)
なし
(値は clojure.lang.IObj のインスタンスでなければならない):
(def x (with-meta [13] {:desc "unlucky"}))
(get (meta x) :desc)
なし
(set 'x 13)
(setf (get 'x :desc) "unlucky")
(get 'x :desc)
(remprop 'x :desc)

算術と論理 (Arithmetic and Logic)

Common LispRacketClojureEmacs Lisp
True/False
t
nil
#t
#f
true
false
true
false
偽 (Falsehoods)
nil
'<()>
#f
false
false
nil
nil
'<()>
論理演算子
(or (not t) (and t nil))
(or (not #t) (and #t #f))(or (not true) (and true false))(or (not t) (and t nil))
関係演算子
= /= < > <= >=
= ない < > <= >== not= < > <= >== /= < > <= >=
最小値・最大値
(min 1 2 3)
(max 1 2 3)
(min 1 2 3)
(max 1 2 3)
(min 1 2 3)
(max 1 2 3)
(min 1 2 3)
(max 1 2 3)
数値判定
numberp integerp rationalp floatp realp complexp
number? integer? rational? inexact? real? complex?number? integer? rational? float? なし
なし
numberp integerp なし
floatp なし
なし
算術演算子
+ - * / mod
+ - * / modulo+ - * / mod+ - * / %
整数除算と剰余
(truncate 7 3)
(rem 7 3)
(quotient 7 3)
(remainder 7 3)
(quot 7 3)
(rem 7 3)
(/ 7 3)
(% 7 3)
ゼロ除算エラー
division-by-zero エラー
division by zero エラーarith-error
浮動小数点除算
有理数: (/ 7 3)
浮動小数点: (/ 7 (* 3 1.0))
有理数: (/ 7 3)
浮動小数点: (/ 7 (float 3))
整数商: (/ 7 3)
浮動小数点: (/ 7 (* 3 1.0))
浮動小数点のゼロ除算
division-by-zero エラー
-1.0e+INF, -0.0e+NaN, または 1.0e+INF
累乗 (Power)
(expt 2 32)
(expt 2 32)
浮動小数点を返す: (Math/pow 2 32)
(expt 2 32)
平方根
(sqrt 2)
(sqrt 2)(Math/sqrt 2)(sqrt 2)
sqrt(-1)
#c(0.0 1.0)
0+1i(Math/sqrt -1): NaN-0.0e+NaN
超越関数
exp log sin cos tan asin acos atan cotanh
exp log sin cos tan asin acos atan atanMath/exp ... Math/atan2exp log sin cos tan asin acos atan atan
浮動小数点の丸め処理
2 つの値を返す(1 目は整数): truncate round ceiling floor
浮動小数点を返す: truncate round ceiling floor
整数を返す: int Math/round
浮動小数点を返す: Math/ceil Math/floor
truncate round ceiling floor
fround fceiling ffloor
truncate は整数を返す
絶対値と符号関数
abs signum
abs
Racket: sgn
Math/abs Math/signumabs signum
整数オーバーフロー
なし; 任意精度の整数
なし; 任意精度の整数
clojure.lang.Numbers.throwIntOverflow エクセプション
浮動小数点オーバーフロー
floating-point-overflow エラー
リテラルでは不可: -Infity NaN Infinity
有理数の構築
(/ 3 7)
リテラル: 3/7
(/ 3 7)
リテラル: 3/7
また有理数:
2.718
(exp 1)
(/ 3 7)
リテラル: 3/7
有理数の分解
(numerator 3/7)
(denominator 3/7)
(numerator 3/7)
(denominator 3/7)
なし なし
複素数の構築
#c(1 2)
1+2i
(+ 1 +2i)
なし
なし
複素数の分解
(realpart #c(1 2))
(imagpart #c(1 2))
(phase #c(1 2))
(abs #c(1 2))
(conjugate #c(1 2))
(real-part 1+2i)
(imag-part 1+2i)
(angle 1+2i)
(magnitude 1+2i)
(conjugate 1+2i)
なし
なし
なし
なし
乱数
一様整数、一様浮動小数点、正規分布
(random 100)
(random 1.0)
なし
(random 100)
(random)
(def rnd (java.util.Random.))
(.nextInt rnd 100)
(.nextFloat rnd)
(.nextGaussian rnd)
(random 100)
なし
なし
(random-seed 17)
乱数のシード
(setq random-state (sb-ext:seed-random-state 17))
(random-seed 17)
ビット演算子
ash left shift (2 目の引数が正の場合), logand logior logxor lognot
arithmetic-shift left shift (同上), bitwise-and bitwise-ior bitwise-xor bitwise-notbit-shift-left bit-shift-right bit-and bit-or bit-xor bit-notlsh left shift (同上), logand logior logxor lognot
2 進数、8 進数、16 進数リテラル
#b101010 #o52 #x2a
#b101010 #o52 #x2a
基数 (Radix)
(format nil "~7r" 42)

文字列 (Strings)

Common LispRacketClojureEmacs Lisp
文字列テスト
(stringp "foo")
(string? "foo")(string? "foo")(stringp "foo")
文字列リテラル
"foo bar"
"foo bar""foo bar""foo bar"
リテラル内の改行
はい
はい
はい
はい
リテラルエスケープ
\" \\ \t \n \r \" \\ \ooo \uhhhh
\b \t \n \f \r \" \\ \ooo \uhhhh\b \t \n \f \r \" \\ \ooo \uhhhh \xh - \xhhhhhh \C-x \M-x
コンストラクタ
(string #\f #\o #\o)
(string ?f ?o ?o)
フォーマット文字列
(format nil "~a: ~a ~,2f" "Foo" 7 13.457)
(format "~a ~a ~a" "Foo" 7 13.457)
(String/format "%s: %d %.2f" (to-array ["Foo" 7 13.457]))
(format "%s: %d %.2f" "Foo" 7 13.457)
フォーマット指定子
~a 任意型、人間 readable
~s 任意型、read parseable
~~ タイルダ
c キャラクター
,5f 小数点以下 5 桁
~d 十進数
~x 16 進数
~o 8 進数
~b 2 進数
~a any type, human readable
~s any time, read parseable
~~ tilde
~c character
~d decimal
~x hex
~o octal
~b binary
文字列の比較
(string= "foo" "bar")
(string< "foo" "bar")
(string=? "foo" "bar")
(string<? "foo" "bar")
(.equals "foo" "bar")
(.compareTo "foo" "bar")
(string= "foo" "bar")
(string< "foo" "bar")
文字列の連結
(concatenate 'string "foo " "bar " "bar")
(string-append "foo " "bar " "baz")(str "foo " "bar " "baz")(concat "foo " "bar " "baz")
要素の複製 (Replicate)
(make-string 3 :initial-element #\f)
(make-string 3 #\f)(String. (into-array (. Character TYPE) (repeat 3 \f)))(make-string 3 ?f)
大文字小文字の転換
(string-downcase "FOO")
(string-upcase "foo")
(.toLowerCase "FOO")
(downcase "FOO")
(upcase "foo")
頭文字を大文字に (Capitalize)
; "Foo Bar": (string-capitalize "foo bar")
; "Foo Bar": (capitalize "foo")
不要なスペースの削除 (Trim)
(string-trim '(#\space #\tab #\newline) " foo ")
(require srfi/13/string)
(string-trim-both " foo ")
(.trim " foo ")なし; 実装については注釈を参照
パディング (Pad)
右側、左側
(format nil "~10a" "foo")
(format nil "~10@a" "foo")
数値から文字列へ
(concatenate 'string "value: " (princ-to-string 8))
(string-append "value: " (number->string 8))
(str "Value: " 8)(concat "value: " (number-to-string 8))
文字列から数値へ
(+ 7 (parse-integer "12"))
(+ 73.9 (read-from-string ".037"))
(+ 7 (string->number "12"))
(+ 73.9 (string->number ".037"))
(+ 7 (Integer/parseInt "12"))
(+ 73.9 (Float/parseFloat ".037"))
文字列の分割
(cl-ppcre:split "[ \t\n]+" "foo bar baz")
(regexp-split #rx"[ \n\t]+" "foo bar baz")(seq (.split "foo bar baz" "[ \t\n]+"))(split-string "foo bar baz")
文字列の結合 (Join)
(reduce (lambda (m o) (concatenate 'string m " " o)) '("foo" "bar" "baz"))
(string-join '("foo" "bar" "baz") " ")(reduce #(str %1 " " %2) '("foo" "bar" "baz"))(reduce (lambda (m o) (concat m " " o)) '("foo" "bar" "baz"))
文字列の長さ
(length "foo")
(string-length "foo")
(.length "foo")(length "foo")
部分文字列の検索 (Index)
(search "bar" "foo bar")
Racket: (require srfi/13/string) (string-contains "foo bar" "bar")(.indexOf "foo bar" "bar")(search "bar" "foo bar")
部分文字列の抽出 (Extract)
(subseq "foo bar" 4 7)
(substring "foo bar" 4 7)
(.substring "foo bar" 4 7)(substring "foo bar" 4 7)
キャラクタリテラル
#\a #\space #\newline #\backspace #\tab #\linefeed #\page #\return #\rubout
#\a #\space #\newline #\backspace #\tab #\linefeed #\page #\return #\nul #\vtab #\alarm #\esc #\delete
Racket にない: #\alarm #\esc #\delete
\a \newline \space \backspace \tab ? \formfeed \return ?
キャラクタのテスト
(characterp #\x)
(alpha-char-p #\x)
(alphanumericp #\x)
(digit-char-p #\7)
(lower-case-p #\x)
(upper-case-p #\X)
(char? #\x)
(char? \x)
(characterp ?x)
Chr と Ord
(code-char 97)
(char-code #\a)
(integer->char 97)
(char->integer #\a)
(char 97)
(int \a)
キャラクタ配列への変換
; リスト: (string->list "foo")
キャラクタのアクセス
(char "foo" 0)
(string-ref "foo" 0)
(.charAt "foo" 0)(aref "foo" 0)
正規表現 (Regular Expressions)
Common LispRacketClojureEmacs Lisp
リテラル
文字列を使用: "\b\d{5}\b"
POSIX 拡張: #rx"^[0-9][0-9][0-9][0-9][0-9]$"
(regexp "^[0-9][0-9][0-9][0-9][0-9]$")
Perl スタイル: #px"\b\d{5}\b"
(pregexp "\b\d{5}\b")
#\b\d{5}\b
キャラクタクラスの略号
. \d \D \s \S \w \W
regexp: .
pregexp: . \d \D \s \S \w \W
. \d \D \s \S \w \W
\ca \cl and \cg match ASCII, Latin, and Greek characters.
Character classes of the form \sx depend on the current syntax table.
アンカー
^ $ \b \B
regexp: ^ $
pregexp: ^ $ \b \B
^ $ \A \b \B \G \z \Z^ $ \b \B
一致テスト (Match Test)
(ql:quickload "cl-ppcre")
(if (cl-ppcre:all-matches "1999" s) (format t "party!"))
(regexp-match #rx"bar" "foo bar")
(re-find #"bar" "foo bar")(string-match "bar" "foo bar")
大文字小文字無視の一致
(regexp-match #px"(?i:lorem)" "Lorem")
(re-find #"(?i:lorem)" "Lorem")
置換 (Substitution)
(cl-ppcre:regex-replace "[^l]l" "hello" "EL")
(cl-ppcre:regex-replace-all "[^l]l" "hello hello" "EL")
(regexp-replace #rx"el" "hello" "EL")
(regexp-replace* #rx"el" "hello hello" "EL")
(.replaceFirst "hello" "[^l]l" "XX")
(.replaceAll "hello hello" "[^l]l" "XX")
?
(replace-regexp-in-string "[^l]l" "EL" "hello hello")
グループキャプチャ
(match (regexp-match #px"(\d{4})-(\d{2})-(\d{2})" "2010-06-03") [(list s yr mn dy) (list yr mn dy)])
(let [[_ yr mn dy] (re-find #"(\d{4})-(\d{2})-(\d{2})" "2010-06-03")] yr)
スキャン
(re-seq #"\w+" "dolor sit amet")
一致と置換におけるバック参照
(regexp-match #px"(\w+) \1" "do do")
(regexp-replace #px"(\w+) (\w+)" "do re" "\2 \1")
日付と時刻 (Dates and Time)
Common LispRacketClojureEmacs Lisp
破損された日時型 (Broken-down datetime type)
専用型なし; 9 値のリストが使用:
second: 0-59
minute: 0-59
hour: 0-23
day of month: 1-31
month: 1-12
year: 4 digits
day of week: 0-6 (Mon-Sun)
daylight savings time: t or nil
timezone: negated UTC offset in hours
現在の日時
(get-decoded-time)
(require racket/date) (current-date)
(def dt (new java.util.Date))
(current-time)
UNIX epoch
gray; seconds since Jan 1, 1900:
(get-universal-time)
(current-seconds)
(/ (System/currentTimeMillis) 1000.0)
(float-time)
UNIX epoch から破損された日時へ
(decode-universal-time (get-unversal-time))
(seconds->date (current-seconds))
(def dt (new java.util.Date (System/currentTimeMillis)))
(seconds-to-time (float-time))
破損された日時から UNIX epoch へ
(encode-universal-time 0 22 10 31 5 2015)
(require racket/date) (date->seconds (current-date))
(/ (.getTime (new java.util.Date)) 1000.0)
(multiple-value-bind (b s) (current-time) (+ (* b (expt 2 16)) s))
日時のフォーマット
(def s "yyyy-MM-dd HH:mm:ss")
(def fmt (new java.text.SimpleDateFormat s))
(.format fmt (new java.util.Date))
(format-time-string "%Y-%m-%d %H:%M:%S" (current-time))日時の解析
(require (prefix-in s19. srfi/19))
(define (date-str->unix-time s fmt) (s19.time-second (s19.date->time-utc (s19.string->date s fmt))))
(date-str->unix-time "2015-05-31 07:06:00" "~Y-~m-~d ~H:~M:~S")
日付の構成要素
(multiple-value-bind (ss mi hr dy mo yr) (get-decoded-time) (list ss mi hr) ; warning quiesce (list dy mo yr))
(date-year (current-date))
(date-month (current-date))
(date-day (current-date))
(def cal (new java.util.GregorianCalendar))
(.setTime cal dt)
(.get cal java.util.Calendar/DAY_OF_MONTH)
(+ (.get cal java.util.Calendar/MONTH) 1)
(.get cal java.util.Calendar/YEAR)
(multiple-value-bind (ss mi hr dy mo yr) (decode-time (current-time)) (list dy mo yr))
時刻の構成要素
(multiple-value-bind (ss mi hr) (get-decoded-time) (list ss mi hr))
(date-hour (current-date))
(date-minute (current-date))
(date-second (current-date))
(def cal (new java.util.GregorianCalendar))
(.setTime cal dt)
(.get cal java.util.Calendar/HOUR_OF_DAY)
(.get cal java.util Calendar/MINUTE)
(.get cal java.util.Calendar/SECOND)
(multiple-value-bind (ss mi hr dy mo yr) (decode-time (current-time)) (list ss mi hr))
破損された日時の構築
(encode-universal-time 0 22 10 31 5 2015)
(let [yr 2015 mo 5 dy 31 hr 10 mi 22 ss 0] (def cal (new java.util.GregorianCalendar yr (- mo 1) dy hr mi ss)))
(encode-time 0 50 8 31 5 2015)
リスト (Lists)
Common LispRacketClojureEmacs Lisp
リテラル
'(1 2 3)
(quote (1 2 3))
(1 2 3)
(quote (1 2 3))
'[1 2 3]
{1 2 3}
(quote (1 2 3))
(1 2 3)
(quote (1 2 3))
'(1 2 3)
(quote (1 2 3))
コンストラクタ
(list 1 2 3)
(list 1 2 3)(list 1 2 3)(list 1 2 3)
述語 (Predicate)
(listp '(1 2 3))
(list? '(1 2 3))(list? '(1 2 3))(listp '(1 2 3))
空リストのテスト
nil と '<()> は同義であり、boolean コンテキストでは false として評価される。他のすべての値は true。
(empty? '())
(empty? ())
nil と '<()> は同義であり、boolean コンテキストでは false として評価される。他のすべての値は true。
(nil and '() are synonyms...)
空リストの評価
nil
error
(')
nil
(first '(1 2 3))
(cdr '(1 2 3))
(rest '(1 2 3))
(next '(1 2 3))
(cdr '(1 2 3))
(rest '(1 2 3))
空リストの頭部と尾部
両方とも nil として評価
error
()
両方とも nil として評価
first car
長さ (Length)
(length '(1 2 3))
(length '(1 2 3))(count '(1 2 3))(length '(1 2 3))
等価性テスト
(equal '(1 2 3) '(1 2 3))
(equal? '(1 2 3) '(1 2 3))(= '(1 2 3) '(1 2 3))(equal '(1 2 3) '(1 2 3))
N 番目の要素
; 0 インデックスから:
(nth 2 '(1 2 3 4))
(list-ref '(1 2 3 4) 2)
(nth '(1 2 3 4) 2)
(nth 2 '(1 2 3 4))
(position 7 '(5 6 7 8))none
(position 7 '(5 6 7 8))
境界外動作
nil
error
raises IndexOutOfBoundsException
nil(equal '(1 2 3) '(1 2 3))
要素のインデックス
(list-index (lambda (x) (= x 7)) '(5 6 7 8))
(require srfi/1)
none
(position 7 '(5 6 7 8))
連結 (Append)
(append '(1 2 3) '(4 5 6))
(concat '(1 2 3) '(4 5 6))(append '(1 2 3) '(4 5 6))
先頭 N 個を取得 (Take)
none
(take '(1 2 3 4) 2)
(take 2 '(1 2 3 4))
(subseq '(1 2 3 4) 0 2)
(drop '(1 2 3 4) 2)
(drop 2 '(1 2 3 4))
(nthcdr 2 '(1 2 3 4))
末尾から N 個を除外 (Drop)
(nthcdr 2 '(1 2 3 4))
(last '(1 2 3))
(last '(1 2 3))
最後の要素
(car (last '(1 2 3)))
(define a '(1 2 3)) (take a (- (length a) 1))
(butlast '(1 2 3))
(butlast '(1 2 3))
最後の要素以外の要素
(butlast '(1 2 3))
(reverse '(1 2 3))
(reverse '(1 2 3))
逆順 (Reverse)
(reverse '(1 2 3))
(sort '(3 2 4 1) '<)
(sort '(3 2 4 1) <)
(sort < '(3 2 4 1))
(sort '(3 2 4 1) '<)
重複削除
(remove-duplicates '(1 1 2 3))
(remove-duplicates '(1 1 2 3))(remove-duplicates '(1 1 2 3))
メンバーシップ
(member 7 '(1 2 3))
(mapcar (lambda (x) (* x x)) '(1 2 3))
(filter (lambda (x) (> x 2)) '(1 2 3))
; filter-not は補集合を返す
(filter #(> % 2) '(1 2 3)); remove returns complement
フィルタリング
(remove-if-not (lambda (x) (> x 2)) '(1 2 3))
; remove-if は補集合を返す
(filter (lambda (x) (> x 2)) '(1 2 3))
; filter-not は補集合を返す
(remove-if-not (lambda (x) (> x 2)) '(1 2 3)); remove-if は補集合を返す
畳み込み (Reduce)
(reduce '- '(1 2 3 4) :initial-value 0)
(foldl (lambda (x y) (- y x)) 0 '(1 2 3 4))
(reduce - 0 '(1 2 3 4))(reduce '- '(1 2 3 4) :initial-value 0 :from-end t)
(foldr - 0 '(1 2 3 4))
none
(reduce '- '(1 2 3 4) :initial-value 0 :from-end t)
反復 (Iterate)
(dolist (x '(1 2 3)) (print x) (print (- x)))
(for ((x '(1 2 3))) (printf "an" x) (printf "an" (- x)))
(doseq [x '(1 2 3)] (println x) (println (- x)))
(dolist (x '(1 2 3)) (print x) (print (- x)))
普遍述語
(every (lambda (i) (= 0 (rem i 2))) '(1 2 3 4))
(for/and ((i '(1 2 3 4))) (= 0 (remainder i 2)))
(every? #(= 0 (rem % 2)) '(1 2 3 4))
(every (lambda (i) (= 0 (% i 2))) '(1 2 3 4))
存在述語
(some (lambda (i) (= 0 (rem i 2))) '(1 2 3 4))
(for/or ((i '(1 2 3 4))) (= 0 (remainder i 2)))
(some #(= 0 (rem % 2)) '(1 2 3 4))
(some (lambda (i) (= 0 (% i 2))) '(1 2 3 4))
リスト理解 (List Comprehension)
(for*/list ((file "ABCDEFGH") (rank (in-range 1 9))) (format "aa" file rank))
(for [file "ABCDEFGH" rank (range 1 9)] (format "%c%d" file rank))
シャッフル
(shuffle '(1 2 3 4))
(shuffle '(1 2 3 4))
リストの先頭を設定 (Set Head)
(defparameter a '(1 2 3))
(setf (car a) 3)
(require schema/mpair)
(define a (mlist 1 2 3))
(set-mcar! a 3)
none
(setq a '(1 2 3))
(setcar a 3)
リストの尾部を設定 (Set Tail)
(defparameter a '(1 2 3))
(setf (cdr a) '(4 5 6))
(require schema/mpair)
(define a (mlist 1 2 3))
(set-mcdr! a (mlist 4 5 6))
none
(setq a '(1 2 3))
(setcar a 3)
(setcdr a '(4 5 6))
末尾から操作 (Manipulate Back)
(defparameter a '(1 2 3))
(push 4 a)
(pop a)
none
(setq a '(1 2 3))
(push 4 a)
(pop a)
フラッテン (Flatten)
(flatten '(1 2 (3 (4))))
(flatten '(1 2 (3 (4))))
関連配列の検索
(assoc 3 '((1 2) (3 4)))
(assoc 3 '((1 2) (3 4)))none, see note(assoc 3 '((1 2) (3 4)))
フラットな関連配列の検索
(getf '(1 2 3 4) 3)
none
none
(getf '(1 2 3 4) 3)
ペアリテラル
'(1 . 2)
'(1 . 2)
none
'(1 . 2)
リストセルのテスト
(cons '(1 . 2))
(not (atom '(1 . 2)))
(cons? '(1 . 2))(pair? '(1 . 2))none
(cons '(1 . 2))
(not (atom '(1 . 2)))
要素の再帰的置換
(sublis '((1 . 2) (3 . 4)) '(1 (3 3 (1))))
(sublis '((1 . 2) (3 . 4)) '(1 (3 3 (1))))
固定長配列 (Fixed-length Arrays)
Common LispRacketClojureEmacs Lisp
リテラル
#(1 2 3)
#(1 2 3)[1 2 3][1 2 3]
コンストラクタ
(vector 1 2 3)
(vector 1 2 3)(vector 1 2 3)(vector 1 2 3)
サイズ
(length #(1 2 3))
(vector-length #(1 2 3))
(count [1 2 3])
(length [1 2 3])
検索 (Lookup)
(elt #(1 2 3) 0) or (aref #(1 2 3) 0)
(vector-ref #(1 2 3) 0)
(nth [1 2 3] 0)
(elt [1 2 3] 0)
更新
(setq v [1 2 3])
(setf (aref v 2) 4)
(define v (vector 1 2 3))
(vector-set! v 2 4)
(replace {2 4} [1 2 3])
(setq v #(1 2 3))
(setf (aref v 2) 4)
境界外動作
raises sb-kernel:index-too-large-error
error
(reverse #(1 2 3))(sort #(2 4 1 3) #'<)(map 'vector (lambda (x) (* x x)) #(1 2 3))
配列からリストへ
(coerce #(1 2 3) 'list)
(vector->list #(1 2 3))
(seq [1 2 3])
(coerce [1 2 3] 'list)
リストから配列へ
(coerce '(1 2 3) 'vector)
(list->vector '(1 2 3))
(vec '(1 2 3))
(coerce '(1 2 3) 'vector)
畳み込み (Reduce)
none
(filter (lambda (x) (> x 2)) #(1 2 3)); also remove-if
辞書 (Dictionaries)
Common LispRacketClojureEmacs Lisp
リテラル
none
不可変: #hash(("t" . 1) ("f" . 0))
Clojure.lang.PersistentArrayMap: {"t" 1 "f" 0}
none
コンストラクタ
(defparameter h (make-hash-table :test 'equal))
デフォルトの等価性テストは 'eql
(define ih (make-immutable-hash '(("t" . 1) ("f" . 0))))
可変: (define h (make-hash '(("t" . 1) ("f" . 0))))
不可変: (def ih (hash-map "t" 1 "f" 0))
(setq h (make-hash-table :test 'equal))
述語
(hash-table-p h)
(hash? h)
また、関連リストとベクトルにも適用:
(dict? h)
(map? ih)
(hash-table-p h)
サイズ
(hash-table-count h)
(hash-count h)
また、関連リストとベクトルにも適用:
(dict-count ih)
(count ih)
(hash-table-count h)
検索 (Lookup)
(gethash "t" h)
(hash-ref h "t")
見つからない場合は -1 を返す:
(hash-ref h "m" -1)
また、関連リストとベクトルにも適用:
(dict-ref ih "t")
(dict-ref ih "m" -1)
(get ih "t")
(find ih "t")
見つからない場合は -1 を返す:
(get ih "m" -1)
(gethash "t" h)
更新
(setf (gethash "t" h) 1)
(hash-set! h "t" 2)
(define ih2 (hash-set ih "t" 2))
また、dict-set! と dict-set
(def ih2 (assoc ih "t" 2))
(puthash "t" 1 h)
キーが存在しない場合の動作
nil を返す
error
nil を返す
nil を返す
キーの有無チェック
(nth-value 1 (gethash "t" h))
(hash-has-key? h "t")
また、dict-has-key?
(contains? ih "t")
none
削除 (Delete)
(remhash "t" h)
(hash-remove! h "t")
(define ih2 (hash-remove ih "t"))
また、dict-remove! と dict-remove
(def ih2 (dissoc ih "t"))
(remhash "hello" h)
マージ (Merge)
ih2 の値が優先される:
(define ih3 (merge ih ih2))
(invert)
(require 'clojure.set)
(define ih4 (clojure.set/map-invert ih))
反復 (Iterate)
(maphash (lambda (k v) (print k) (print v)) h)
(hash-for-each h (lambda (k v) (printf "an" k) (printf "an" v)))
また、dict-for-each
(doseq [p ih] (println (first p)) (println (second p)))
(maphash (lambda (k v) (print k) (print v)) h)
キーと値をリストへ
none
(hash-keys h)
(hash-values h)
また、dict-keys と dict-values
(def hkeys (map (fn [p] (first p)) ih))
(def hvals (map (fn [p] (second p)) ih))
none
ユーザー定義型 (User-defined Types)
Common LispRacketClojureEmacs Lisp
Defstruct
(defstruct account id balance)
(setq a (make-account :id 3 :balance 17.12))
(account-id a)
(setf (account-balance a) 0)
(account-p a)
define-struct
account (id (balance #:mutable))
(define a (make-account 3 17.12))
(account-id a)
(set-account-balance! a 0)
(account? a)
(defstruct account :id :balance)
(def a (struct account 3 17.12))
(:id a)
none
*(account-p a)
構造体
(defstruct account id balance)
(setq a (make-account :id 3 :balance 17.12))
(define a (make-account 3 17.12))
(def a (struct account 3 17.12))
*(setq a (make-account :id 3 :balance 17.12))
構造体のゲッター
(account-id a)
(:id a)
(account-id a)
構造体のセッター
(setf (account-balance a) 0)
(set-account-balance! a 0)
none
(setf (account-balance a) 0)
構造体の述語
(account-p a)
(account? a)none
(account-p a)
関数 (Functions)
Common LispRacketClojureEmacs Lisp
関数の定義
(defun add (x y) (+ x y))
(define (add x y) (+ x y))(defn add [x y] (+ x y))(defun add (x y) (+ x y))
関数と変数の名前共有
可能
不可能
不可能
可能
オプション引数
(defun add (a &optional b) (if (null b) a (+ a b)))
(define (add a (b null)) (if (null? b) a (+ a b)))
(defn add ([a] a) ([a b] (+ a b)))
引数が 2 つより多く呼ばれる場合はエラーにならない:
(defn add [a & [b]] (if (nil? b) a (+ a b)))
(defun add (a &optional b) (if (null b) a (+ a b)))
可変数個の引数
(defun add (a &rest b) (if (null b) a (+ a (eval (cons '+ b)))))
(define (add a . b) (if (null? b) a (+ a (apply + b))))
(defn add [a & b] (if (nil? b) a (+ a (apply + b))))
(defun add (a &rest b) (if (null b) a (+ a (eval (cons '+ b)))))
デフォルト値
(defun add (a &optional (b 0)) (+ a b))
Racket: (define (add a (b 0)) (+ a b))
(defn add ([a] (add a 0)) ([a b] (+ a b)))
none
名前付きパラメータ
(defun logarithm (&key number base) (/ (log number) (log base)))
(logarithm :base 2 :number 8)
none
(defn logarithm [{x :number b :base}] (/ (Math/log x) (Math/log b)))
(logarithm {:base 2 :number 8})
(defun logarithm (&key number &key base) (if base (/ (log number) (log base)) (log number)))
順序が重要、キー名ではない:
(logarithm :foo 8 :bar 2)
複数の値を返す
(defun sqrts (x) (values (sqrt x) (- (sqrt x))))
(define (sqrts x) (values (sqrt x) (- (sqrt x))))
(defn sqrts [x] (list (Math/sqrt x) (- (Math/sqrt x))))
values はリストを作成:
(defun sqrts (x) (values (sqrt x) (- (sqrt x))))
(values creates a list)
(values-list '(1 2 3))
(apply values '(1 2 3))
複数の値はリスト
複数の値はリスト
ローカル変数への複数値の割り当て
(multiple-value-bind (r1 r2) (sqrts 3) r2)
(let-values (((r1 r2) (sqrts 3))) r2)
(let [[r1 r2] (sqrts 3)] r2)(multiple-value-bind (r1 r2) (sqrts 3) r2)
グローバル変数への複数値の割り当て
(multiple-value-setq (r1 r2) (sqrts 3))
(define-values (r1 r2) (sqrts 3))
none(multiple-value-setq (r1 r2) (sqrts 3))
リストから複数値への変換
(values-list '(1 2 3))
(apply values '(1 2 3))
複数の値はリスト
複数の値はリスト
タイルコール最適化 (Tail Call Optimization)
Sbcl 用には可能
可能
recur で可能
不可
ラムダ (Lambda)
(lambda (x) (* x x))
(lambda (x) (* x x))#(* % %)
2 つの引数の簡略表記: #(* %1 %2)
(fn [x] (* x x))
; 2 つの引数の簡略表記:
#(* %1 %2)
(lambda (x) (* x x))
適用 (Apply)
((lambda (x) (* x x)) 2)
(apply #'(lambda (x) (* x x)) '(2))((lambda (x) (* x x)) 2)
(apply (lambda (x) (* x x)) '(2))
(#(* % %) 2)
((fn [x] (* x x)) 2)
(apply #(* % %) '(2))
((lambda (x) (* x x)) 2)
(apply #'(lambda (x) (* x x)) '(2))
実行制御 (Execution Control)
Common LispRacketClojureEmacs Lisp
progn
progn prog1 prog2
begin none none
r6rs: begin begin0 none
do none none
progn prog1 prog2
ループ (Loop)
(setq i 1)
(loop (print "hello") (if (> i 10) (return) (setq i (+ i 1))))
none, recursion を使用
(loop [i 1] (if (<= i 10) (do (println "hello") (recur (+ i 1)))))
none
(loop [i 1] (if (<= i 10) (do (println "hello") (recur (+ i 1)))))
Do
(do ((i 1) (sum 0)) ((> i 100) sum) (setq sum (+ sum i)) (setq i (+ i 1)))
do* は順次初期化
none
(do ((i 1) (sum 0)) ((> i 100) sum) (setq sum (+ sum i)) (setq i (+ i 1)))
do* は直列に初期化
Dotimes
(dotimes (i 10 nil) (format t "hello~%"))
(dotimes [_ 10] (println "hello"))
(dotimes (i 10 nil) (print "hello\n"))
If
(if (< x 0) (- x) x)
(if (< x 0) (- x) x)
(if (< x 0) (- x) x)
(if (< x 0) (- x) x)
When
(when (< x y) (print "x is less ") (print "than y"))
Racket: (when (< x y) (display "x is less ") (display "than y"))
(when (< x y) (println "x is less ") (println "than y"))
(when (< x y) (print "x is less ") (print "than y"))
Cond
(cond ((> x 0) 1) ((= x 0) 0) (t -1))
(cond ((> x 0) 1) ((= x 0) 0) (else -1))
(cond (> x 0) 1 (= x 0) 0 true -1)
(cond ((> x 0) 1) ((= x 0) 0) (t -1))
遅延評価
(define x (delay (/ 1 0)))
(promise? x)
(+ 1 (force x))
継続 (Continuations)
(define cc null)
(+ 1 (call/cc (lambda (x) (set! cc x) 0)))
(cc 5)
エラー処理 (Exceptions)
Common LispRacketClojureEmacs Lisp
エラー
(error "failed")
(error "failed")(throw (Exception. "failed"))(error "failed")
エラー処理
(handler-case (error "failed") (simple-error (e) (format t "error: ~a" e)))
(with-handlers ((exn:fail? (lambda (e) (printf "error: ~a" (exn-message e))))) (error "failed"))
(try (throw (Exception. "failure")) (catch Exception e (printf "error: %s" (.getMessage e))))(condition-case e (error "failed") (error (message "error: %s" (error-message-string e))))
エラーの定義
(define-condition odd-err (error) ((num :accessor odd-err-num :initarg :num)) (:report (lambda (e s) (format s "odd number: ~a" (odd-err-num e)))))
(define exn:odd-err? "odd number")
シンボルとキーワードのみがスローされ、キャッチできる
only symbols and keywords can be thrown and caught
例外のスロー
(error 'odd-err :num 7)
(raise exn:odd-err?)
(throw (Exception. "failed"))(throw 'odd-err t)
例外のキャッチ
(handler-case (/ 1 0) (division-by-zero () (progn (format t "division by zero") nil)))
(with-handlers ((exn:fail? (lambda (e) (begin (printf "division by zero~n") null)))) (/ 1 0))
(try (/ 1 0) (catch ArithmeticException _ (do (println "division by zero") nil)))(catch 'failed (throw 'failed nil) t)
Restart-case
(defun halve (l) (mapcar (lambda (x) (restart-case (if (= (rem x 2) 0) (/ x 2) (error 'odd-error :num x)) (round-down () (/ (- x 1) 2)) (round-up () (/ (+ x 1) 2)))) l))
none
Restart の呼び出し
(handler-bind ((odd-err (lambda (c) (invoke-restart 'round-down)))) (halve '(1 2 4 9)))
none
Finally クロージャ
(unwind-protect (error "failure") (print "clean up"))
none(try (throw (Exception. "failure")) (finally (println "clean up")))(unwind-protect (error "failure") (print "clean up"))
ストリーム (Streams)
Common LispRacketClojureEmacs Lisp
標準ファイルハンドル
standard-input standard-output error-output
(current-input-port) (current-output-port) (current-error-port)in out err
EOF 動作
read-line は 2 つの値を返し、2 目は EOF で T に設定される。ファイル終了以降には read を試すと EOF-OF-FILE がスローされる。
Returns the value eof. Use eof-object? to test for it.
.readLine on a java.io.Reader object returns nil.
read-line は改行を破棄
write-string s
(newline)
(println "hello")
stdin から 1 行読み込み
(setq line (read-line))
(let ((s (read-line))) #|use s#
)(let [s (read-line)] (comment use s))
改行の削除 (Chomp)
read-line は改行を破棄
read-line は改行を破棄
stdout に 1 行書き出し
(defun println (s) (format t "a%" s))
(println "hello")
(write-string s)
(newline)
(println "hello")
(printf "%s %d %.2f\n" "foo" 7 13.7)
フォーマットされた文字列の stdout への書き出し
(format t "~s ~d: 2$%" "foo" 7 13.7)
(printf "~a ~a: an" "foo" 7 (/ (round (* 13.7 100)) 100))
ファイルの読み込みオープン
(setq in (open "/etc/hosts"))
(let ((f (open-input-file "/etc/hosts"))) #| use f #
)
f は java.io.Reader オブジェクト:
(let [f (clojure.java.io/reader "/etc/hosts")] (.readLine f))
ファイルの書き込みオープン
(setq out (open "/tmp/test" :direction :output :if-exists :supersede))
(let ((f (open-output-file "/tmp/foo" #:exists 'truncate))) #| use f #
)
f は java.io.Writer オブジェクト:
(let [f (clojure.java.io/writer "/tmp/foo")] (.write f "lorem ipsum\n") (.close f))
ファイルの追加書き込みオープン
(setq out (open "/tmp/test" :direction :output :if-exists :append))
(let ((f (open-output-file "/tmp/foo" #:exists 'append))) #| use f #
)
(let [f (clojure.java.io/writer "/tmp/foo" :append true)] (.write f "lorem ipsum\n") (.close f))
ファイルの閉鎖
(close in)
(close-input-port f)
(close-output-port f)
(.close f)
明示的なファイル閉鎖
(with-open-file (out #P"/tmp/test" :direction :output) (write-line "lorem ipsum" out))
(call-with-input-file "/etc/hosts" (lambda (f) (#| use f #
)))
また、call-with-output-file
(with-open [f (clojure.java.io/reader "/etc/hosts")] (comment use f))
1 行読み込み
(setq line (read-line f))
(define line (read-line in))
(.readLine f)
ファイルの反復 (1 行単位)
(for ([line (in-lines (open-input-file "/etc/hosts"))]) (write-string line) (newline))
(loop [line (.readLine f)] (if (not= line nil) (do (println line) (recur (.readLine f)))))
ファイルを文字列配列へ読み込み
文字列のリストへ:
(sequence->list (in-lines (open-input-file "/etc/hosts")))
(vec (line-seq f))
ファイルを文字列へ読み込み
(define s (file->string "/etc/hosts"))
(let [s (slurp "/etc/hosts")] (print s))
文字列の書き出し
(write-string s f)
(.write f s)
1 行の書き出し
(write-string s f)
(newline f)
(.write f (println-str s))
ファイルハンドルのフラッシュ
(flush-output f)
(f .flush)
ファイルハンドル位置
get, set
非負の整数として評価:
(file-position f)
次回の読み書きをファイル先頭へ設定:
(file-position f 0)
引数は現在の位置から文字数; 後ろ移動は不可能:
(.skip f 1000)
バッファする最大文字数:
(.mark f 1000000)
mark 時の位置へ移動:
(.rest f)
メモリストリーム
(setq f (make-string-input-stream "lorem ipsum"))
(read-line f)
(setq f2 (make-string-output-stream))
(write-string "lorem ipsum" f2)
(get-output-stream-string out)
(define f (open-input-string "lorem ipsum"))
(read-line f)
(define f2 (open-output-string))
(write-string "lorem ipsum" f2)
(get-output-string f2)
文字列からの読み込み:
(with-in-str "lorem ispum" (read-line))
文字列への書き込み:
(with-out-str (println "lorem ipsum"))
Emacs バッファ
Emacs Lisp
バッファリストの作成
;; バッファオブジェクトのリスト: (buffer-list)
;; リスト内の最初のバッファ名: (buffer-name (car (buffer-list)))
;; 現在のバッファ名: (buffer-name (current-buffer))
現在バッファ
get and set
;; 現在のバッファ名: (buffer-name (current-buffer))
;; 現在のパネでオープン: (switch-to-buffer "foo.txt")
;; 他のパネでオープン: (switch-to-buffer-other-window "bar.txt")
バッファのクリア
;; 現在のバッファ: (erase-buffer)
;; "foo.txt" という名前のバッファ: (with-current-buffer "foo.txt" (erase-buffer))
カーソル位置 (Point)
get and set
;; カーソルの下の文字の 1 ベースインデックス: (point)
;; 現在のバッファの先頭へ移動: (goto-char 1)
;; 現在のバッファの末尾へ移動: (goto-char (buffer-size))
検索と Point の設定
;; Set point to character after string.
;; 1st arg is position in buffer beyond which search stops.
;; If 2nd arg is true, return nil on failure, otherwise raise error.
;; 3rd argument is the occurrence of the string, if negative search backwards from point.
(search-forward "lorem" nil t 1)
文字列の Point への挿入
;; 1 つ以上の引数を受け取る: (insert "lorem" " ipsum")
バッファを文字列へ
(buffer-string)
Point へのファイル内容の挿入
(insert-file "/etc/passwd")
マーク (Mark)
get and set
;; 現在のバッファの先頭: (set-mark 1)
;; 現在のバッファの Point へ: (set-mark (point))

ファイル (Files)

Common LispRacketClojureEmacs Lisp
ファイルテスト、通常ファイルテスト
(osicat:file-exists-p "/tmp/foo")
(osicat:regular-file-exists-p "/tmp/foo")
??(file-exists? "/etc/hosts")
(.exists (io/file "/etc/hosts"))
(file-exists-p "/etc/hosts")
(file-regular-p "/etc/hosts")
ファイルサイズ
(file-size "/etc/hosts")
(.length (io/file "/etc/hosts"))(eighth (file-attributes "/etc/hosts"))
読み込み/書き込み/実行許可テスト
(pair? (filter (lambda (x) (eq? x 'read)) (file-or-directory-permissions "/etc/hosts")))
(pair? (filter (lambda (x) (eq? x 'write)) (file-or-directory-permissions "/etc/hosts")))
(pair? (filter (lambda (x) (eq? x 'execute)) (file-or-directory-permissions "/etc/hosts")))
(.canRead (io/file "/etc/hosts"))
(.canWrite (io/file "/etc/hosts"))
(.canExecute (io/file "/etc/hosts"))
ファイル権限の設定
(file-or-directory-permissions "/tmp/foo" #o755)
(set-file-modes "/tmp/foo" #o755)
最終変更時刻
(file-or-directory-modify-seconds "/tmp/foo")
UNIX epoch in milliseconds:
(.lastModified (java.io.File. "/tmp/foo"))
ファイルのコピー、削除、改名
(cl-fad:copy-file #P"/tmp/foo" #P"/tmp/bar")
(delete-file #P"/tmp/foo")
(rename-file #P"/tmp/bar" #P"/tmp/foo")
(copy-file "/tmp/foo" "/tmp/bar")
(delete-file "/tmp/foo")
(rename-file-or-directory "/tmp/bar" "/tmp/foo")
(clojure.java.io/copy (java.io.File. "/tmp/foo") (java.io.File. "/tmp/bar"))
(clojure.java.io/delete-file "/tmp/foo")
(.renameTo (java.io.File. "/tmp/bar") (java.io.File. "/tmp/foo"))
(copy-file "/tmp/foo" "/tmp/bar")
(delete-file "/tmp/foo")
(rename-file "/tmp/bar" "/tmp/foo")
シンボリックリンクの作成、テスト、ターゲット取得
(osicat:make-link "/tmp/hosts" :target "/etc/hosts")
(make-file-or-directory-link "/etc/hosts" "/tmp/hosts")
(link-exists? "/tmp/hosts")
??(make-symbolic-link "/etc/hosts" /tmp/hosts")
シンボリックリンクまたは nil の場合、ターゲットを返す: (file-symlink-p "/tmp/hosts")
一時ファイル
(define tmp (make-temporary-file))
(path->string tmp)
java.io.File:
(java.io.File/createTempFile "foo" ".txt")
(make-temp-file "foo")

ディレクトリ (Directories)

Common LispRacketClojureEmacs Lisp
パス名の構築
(make-pathname :directory '(:absolute "etc") :name "hosts")
パスを返す; 文字列へ変換するには path->string を使用:
(build-path "/etc" "hosts")
(require '[clojure.java.io :as io])
java.io.File を返す; 文字列へ変換するには .getPath を使用:
(io/file "/etc" "hosts")
ディレクトリ名とファイル名の取得
(pathname-directory #P"/etc/hosts")
(pathname-name #P"/etc/hosts")
(let-values (((dir file _) (split-path "/etc/hosts"))) #| use dir or file #)(.getParent (io/file "/etc/hosts"))
(.getName (io/file "/etc/hosts"))
絶対パス
(simplify-path (path->complete-path ".."))
(.getCanonicalPath (java.io.File. ".."))(expand-file-name "..")
ディレクトリの反復 (ファイル単位)
(dolist (file (osicat:list-directory "/tmp")) (format t "a%" file))
(for ([path (directory-list "/etc")]) (write-string (path->string path)))
file-seq は引数ディレクトリとサブディレクトリ再帰的にファイルの java.io.File オブジェクトを返す:
(filter #(= (.getParent %) "/etc") (file-seq (clojure.java.io/file "/etc")))
(dolist (file (directory-files "/etc")) (print file))
ディレクトリの作成
(make-directory* "/tmp/foo/bar")
2 目の引数が nil でない場合、親ディレクトリを作成:
(make-directory "/tmp/foo/bar" t)
再帰コピー
(copy-directory/files "/tmp/foo.d" "/tmp/bar.d")
空ディレクトリの削除
(delete-directory "/tmp/foo.d")
(delete-directory "/tmp/foo.d")
(clojure.java.io/delete-file "/tmp/foo.d")
(delete-directory "/tmp/foo.d")
ディレクトリと内容の削除
(osicat:delete-directory-and-files "/tmp/foo.d")
(delete-directory/files "/tmp/foo.d")(delete-directory "/tmp/foo.d" t)
ディレクトリテスト
(osicat:directory-exists-p #P"/etc")
(directory-exists? "/etc")
(.isDirectory (io/file "/etc"))
(file-directory-p "/etc")

プロセスと環境 (Processes and Environment)

Common LispRacketClojureEmacs Lisp
コマンドライン引数
posix-argv
current-command-line-argumentscommand-line-args
shebang モードのみ: command-line-args or argv
プログラム名
環境変数
(posix-getenv "HOME")
(getenv "HOME")(System/getenv "HOME")(getenv "HOME")
ユーザー ID と名前
終了
外部コマンド
(run-program "ls" '("/etc"))
(require scheme/system)
(system "ls /etc")
(.exec (Runtime/getRuntime) "ls")
(shell-command "ls /etc")
コマンド置換
(shell-command-to-string "ls /etc")

ライブラリと名前空間 (Libraries and Namespaces)

Common LispRacketClojureEmacs Lisp
完全な例
$ cat b/a.clj

(ns b.a)
(def x 3)
$ java -cp clojure.jar:. clojure.main
<br=> (require 'b.a)<br=> b.a/x
3
コンパイルライブラリ
(compile-file "a.lisp")
$ raco make a.rkt

(compile 'a)
ロードライブラリ
(load "a.lisp")
サブディレクトリのライブラリ読み込み
(load "b/a.lisp")
(require "b/a.rkt")
(require 'b.a)
ホットパッチ
(load "a.lisp")
none(require 'b.a :reload)
(load "a")
ロードエラー
raises sb-int:simple-file-error
raises exn:fail:syntax:missing-module. require はトップレベルである必要があるため、例外は処理できない。
raises FileNotFoundException
raises file-err
ライブラリパス
起動時に作業ディレクトリが含まれる
(require setup/dirs)
(get-collects-search-dirs)
same as path used by java VM
追加:
(add-to-list 'load-path ("/home/ed/.emacs.d/lib"))
EMACSLOADPATH
ライブラリパス環境変数noneCLASSPATH
コマンドラインオプション
none
$ java -cp /foo/bar:/baz/quux
$ emacs -L /foo/bar
名前空間宣言
(defpackage :foo)
(module mconst racket (provide pi) (define pi 3.14))(ns mconst)No namespaces; library のすべての識別子にハイフンで区切られたプレフィックスを使用する一般的な慣習がある。
サブ名前空間宣言none
b/a.clj でなければならない:
(ns b.a)
名前空間のセパレータ
:
:. and /
インポート定義
*現在の package を foo に設定し、twiddle を bar からインポート:
(defpackage :foo (:import-from :bar :twiddle))
名前空間のすべての定義をインポート
*現在の package を foo に設定し、bar のシンボルをインポート:
(defpackage :foo (:use :bar))
名前空間のシャドウ回避
識別子のシャドウ回避
パッケージマネージャーヘルプ
$ raco help

$ raco pkg --help

$ raco pkg install --help

M-x list packages
M-x list-packages
インストールされたパッケージのリスト
$ raco pkg show --all
パッケージの検索
(ql:system-apropos "time")
http://pkgs.racket-lang.org
M-x list-packages
パッケージのインストール
quicklisp のインストール:
(load "~/quicklisp/setup.lisp")
(ql:quickload "osicat")
$ raco pkg install --deps search-auto srfi

M-x list-packages でパッケージメニューを開く; i で選択、x でインストール。
パッケージの削除
$ raco pkg remove srfi
パッケージメニューで d で選択、x でアンインストール。
オブジェクト (Objects)
Common LispRacketClojureEmacs Lisp
クラスの定義
(defclass rectangle () ((height :accessor rectangle-height :initarg :height) (width :accessor rectangle-width :initarg :width)))
(define rectangle% (class object% (init width) (init height) (super-new) (define curr-height height) (define curr-width width) (define/public (get-height) curr-height) (define/public (get-width) curr-width) (define/public (set-height ht) (set! curr-height ht)) (define/public (set-width wd) (set! curr-width wd))))use java: public class Rectangle { public float height; public float width; ... }
public void setHeight(float h) {...}
public void setWidth(float w) {...}
インスタンスの作成
(make-instance 'rectangle :height 3 :width 7)
(define rect (new rectangle (height 7) (width 3)))
(import 'Rectangle)
(def r (Rectangle. 7 3))
(.height r)
(.setHeight r 8)
属性の読み取り
(rectangle-height rect)
(send rect get-height)
属性の書き込み
(setf (rectangle-height rect) 4)
(send rect set-height 4)
(.setHeight r 8)
メソッドの定義
(defmethod area ((figure rectangle)) (* (rectangle-height figure) (rectangle-width figure)))
(define/public (area) (* curr-height curr-width))(defmulti area class)
(defmethod area Rectangle [r] (* (.height r) (.width r)))
メソッドの呼び出し
(area rect)
(send rect area)(area r)
普遍的な上位クラス
standard-object t
object%Object
多重継承可能
不可
1 つの直接上位クラスのみ; 複数のインタフェースを実装可能
Lisp マクロ
Common LispRacketClojureEmacs Lisp
Backquote と Comma
(setq op '+)
(eval `(,op 1 1))
(define op '+)
(eval `(,op 1 1))
(eval (quasiquote ((unquote op) 1 1)))(def op +)
(eval `(,op 1 1))
*(setq op '+)
(eval `(,op 1 1))
Defmacro
(defmacro rpn (arg1 arg2 op) (list op arg1 arg2))
(define-syntax-rule (rpn arg1 arg2 op) (op arg1 arg2))(defmacro rpn [arg1 arg2 op] (list op arg1 arg2))(defmacro rpn (arg1 arg2 op) (list op arg1 arg2))
Backquote での Defmacro
(defmacro rpn (arg1 arg2 op) `(,op ,arg1 ,arg2))
(define-syntax-rule (rpn3 arg1 arg2 op) (eval '(,op ,arg1 ,arg2)))(defmacro rpn [arg1 arg2 op] `(~op ~arg1 ~arg2))(defmacro rpn (arg1 arg2 op) `(,op ,arg1 ,arg2))
マクロ述語
(macro-function rpn)
none
none
none
Macroexpand
(macroexpand '(rpn 1 2 +))
(syntax-object->datum (expand-to-top-form '(rpn 1 2 +)))(macroexpand '(rpn 1 2 +))(macroexpand '(rpn 1 2 +))
Splice Quote
(defmacro add (&rest args) `(+ ,@args))
(define-syntax-rule (add first ...) (+ first ...))(defmacro add [& args] `(~@args ~@arg1))(defmacro add (&rest args) `(,op ,@args))
再帰マクロ
(defmacro add (a &rest b) `(if (null ',b) (+ ,a) (+ ,a (add ,@b))))
(define-syntax add (syntax-rules () [(add x) x] [(add x y) (+ x y)] [(add x y ...) (+ x (add y ...))]))(defmacro add ([a] `(,~a)) ([a & b] `(,~a (add ~@b))))(defmacro add (a &rest b) `(if (null ',b) (+ ,a) (+ ,a (add ,@b))))
衛生的 (Hygienic)
不可
可能
# 接尾符付きで可能
不可
ローカル値
(defmacro square-sum (x y) (let ((sum (gensym))) `(let ((,sum (+ ,x ,y))) (* ,sum ,sum))))
(define-syntax-rule (square-sum x y) (let ((sum (+ x y))) (* sum sum)))(defmacro two-list [x] `((let [arg# ~x]) (list arg# arg#)))
(defmacro square-sum (x y) (let ((sum (gensym))) `(let ((,sum (+ ,x ,y))) (* ,sum ,sum))))
リフレクション
Common LispRacketClojureEmacs Lisp
型を調査
(type-of '(1 2 3))
(typep '(1 2 3) 'list)
(listp '(1 2 3))
(type-of [1 2 3] 'vector)
(typep [1 2 3] 'vector)
(vectorp [1 2 3])
(= (type 1) java.lang.Long)
(= (class 1) java.lang.Long)
(integer? 1)
インスタンスの所属
instance-of
instance?
基本型
logical and numeric: bignum bit complex double-float fixnum float integer long-float nil null number ratio rational real short-float signed-btye single-float t unsigned-byte
symbols and strings: base-character character extended-character keyword simple-string standard-char string symbol
data structures: array atom bit-vector cons hash-table list sequence simple-array simple-bit-vector simple-vector vector
other: compiled-function function package pathname random-state stream
all collections and strings
list vector
sequence data types
list vector hash-table string input-port range
get docstring
(describe #'mapcar)
(none)
(doc map)
(describe-function 'mapcar)
ドキュメント文字列付き関数の定義
(defun add (x y) "add x and y" (+ x y))
none
defn add "add x and y" [x y] (+ x y)
(defun add (x y) "add x and y" (+ x y))
Apropos とドキュメント検索
none
none
(apropos #"^add$")
(find-doc #"add \S+ and \S+")
(apropos "^add$")
none
Java インタラプション
Common LispRacketClojureEmacs Lisp
新しいオブジェクト作成
(def rnd (new java.util.Random))
(def rnd (java.util.Random.))
(. rnd nextFloat)
(.nextFloat rnd)
(. rnd nextInt 10)
(.nextInt rnd 10)
(Math/sqrt 2)
メソッド(import '(java.util Random))
(def rnd (Random.))
クラスメソッド(to-array '(1 2 3))(into-array Integer '(1 2 3))
JVM のバージョンと追加ライブラリ
racket: The srfi-1 library brings in a common list functions which Kawa does not make available by default. See SRFI.
ANSI Specification
SBCL User Manual
Quicklisp
パッケージマネージャーとして Quicklisp を使用:
* インストールと cl-ppcre のロード方法:
$ curl -O http://beta.quicklisp.org/quicklisp.lisp

$ sbcl

* (load "quicklisp.lisp")
* (quicklisp-quickstart:install)
* (ql:quickload "cl-ppcre")
* (cl-ppcre:all-matches "foo" "foo bar")
Quicklisp はユーザーのホームディレクトリに quicklisp ディレクトリを作成:
$ sbcl

* (load "/quicklisp/setup.lisp")
* (ql:quickload "cl-ppcre")
* (cl-ppcre:all-matches "foo" "foo bar")
起動時に自動的に Quicklisp をロードするには、.sbclrc ファイルにロードコマンドを入れる:
$ cat ~/.sbclrc

(load "
/quicklisp/setup.lisp")
Racket
Guide: Racket
Reference: Racket
PLaneT: Racket Packages
Racket の collects ディレクトリには多くのライブラリが含まれ、require コマンドでロード可能:
raw symbol が collects ディレクトリからの相対パス。
Racket 5.1 には 50 つの SRFI ライブラリが含まれる。
ビルトインのパッケージ管理システムも備える。利用可能なパッケージのリストを表示、詳細ページから require 文字列を取得。
$ racket

> (require (planet "spgsql.rkt" ("schematics" "spgsql.plt" 2 3)))
ファイルは ~/Library/Racket にインストール。
Clojure
Clojure Reference
Clojure Cheat Sheet
Calling Java:
(def rnd (new java.util.Random)) ; Java object 作成
(. rnd nextFloat) ; オブジェクト上のメソッド呼び出し
(. rnd nextInt 10) ; 引数付きメソッド呼び出し
(. Math PI) ; 静的メンバー
(import '(java.util Random)) ; インポート
Clojure は java.lang のすべてを自動的にインポート。
短縮形:
(Random.) (new Random)
Math/PI (. Math PI)
(.nextInt rnd) (. rnd nextInt)
primitive 型のため、Java 配列に特化した関数:
(make-array CLASS LEN)
(make-array CLASS DIM & DIMS)
(aset ARY IDX VAL)
(aget ARY IDX)
(alength JARY)
(to-array SEQ)
(into-array TYPE SEQ)
(amap ARY I COPY EXPR)
(areduce ARY IDX COPY INIT EXPR)
Emacs Lisp
GNU Emacs Manual
GNU Emacs Lisp Reference Manual
Emacs 内での導入:
M-x lisp-interaction-mode で Lisp インタラクションモードへ。
C-x e で現在の行の s-expression を評価。
M-x eval-buffer でバッファ全体を評価。
Lisp インタラクションモードで関数を定義:
(defun dired-emacs-lisp () "Open the Emacs Lisp directory in dired." (interactive) (dired "/Applications/Emacs.app/Contents/Resources/lisp"))
関数は M-x dired-emacs-lisp で呼べる。
Lisp 関数の一部はコマンドとして呼び出せる。
コマンドの本体にはオプションの説明文字列があり、followed by interactive call.
M-x describe-function で機能名を入力すると説明を表示。
interactive は Lisp 関数をコマンドにする。
キー C-c l にバインド:
(global-set-key "\C-cl" 'dired-emacs-lisp)
起動時に常時利用可能なら ~/.emacs.d/init.el に置く。

同じ日のほかのニュース

一覧に戻る →

2026/05/19 10:30

LLM による「過去六ヶ月の要約」――わずか五分で読み解く

## Japanese Translation: PyCon US 2026 における「2025 年 11 月の転換点」に関する振り返りは、AI ランドスケープが標準ハードウェア(例:Mac Mini)上で動作する実践的なローカルツールおよび個人用 AI アシスタントへと劇的に移行していることを示しました。2025 年後期から 2026 年初頭にかけての期間は、「最良」という称号を巡る過激な競争によって特徴づけられていました。11 月単独でわずか 2 ヶ月の間にトッププロバイダーにおけるリーダーシップは 5 回交代し、Claude Sonnet 4.5、GPT-5.1、Gemini 3、Codex Max などを経由した後、最終的に Claude Opus 4.5 に落ち着きました。この時代は、コーディングエージェントにおいて OpenAI や Anthropic の検証可能な報酬に基づく強化学習(Reinforcement Learning from Verifiable Rewards)への取り組みにより、単発的な動作から信頼できる日常利用ツールへと移行したことで推進されました。 顕著な技術的進展としては、Google が実用的なオープンウェイトモデルとして Gemma 4 シリーズをリリースしたことや、中国の研究所が GLM-5.1(1.5TB モデル)を公開したことが挙げられます。これらのモデルは、動物がエスクーターに乗っている様子やバージニア北部のカナザが自転車に乗っているような不可能なタスクのアニメーション生成といった驚くべき能力を発揮しました。特定のコミュニティプロジェクトは「Warelay」として始まりましたが、「OpenClaw」という名称を最終的に採用し、人気のあるローカル「個人用 AI アシスタント」の代名詞となりました。2026 年 2 月には新規モデルに対する需要が高まりシリコンバレーで Mac Mini が品切れになった一方で、一部のプロジェクトはセキュリティ懸念とパフォーマンスの問題のため廃止されました。全体のテーマは、自律的にホストされる知能のブームであり、ラップトップ搭載のモデルが業界リーダーと比較して期待を大きく上回る性能を発揮し始めた点にあります。

2026/05/17 1:49

Android スマートフォンを业余無線局トランシーバーに変えてください。

## Japanese Translation: kv4p HT は、Android スマートフォンとの統合を目的として設計されたオープンソースの VHF/UHF アマチュア無線トランスceiver です。専用バッテリーや外部充電器の必要性を排除するため、スマートフォンから電力を供給します。カスタム PCB(v2.0e)、SA818-V/U または DRA818V/U モジュール、SMA メスアンテナなどの部品の使用により構成され、SMS 風のメッセージングおよび位置情報ビーコン機能(APRS)を含む高度なデータ通信タスクをサポートします。法的に運用するためには、少なくとも技師級のアマチュア無線免許証を保有している必要があります。製品には保証がありません。フルデザインと GPL3 ライセンスの ESP32 ファームウェアは GitHub 上に公開されており、3D プリンター用ファイルも用意されているため、DIY による組み立てが可能で、モジュール/PCB のハンダ付け、接着ゲルパッドによる装着、3D プリント製ケースの取り付けを伴います。新規ユーザーは、事前に組み立て済みのベンダーキットを購入しない場合は、ソフトウェアを手動でフラッシュする必要があります。本システムは、2017 年以降の Android 8 以上のデバイスとのみ互換性があります。リアルタイムクローズドキャプション、PTT 用のハプティックフィードバック、アニメーション制御など、アクセシビリティ機能により、多様なユーザーにとって使いやすさが向上しています。

2026/05/19 13:24

コーデックス・マキシング(Codex-maxxing)

## Japanese Translation: この文は、短命なチャットセッションから、複雑な知識労働に適した耐久性のある長時間稼働型コーディングエージェントへの転換を描いています。これらのエージェントは、「compaction(コンパクト化)」という機能を用いて古いのメッセージを剪定し、コスト超過やコンテキスト制限を防ぎつつ不可欠な履歴を保持しながら、数ヶ月間自動化された動作を持続させます。ユーザーは「Chief of Staff」のようなメガスレッドをピン留めして好みを蓄積し、Command-1 から Command-9 などのショートカットを通じてワークストリームを舵取りできますが、オフキャッシュのスレッドは新規の短寿命スレッドよりも高いコストを支払う可能性があります。エージェントは Codex および Wispr Flow を通じて音声入力を受付けることができ、システム全体での口述が可能になり、タイピング単独よりも豊富なコンテキストを実現します。ユーザーはツール呼び出し後(steering)に新たな方向性を注入し、ステップが完了するのを待たずにエージェントを誘導できます。共有メモリシステムはチャット外に Obsidian クォート内にアーティファクト(AGENTS.md を含む)を保存しており、これらを検証、編集、差分表示することを可能にします;GitHub でリポジトリとしてホストされる場合、クラウドツールを通じてメモリの更新内容を確認でき、審査されていない対話の「vibes(雰囲気)」が蓄積するのを防ぎます。$slack、$gmail、$calendar、$browser、@chrome、および@computer といったコネクタは、ローカルのウェブ表面、認証済みのブラウザ状態、Twitter やデスクトップアプリなどの GUI アプリケーションなど、追加機能を提供します。Hatch Pet などのインストール可能なスキルは再利用可能なワークフローをパッケージ化し、エージェントが再教育なしでタスクを繰り返せるようにします。リモートコントロール機能により、ユーザーは作業マシン上で長時間稼働するタスクを開始し、モバイルデバイスからステップを承認することで進捗を持続させつつ管理できます。スレッドローカルハートビートは、Slack/Gmail を 30 分ごとに、フィードバックを 15 分ごとにといった再帰的なチェックをスケジュールし、ユーザーの常在なしでループを稼働させます。ゴールはエージェントに明確な仕上げラインと成功基準を与え、例えば元の単一テストを全てパスしながら Python Rich を Rust に移行する場合などに適用されます。サイドパネルはアーティファクト(Markdown、PDF、スプレッドシート)を検証し、ウェブ表面(index.html、Storybook、Slidev)を操作し、ループを壊さずに変更を確認する作業領域として機能します。

ハイポリグロット・リズプ:コモンリズプ、ラケット、クロージャ、エマックスリズプ。 | そっか~ニュース