Declaration: Content forked form the http://hyperpolyglot.org/lisp, only for compare study lisp and record learning experience
;; common-lisp
$ sbcl --version
;; racket
$ racket --version
;; clojure
displayed by repl on startup
;; emacs-lisp
$ emacs --version
;; common-lisp
;; racket
$ raco make module.rkt
;; clojure
;; emacs-lisp
M-x byte-compile-file
;; common-lisp
(sb-ext:save-lisp-and-die "executable" :executable t :toplevel 'function)
;; racket
$ mzc —exe executable file
;; clojure
;; emacs-lisp
;; common-lisp
$ sbcl --script foo.lisp
;; racket
$ racket -r foo.racket
;; clojure
specify full path to clojure jar:
java -cp clojure.jar clojure.main foo.clj
;; emacs-lisp
;; common-lisp
#!/usr/bin/env sbcl --script
;; racket
#!/usr/bin/env racket --script
;; clojure
specify full path to clojure jar:
#!/usr/bin/env java -jar clojure.jar
;; emacs-lisp
#!/usr/bin/env emacs --script
;; common-lisp
$ sbcl
;; racket
$ racket
;; clojure
$ java -jar /PATH/TO/clojure.jar
;; emacs-lisp
M-x ielm
;; common-lisp
;; racket
$ racket -e '(+ 1 1)'
;; clojure
;; emacs-lisp
;; common-lisp
whitespace
;; racket
whitespace
;; clojure
whitespace and commas
;; emacs-lisp
whitespace
;; common-lisp
(+ 1 1) ; adding
;; racket
(+ 1 1) ; adding
;; clojure
(+ 1 1) ; adding
;; emacs-lisp
(+ 1 1) ; adding
;; common-lisp 和 emacs-lisp的区别, clisp 可以行中间注释, elisp不可以
(+ 1 #| adding |# 1) ;;=> 2
;; racket
(+ 1 #| adding |# 1)
;; clojure
;; emacs-lisp
;; common-lisp
case insensitive, cannot start with digitexcluded characters:
SP ( ) " , ' ` : ; # | \reserved for user macros:
? ! [ ] { }
;; racket
case sensitive, cannot start with digitexcluded characters:
SP ( ) [ ] { } " , ' ` ; # | \
;; clojure
case sensitive, cannot start with digitpermitted characters:
A-Z a-z 0-9 * + ! - _ ?these have special meaning or are reserved:
/ . :
;; emacs-lisp
case sensitive, cannot start with digitexcluded characters:
SP ( ) " , ' ` ; # | \ _ [ ]
;; common-lisp
(setq |white space symbol| 3) ;;=> 3
(setq white\ space\ symbol 3) ;;
;; racket
(define |white space symbol| 3)
(define white\ space\ symbol 3)
;; clojure
nonenone
;; emacs-lisp
none
(setq white\ space\ symbol 3)
;; common-lisp
; parallel assignment:
(let ((x 3) (y 4)) (+ x y)) ; sequential assignment: 7
(let* ((x 3) (y (* x x))) (+ x y)) ;;=> 12
;; racket
; parallel assignment:
(let ((x 3) (y 4)) (+ x y)); sequential assignment:
(let* ((x 3) (y (* x x))) (+ x y))
;; clojure
(let [x 3 y 4] (+ x y))
(let [[x y] [3 4]] (+ x y))
(let [x 3 y (* x x)] (+ x y))
;; emacs-lisp
; parallel assignment:
(lexical-let ((x 3) (y 4)) (+ x y)) ;; 7
(lexical-let* ((x 3) (y (* x x))) (+ x y)) ;; 12
;; common-lisp
(defparameter *x* 3) ;; doesn't change x if already set, *X* => 3 , (setq *X* 312312) => *X* 还是312312?
(defvar *x* 3)
;; racket
(define x 3); y is not global:
(define (double z) (define y 2) (* y z))
;; clojure
(def x 3)
;; emacs-lisp 即使是一个列表,也是可以作为变量名的
(set 'x 3)
(setq x 3)
;; common-lisp
(makunbound 'x) ;; (makunbound '*X*) 去除变量值
;; racket
(namespace-undefine-variable! 'x)
;; clojure
(ns-unmap *ns* 'x)
;; emacs-lisp 这里是移除变量的操作
(makunbound 'x)
;; common-lisp
nil '()
;; racket
null '()
;; clojure
; same value as null in Java:
nil
;; emacs-lisp
nil '()
;; common-lisp
(null x) ;; x 为nil时, 结果为T. 否则为NIL
;; racket
(null? x)
;; clojure
(nil? x)
;; emacs-lisp
(null x)
;; common-lisp
'x
(quote x) ;; (= (quote x) 'X) ? ==> = 只能是数字
;; racket
'x
(quote x)
;; clojure
'x
(quote x)
;; emacs-lisp
'x
(quote x)
;; common-lisp
(symbolp 'x) ;; T 判断是否为symbol类型
;; racket
(symbol? 'x)
;; clojure
(symbol? 'x)
;; emacs-lisp p判断类型通常有着一个p
(symbolp 'x)
;; common-lisp
(eq 'x 'x) ;; => (eq (quote x) 'x) => T, eq通常用于测试是否相等的表达式,=测试是否相等的数字
;; racket
(eq? 'x 'x)
;; clojure
(= 'x 'x)
;; emacs-lisp
(eq 'x 'x)
;; common-lisp
:foo ;;=> :FOO
;; racket
#:foo
;; clojure
:foo
;; emacs-lisp
:foo
;; common-lisp
(set 'x 13)
(setf (get 'x :desc) #|这里测试是NIL|# "unlucky") ;;=> 结果输出unlucky, (get 'x :desc)变成了unlucky, setf 给:desc属性赋值为unlucky
(get 'x :desc)
(remprop 'x :desc) ;;=> (:DESC "unlucky"), :desc属性去除后为零了
;; racket
none
;; clojure
; value must be instance of clojure.lang.IObj:
(def x (with-meta [13] {:desc "unlucky"}))
(get (meta x) :desc); none
;; emacs-lisp 元数据的操作,移除和获取
(set 'x 13)
;; get is nil, setf is string
(setf (get 'x :desc) "unlucky")
(get 'x :desc) ;; string
(remprop 'x :desc) ;; 移除元数据就没有字符串了
;; common-lisp
t nil ;;=> T, NIL
;; racket
#t #f
true false
;; clojure
true false
;; emacs-lisp
t nil
;; common-lisp
nil ()
;; racket
#f false
;; clojure
false nil
;; emacs-lisp
nil ()
;; common-lisp
(or (not t) #|输出NIL|# (and t nil) #|输出NIL|#) ;;=> NIL
;; racket
(or (not #t) (and #t #f))
;; clojure
(or (not true) (and true false))
;; emacs-lisp
(or (not t) (and t nil))
;; common-lisp
= /= < > <= >=
;; racket
= none < > <= >=
;; clojure
= not= < > <= >=
;; emacs-lisp
= /= < > <= >=
;; common-lisp
(min 1 2 3) ;;=> 1
(max 1 2 3) ;;=> 3
;; racket
(min 1 2 3)
(max 1 2 3)
;; clojure
(min 1 2 3)
(max 1 2 3)
;; emacs-lisp
(min 1 2 3)
(max 1 2 3)
;; common-lisp 数值和浮点型判断
numberp integerp
rationalp floatp
realp complexp
;; racket
number? integer?
rational? inexact?
real? complex?
;; clojure
number? integer?
rational? float?none none
;; emacs-lisp 基本上和clisp设计是一样的,类型的判断p
numberp integerpnone floatpnone none
;; common-lisp
+ - * / mod
;; racket
+ - * / modulo
;; clojure
+ - * / mod
;; emacs-lisp
+ - * / %
;; common-lisp
(truncate 7 3) ;;=> 2, 1
(rem 7 3) ;;=> 1
;; racket
(quotient 7 3)
(remainder 7 3)
;; clojure
(quot 7 3)
(rem 7 3)
;; emacs-lisp
(/ 7 3)
(% 7 3)
;; common-lisp
division-by-zero error
;; racket
division by zero error
;; clojure
;; emacs-lisp
arith-error
;; common-lisp
rational:
(/ 7 3) ;;=> float: => 7/3 (2.3333333) ;;;=> (= (/ 7 3) 2) => NIL
(/ 7 (* 3 1.0)) ;; => 2.3333333
;; racket
rational:
(/ 7 3)float:
(/ 7 (float 3))
;; clojure
rational:
(/ 7 3)float:
(/ 7 (* 3 1.0))
;; emacs-lisp
integer quotient:
(/ 7 3)float:
(/ 7 (* 3 1.0))
;; common-lisp
division-by-zero error
;; racket
;; clojure
;; emacs-lisp
-1.0e+INF, -0.0e+NaN, or 1.0e+INF
;; common-lisp
(expt 2 32) ;;=> => 4294967296 (33 bits, #x100000000, #o40000000000, #b100000000000000000000000000000000)
;; racket
(expt 2 32)
;; clojure
returns float:
(Math/pow 2 32)
;; emacs-lisp
(expt 2 32) ;; 0, ?
;; common-lisp
(sqrt 2) ;;=> => 1.4142135
;; racket
(sqrt 2)
;; clojure
(Math/sqrt 2)
;; emacs-lisp
(sqrt 2)
;; common-lisp
#c(0.0 1.0)
;; racket
0+1i
;; clojure
(Math/sqrt -1): NaN
;; emacs-lisp
-0.0e+NaN
;; common-lisp
exp log sin cos tan asin acos atan atan ;;=> 周期函数,声波的机器学习,傅里叶分析
;; racket
exp log sin cos tan asin acos atan atan
;; clojure
Math/exp Math/log Math/sin Math/cos Math/tan Math/asin Math/acos Math/atan Math/atan2
;; emacs-lisp 三角函数的,周期的建模
exp log sin cos tan asin acos atan atan
;; common-lisp
return two values, first is integer:
truncate round ceiling floor
;; racket
return floats:
truncate round ceiling floor
;; clojure
return integers:
int Math/roundreturn floats:
Math/ceil Math/floor
;; emacs-lisp
truncate round ceiling floor
fround fceiling ffloortruncate returns integer
;; common-lisp
abs signum
;; racket
absracket: sgn
;; clojure
Math/abs Math/signum
;; emacs-lisp
abs signum
;; common-lisp
none; arbitrary-precision integers
;; racket
none; arbitrary-precision integers
;; clojure
clojure.lang.Numbers.throwIntOverflow exception
;; emacs-lisp
;; common-lisp
floating-point-overflow error
;; racket
;; clojure
not literals:
-Infity NaN Infinity
;; emacs-lisp
;; common-lisp
(/ 3 7); literal:
3/7
;; racket
(/ 3 7); literal:
3/7; also rational:
2.718
(exp 1)
;; clojure
(/ 3 7); literal:
3/7
;; emacs-lisp
;; common-lisp
(numerator 3/7) ;;=> 3
(denominator 3/7) ;;=> 7
;; racket
(numerator 3/7)
(denominator 3/7)
;; clojure
(numerator 3/7)
(denominator 3/7)
;; emacs-lisp
none none
;; common-lisp
#c(1 2) ;;=> ??
;; racket
1+2i
(+ 1 +2i)
;; clojure
none
;; emacs-lisp
none
;; common-lisp
(realpart #c(1 2)) ;; => 1
(imagpart #c(1 2)) ;;=> 2
(phase #c(1 2)) ;;=> 1.1071488
(abs #c(1 2)) ;;=> 2.236068
(conjugate #c(1 2)) ;;=> #C(1 -2)
;; racket
(real-part 1+2i)
(imag-part 1+2i)
(angle 1+2i)
(magnitude 1+2i)
(conjugate 1+2i)
;; clojure
nonenone
;; emacs-lisp
none none
;; common-lisp
(random 100) ;; => 92
(random 1.0) ;; => 0.6700171
;; racket
(random 100)
(random)none
;; clojure
(def rnd (java.util.Random.))
(.nextInt rnd 100)
(.nextFloat rnd)
(.nextGaussian rnd)
;; emacs-lisp
(random 100)
;; common-lisp
(setq *random-state* (sb-ext:seed-random-state 17))
;; racket
(random-seed 17)
;; clojure
;; emacs-lisp
;; common-lisp 位运算
ash left shift when 2nd argument positive logand logior logxor lognot
;; racket
arithmetic-shift left shift when 2nd argument positive bitwise-and bitwise-ior bitwise-xor bitwise-not
;; clojure
bit-shift-left bit-shift-right bit-and bit-or bit-xor bit-not
;; emacs-lisp 位的操作
lsh left shift when 2nd argument positive logand logior logxor lognot
;; common-lisp
#b101010 ;; => 42 (6 bits, #x2A, #o52, #b101010)
#o52 ;;=> 42 (6 bits, #x2A, #o52, #b101010)
#x2a ;;=> 42 (6 bits, #x2A, #o52, #b101010)
;; racket
#b101010
#o52
#x2a
;; clojure
;; emacs-lisp
;; common-lisp
(format nil "~7r" 42) ;;=> "60"
;; racket
;; clojure
;; emacs-lisp
;; common-lisp
(stringp "foo") ;;=> T, (symbolp :abc)=> T
;; racket
(string? "foo")
;; clojure
(string? "foo")
;; emacs-lisp p的类型判断
(stringp "foo")
;; common-lisp
"foo bar"
;; racket
"foo bar"
;; clojure
"foo bar"
;; emacs-lisp
"foo bar"
;; common-lisp
yes
;; racket
yes
;; clojure
yes
;; emacs-lisp
yes
;; common-lisp
\" \\ ;; 特殊字符反引号
;; racket
\t \n \r \" \\ \ooo \uhhhh
;; clojure
\b \t \n \f \r \" \\ \ooo \uhhhh
;; emacs-lisp 特殊字符如换行
\b \t \n \f \r \" \\ \ooo \uhhhh \xh - \xhhhhhh \C-x \M-x
;; common-lisp
;; racket
(string #\f #\o #\o)
;; clojure
;; emacs-lisp 列表转为字符串
(string ?f ?o ?o) ;; foo
;; common-lisp "~,2f" 是浮点型的format
(format nil "~a: ~a ~,2f" "Foo" 7 13.457) ;;=> "Foo: 7 13.46"
;; racket
(format "~a ~a ~a" "Foo" 7 13.457)
;; clojure
(String/format "%s: %d %.2f" (to-array ["Foo" 7 13.457]))
;; emacs-lisp
(format "%s: %d %.2f" "Foo" 7 13.457)
;; common-lisp 各种类型的Format填充方法
~a any type, human readable
~s any time, read parseable
~% newline
~~ tilde
~c character
~,5f 5 digits right of decimal mark
~d decimal
~x hex
~o octal
~b binary
;; racket
~a any type, human readable
~s any time, read parseable
~% newline
~~ tilde
~c character
~d decimal
~x hex
~o octal
~b binary
;; clojure
;; emacs-lisp
;; common-lisp
(string= "foo" "bar") ;;=> NIL ,字符串比较是否相同
(string< "foo" "bar") ;;=> NIL
;; racket
(string=? "foo" "bar")
(string<? "foo" "bar")
;; clojure
(.equals "foo" "bar")
(.compareTo "foo" "bar")
;; emacs-lisp 字母的先后排序大小
(string= "foo" "bar")
(string< "foo" "bar")
;; common-lisp 字符串连接
(concatenate 'string "foo " "bar " "bar") ;;=> "foo bar bar" ,, (concatenate 'string 1 2 3) 是报错的
;; racket
(string-append "foo " "bar " "baz")
;; clojure
(str "foo " "bar " "baz")
;; emacs-lisp 字符串连接
(concat "foo " "bar " "baz")
;; common-lisp
(make-string 3 :initial-element #\f) ;;=> "fff"
;; racket
(make-string 3 #\f)
;; clojure
(String. (into-array (. Character TYPE) (repeat 3 \f)))
;; emacs-lisp 字符串创建
(make-string 3 ?f) ;; fff
;; common-lisp
(string-downcase "FOO") ;;=> "foo"
(string-upcase "foo")
;; racket
(string-downcase "FOO")
(string-upcase "foo")
;; clojure
(.toLowerCase "FOO")
;; emacs-lisp
(downcase "FOO")
(upcase "foo")
;; common-lisp
; "Foo Bar":
(string-capitalize "foo bar") ;;=> "Foo Bar", 驼峰
;; racket
;; clojure
;; emacs-lisp
; "Foo Bar": 类似rails 命名
(capitalize "foo")
;; common-lisp
(string-trim '(#\space #\tab #\newline) " foo ") ;;=> "foo" 去除一些字符串
;; racket
(require srfi/13/string)
(string-trim-both " foo ")
;; clojure
(.trim " foo ")
;; emacs-lisp
none; see notes for an implementation
;; common-lisp
(format nil "~10a" "foo") ;; => "foo "
(format nil "~10@a" "foo") ;;=> " foo"
;; racket
;; clojure
;; emacs-lisp
;; common-lisp
(concatenate 'string "value: " (princ-to-string 8)) ;;=> "value: 8"
;; racket
(string-append "value: " (number->string 8))
;; clojure
(str "Value: " 8)
;; emacs-lisp 这里要注意转换为字符串才可以拼接
(concat "value: " (number-to-string 8))
;; common-lisp
(+ 7 (parse-integer "12")) ;;=> 19 (5 bits, #x13, #o23, #b10011)
(+ 73.9 (read-from-string ".037") #|输出=> 0.037, 4|#) ;;=> 73.937004
;; racket
(+ 7 (string->number "12"))
(+ 73.9 (string->number ".037"))
;; clojure
(+ 7 (Integer/parseInt "12"))
(+ 73.9 (Float/parseFloat ".037"))
;; emacs-lisp
(+ 7 (string-to-number "12"))
(+ 73.9 (string-to-number ".037"))
;; common-lisp
(cl-ppcre:split "[ \t\n]+" "foo bar baz") ;; 必须要安装包=> Package CL-PPCRE does not exist.
;; racket
(regexp-split #rx"[ \n\t]+" "foo bar baz")
;; clojure
(seq (.split "foo bar baz" "[ \t\n]+"))
;; emacs-lisp 这里可以按照正则表达式来切割
(split-string "foo bar baz")
;; common-lisp reduce累加的字符串
(reduce (lambda (m o) (concatenate 'string m " " o)) '("foo" "bar" "baz")) ;;=> "foo bar baz"
;; racket
(string-join '("foo" "bar" "baz") " ")
;; clojure
(reduce #(str %1 " " %2) '("foo" "bar" "baz"))
;; emacs-lisp ruby's inject 求字符串的积分
(reduce (lambda (m o) (concat m "_" o)) '("foo" "bar" "baz")) ; "foo_bar_baz"
;; common-lisp
(length "foo") ;;=> 3 (2 bits, #x3, #o3, #b11)
;; racket
(string-length "foo")
;; clojure
(.length "foo")
;; emacs-lisp
(length "foo")
;; common-lisp
(search "bar" "foo bar") ;;=> 4 (3 bits, #x4, #o4, #b100)
;; racket
racket:
(require srfi/13/string)
(string-contains "foo bar" "bar")
;; clojure
(.indexOf "foo bar" "bar")
;; emacs-lisp 搜索得到一个数字,说明是存在的,并且知道它所在的位置
(search "bar" "foo bar") ; 4
;; common-lisp
(subseq "foo bar" 4 7)
;; racket
(substring "foo bar" 4 7)
;; clojure
(.substring "foo bar" 4 7)
;; emacs-lisp 根据位置来拿到字符串
(substring "foo bar" 4 7)
;; common-lisp
#\a #\space #\newline #\backspace #\tab #\linefeed #\page #\return #\rubout
;; racket
#\a #\space #\newline #\backspace #\tab #\linefeed #\page #\return #\nul #\vtab #\alarm #\esc #\deletenot in racket: #\alarm #\esc #\delete
;; clojure
\a \newline \space \backspace \tab ? \formfeed \return ?
;; emacs-lisp 一些特殊的字符串
?a ?\b ?\t ?\n ?\f ?\r ?\" ?\\ ?\ooo ?\uhhhh ?\xh - ?\xhhhhhh ?\C-x ?\M-x
;; common-lisp
(characterp #\x)
(alpha-char-p #\x)
(alphanumericp #\x)
(digit-char-p #\7)
(lower-case-p #\x)
(upper-case-p #\X)
;; racket
(char? #\x)
;; clojure
(char? \x)
;; emacs-lisp 这里的问号是代表什么东西呢, char
(characterp ?x) ; t
;; common-lisp
(code-char 97)
(char-code #\a)
;; racket
(integer->char 97)
(char->integer #\a)
;; clojure
(char 97)
(int \a)
;; emacs-lisp
;; common-lisp
;; racket
; list:
(string->list "foo")
;; clojure
;; emacs-lisp
;; common-lisp
(char "foo" 0)
;; racket
(string-ref "foo" 0)
;; clojure
(.charAt "foo" 0)
;; emacs-lisp 这里的应该是不同于环境查找变量
(aref "foo" 2) ; 0 => 102, 2 => 111
;; common-lisp
use a string:
"\\b\\d{5}\\b"
;; racket
posix extended:
#rx"^[0-9][0-9][0-9][0-9][0-9]$"
(regexp "^[0-9][0-9][0-9][0-9][0-9]$")perl style:
#px"\\b\\d{5}\\b"
(pregexp "\\b\\d{5}\\b")
;; clojure
#"\b\d{5}\b"
;; emacs-lisp
;; common-lisp
. \d \D \s \S \w \W
;; racket
regexp:
.pregexp:
. \d \D \s \S \w \W
;; clojure
. \d \D \s \S \w \W
;; emacs-lisp
. \w \W \ca \cl \cg \Ca \Cl \Cg \sx\ca \cl and \cg match ASCII, Latin, and Greek characters.Character classes of the form \sx depend on the current syntax table.
;; common-lisp
^ $ \b \B
;; racket
regexp:
^ $pregexp:
^ $ \b \B
;; clojure
^ $ \A \b \B \G \z \Z
;; emacs-lisp
^ $ \b \B
;; common-lisp
(ql:quickload "cl-ppcre")
(if (cl-ppcre:all-matches "1999" s) (format t "party!"))
;; racket
(regexp-match #rx"bar" "foo bar")
;; clojure
(re-find #"bar" "foo bar")
;; emacs-lisp 这里就像红宝石的 =~
(string-match "bar" "foo bar")
;; common-lisp
;; racket
(regexp-match #px"(?i:lorem)" "Lorem")
;; clojure
(re-find #"(?i:lorem)" "Lorem")
;; emacs-lisp
;; common-lisp
(cl-ppcre:regex-replace "[^l]l" "hello" "EL")
(cl-ppcre:regex-replace-all "[^l]l" "hello hello" "EL")
;; racket
(regexp-replace #rx"el" "hello" "EL")
(regexp-replace* #rx"el" "hello hello" "EL")
;; clojure
(.replaceFirst "hello" "[^l]l" "XX")
(.replaceAll "hello hello" "[^l]l" "XX")
;; emacs-lisp 这里就像红宝石的gsub
?
(replace-regexp-in-string "[^l]l" "EL" "hello hello")
;; common-lisp
;; racket
(match (regexp-match #px"(\\d{4})-(\\d{2})-(\\d{2})" "2010-06-03") [(list s yr mn dy) (list yr mn dy)])
;; clojure
(let [[_ yr mn dy] (re-find #"(\d{4})-(\d{2})-(\d{2})" "2010-06-03")] yr)
;; emacs-lisp
;; common-lisp
;; racket
;; clojure
(re-seq #"\w+" "dolor sit amet")
;; emacs-lisp
;; common-lisp
;; racket
(regexp-match #px"(\\w+) \\1" "do do")
(regexp-replace #px"(\\w+) (\\w+)" "do re" "\\2 \\1")
;; clojure
;; emacs-lisp
;; common-lisp
No dedicated type; a list of 9 values is used: 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 for Mon-Sun is daylight savings time: t or nil timezone: negated UTC offset in hours
;; racket
;; clojure
;; emacs-lisp
;; common-lisp
(get-decoded-time)
;; racket
(require racket/date)
(current-date)
;; clojure
(def dt (new java.util.Date))
;; emacs-lisp 可以通过时间的先后顺序来判断运算,逻辑的先后顺序
(current-time)
;; common-lisp
gray|; seconds since Jan 1, 1900:##
(get-universal-time)
;; racket
(current-seconds)
;; clojure
(/ (System/currentTimeMillis) 1000.0)
;; emacs-lisp
(float-time)
;; common-lisp
(decode-universal-time (get-unversal-time))
;; racket
(seconds->date (current-seconds))
;; clojure
(def dt (new java.util.Date (System/currentTimeMillis)))
;; emacs-lisp
(seconds-to-time (float-time))
;; common-lisp
(encode-universal-time 0 22 10 31 5 2015)
;; racket
(require racket/date)
(date->seconds (current-date))
;; clojure
(/ (.getTime (new java.util.Date)) 1000.0)
;; emacs-lisp
(multiple-value-bind (b s) (current-time) (+ (* b (expt 2 16)) s))
;; common-lisp
;; racket
;; clojure
(def s "yyyy-MM-dd HH:mm:ss")
(def fmt (new java.text.SimpleDateFormat s))
(.format fmt (new java.util.Date))
;; emacs-lisp
(format-time-string "%Y-%m-%d %H:%M:%S" (current-time))
;; common-lisp
;; racket
(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")
;; clojure
(def s "yyyy-MM-dd HH:mm:ss")
(def fmt (new java.text.SimpleDateFormat s))
(.parse fmt "2015-05-30 09:14:14")
;; emacs-lisp
;; common-lisp
(multiple-value-bind (ss mi hr dy mo yr) (get-decoded-time) (list ss mi hr) ; quiesce warning (list dy mo yr))
;; racket
(date-year (current-date))
(date-month (current-date))
(date-day (current-date))
;; clojure
(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)
;; emacs-lisp
(multiple-value-bind (ss mi hr dy mo yr) (decode-time (current-time)) (list dy mo yr))
;; common-lisp
(multiple-value-bind (ss mi hr) (get-decoded-time) (list ss mi hr))
;; racket
(date-hour (current-date))
(date-minute (current-date))
(date-second (current-date))
;; clojure
(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)
;; emacs-lisp
(multiple-value-bind (ss mi hr dy mo yr) (decode-time (current-time)) (list ss mi hr))
;; common-lisp
(encode-universal-time 0 22 10 31 5 2015)
;; racket
;; clojure
(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)))
;; emacs-lisp
(encode-time 0 50 8 31 5 2015)
;; common-lisp
'(1 2 3)
(quote (1 2 3))
;; racket
'(1 2 3)
'[1 2 3]
'{1 2 3}
(quote (1 2 3))
;; clojure
'(1 2 3)
(quote (1 2 3))
;; emacs-lisp
'(1 2 3)
(quote (1 2 3))
;; common-lisp
(list 1 2 3)
;; racket
(list 1 2 3)
;; clojure
(list 1 2 3)
;; emacs-lisp
(list 1 2 3)
;; common-lisp
(listp '(1 2 3))
;; racket
(list? '(1 2 3))
;; clojure
(list? '(1 2 3))
;; emacs-lisp 判断是不是列表
(listp '(1 2 3))
;; common-lisp
nil and '() are synonyms and evaluate as false in a boolean context. All other values are true.
;; racket
(empty? '())
;; clojure
(empty? ())
;; emacs-lisp
nil and '() are synonyms and evaluate as false in a boolean context. All other values are true.
;; common-lisp
nil
;; racket
error
;; clojure
()
;; emacs-lisp
nil
;; common-lisp
(cons 1 '(2 3))
;; racket
(cons 1 '(2 3))
;; clojure
(cons 1 '(2 3))
;; emacs-lisp 连接列表
(cons 1 '(2 3))
;; common-lisp
(car '(1 2 3))
(first '(1 2 3))
;; racket
(car '(1 2 3))
(first '(1 2 3))
;; clojure
first
;; emacs-lisp 取列表的第一个
car
;; common-lisp
(cdr '(1 2 3))
(rest '(1 2 3))
;; racket
(cdr '(1 2 3))
(rest '(1 2 3))
;; clojure
(rest '(1 2 3))
(next '(1 2 3))
;; emacs-lisp 取除了第一个列表
(cdr '(1 2 3))
(rest '(1 2 3))
;; common-lisp
both evaluate to nil
;; racket
error
;; clojure
()
;; emacs-lisp
both evaluate to nil
;; common-lisp
(length '(1 2 3))
;; racket
(length '(1 2 3))
;; clojure
(count '(1 2 3))
;; emacs-lisp
(length '(1 2 3))
;; common-lisp
(equal '(1 2 3) '(1 2 3))
;; racket
(equal? '(1 2 3) '(1 2 3))
;; clojure
(= '(1 2 3) '(1 2 3))
;; emacs-lisp 这里是eq增强版,可以判断整一个列表是不是相同
(equal '(1 2 3) '(1 2 3))
;; common-lisp
; indexed from zero:
(nth 2 '(1 2 3 4))
;; racket
(list-ref '(1 2 3 4) 2)
;; clojure
(nth '(1 2 3 4) 2)
;; emacs-lisp 直接根据列表的位置去取,和clojure一样的
(nth 2 '(1 2 3 4))
;; common-lisp
nil
;; racket
error
;; clojure
raises IndexOutOfBoundsException
;; emacs-lisp
nil
;; common-lisp
(position 7 '(5 6 7 8))
;; racket
(require srfi/1)
(list-index (lambda (x) (= x 7)) '(5 6 7 8))
;; clojure
none
;; emacs-lisp 根据值来得到位置所在
(position 7 '(5 6 7 8)) ; 2
;; common-lisp
(append '(1 2 3) '(4 5 6))
;; racket
(append '(1 2 3) '(4 5 6))
;; clojure
(concat '(1 2 3) '(4 5 6))
;; emacs-lisp 拼接两个大的列表
(append '(1 2 3) '(4 5 6)) ; ( 1 2 3 4 5 6)
;; common-lisp
none
;; racket
(take '(1 2 3 4) 2)
;; clojure
(take 2 '(1 2 3 4))
;; emacs-lisp
none
;; common-lisp
(nthcdr 2 '(1 2 3 4))
;; racket
(drop '(1 2 3 4) 2)
;; clojure
(drop 2 '(1 2 3 4))
;; emacs-lisp 切割部分列表
(nthcdr 2 '(1 2 3 4)) ; (3 4)
;; common-lisp
(car (last '(1 2 3)))
;; racket
(last '(1 2 3))
;; clojure
(last '(1 2 3))
;; emacs-lisp first对应的last
(car (last '(1 2 3)))
;; common-lisp
(butlast '(1 2 3))
;; racket
(define a '(1 2 3))
(take a (- (length a) 1))
;; clojure
(butlast '(1 2 3))
;; emacs-lisp 对应的rest
(butlast '(1 2 3)) ; (2 3)
;; common-lisp
(reverse '(1 2 3))
;; racket
(reverse '(1 2 3))
;; clojure
(reverse '(1 2 3))
;; emacs-lisp
(reverse '(1 2 3))
;; common-lisp
(sort '(3 2 4 1) '<)
;; racket
(sort '(3 2 4 1) <)
;; clojure
(sort < '(3 2 4 1))
;; emacs-lisp
(sort '(3 2 4 1) '<)
;; common-lisp
(remove-duplicates '(1 1 2 3))
;; racket
(remove-duplicates '(1 1 2 3))
;; clojure
;; emacs-lisp, uniq
(remove-duplicates '(1 1 2 3))
;; common-lisp
(member 7 '(1 2 3))
;; racket
(member 7 '(1 2 3))
;; clojure
;; emacs-lisp ??? ====
(member 7 '(2 2 3)) ;nil
;; common-lisp
(mapcar (lambda (x) (* x x)) '(1 2 3))
;; racket
(map (lambda (x) (* x x)) '(1 2 3))
;; clojure
(map #(* % %) '(1 2 3))
;; emacs-lisp , mapcar is c code
;; (-map (lambda (x) (* x x)) '(1 2 3)) ;; dash
(mapcar (lambda (x) (* x x)) '(1 2 3)) ;; (1 4 9)
;; common-lisp
(remove-if-not (lambda (x) (> x 2)) '(1 2 3)); remove-if returns complement
;; racket
(filter (lambda (x) (> x 2)) '(1 2 3)); filter-not returns complement
;; clojure
(filter #(> % 2) '(1 2 3)); remove returns complement
;; emacs-lisp, ruby select
(remove-if-not (lambda (x) (> x 2)) '(1 2 3)); remove-if returns complement
;; common-lisp
(reduce '- '(1 2 3 4) :initial-value 0)
;; racket
(foldl (lambda (x y) (- y x)) 0 '(1 2 3 4))
;; clojure
(reduce - 0 '(1 2 3 4))
;; emacs-lisp
(reduce '- '(1 2 3 4) :initial-value 0) ; -10
;; common-lisp
(reduce '- '(1 2 3 4) :initial-value 0 :from-end t)
;; racket
(foldr - 0 '(1 2 3 4))
;; clojure
none
;; emacs-lisp
(reduce '- '(1 2 3 4) :initial-value 0 :from-end t) ;; -2
;; common-lisp
(dolist (x '(1 2 3)) (print x) (print (- x)))
;; racket
(for ((x '(1 2 3))) (printf "~a~n" x) (printf "~a~n" (- x)))
;; clojure
(doseq [x '(1 2 3)] (println x) (println (- x)))
;; emacs-lisp
(dolist (x '(1 2 3)) (print x) (print (- x))) ;; doseq
;; common-lisp
(every (lambda (i) (= 0 (rem i 2))) '(1 2 3 4))
;; racket
(for/and ((i '(1 2 3 4))) (= 0 (remainder i 2)))
;; clojure
(every? #(= 0 (rem % 2)) '(1 2 3 4))
;; emacs-lisp
(every (lambda (i) (= 0 (% i 2))) '(1 2 3 4))
;; common-lisp
(some (lambda (i) (= 0 (rem i 2))) '(1 2 3 4))
;; racket
(for/or ((i '(1 2 3 4))) (= 0 (remainder i 2)))
;; clojure
(some #(= 0 (rem % 2)) '(1 2 3 4))
;; emacs-lisp
(some (lambda (i) (= 0 (% i 2))) '(1 2 3 4)) ; t
;; common-lisp
;; racket
(for*/list ((file "ABCDEFGH") (rank (in-range 1 9))) (format "~a~a" file rank))
;; clojure
(for [file "ABCDEFGH" rank (range 1 9)] (format "%c%d" file rank))
;; emacs-lisp
;; common-lisp
;; racket
(shuffle '(1 2 3 4))
;; clojure
(shuffle '(1 2 3 4))
;; emacs-lisp
;; common-lisp
(defparameter *a* '(1 2 3))
(setf (car *a*) 3)
;; racket
(require schema/mpair)
(define a (mlist 1 2 3))
(set-mcar! a 3)
;; clojure
none
;; emacs-lisp
(setq a '(1 2 6 4 5))
(setcar a 3) ; 3, (3 2 7 4 5)
;; common-lisp
(defparameter *a* '(1 2 3))
(setf (cdr *a*) '(4 5 6))
;; racket
(require schema/mpair)
(define a (mlist 1 2 3))
(set-mcdr! a (mlist 4 5 6))
;; clojure
none
;; emacs-lisp
(setq a '(1 2 3)
(setcar a 3)
(setcdr a '(4 5 6))
;; common-lisp
(defparameter *a* '(1 2 3))
(push 4 *a*)
(pop *a*)
;; racket
none
;; clojure
;; emacs-lisp
(setq a '(1 2 3))
(push 4 a)
(pop a)
;; common-lisp
;; racket
(flatten '(1 2 (3 (4))))
;; clojure
(flatten '(1 2 (3 (4))))
;; emacs-lisp
;; common-lisp
(assoc 3 '((1 2) (3 4)))
;; racket
(assoc 3 '((1 2) (3 4)))
;; clojure
none, see note
;; emacs-lisp
(assoc 3 '((1 2) (3 4)))
;; common-lisp
(getf '(1 2 3 4) 3)
;; racket
none
;; clojure
none
;; emacs-lisp
(getf '(1 2 3 4) 3)
;; common-lisp
'(1 . 2)
;; racket
'(1 . 2)
;; clojure
none
;; emacs-lisp
'(1 . 2)
;; common-lisp
(cons '(1 . 2))
(not (atom '(1 . 2)))
;; racket
(cons? '(1 . 2))
(pair? '(1 . 2))
;; clojure
none
;; emacs-lisp
(cons '(1 . 2))
(not (atom '(1 . 2)))
;; common-lisp
(sublis '((1 . 2) (3 . 4)) '(1 (3 3 (1))))
;; racket
;; clojure
;; emacs-lisp
(sublis '((1 . 2) (3 . 4)) '(1 (3 3 (1))))
;; common-lisp
#(1 2 3)
;; racket
#(1 2 3)
;; clojure
[1 2 3]
;; emacs-lisp
[1 2 3]
;; common-lisp
(vector 1 2 3)
;; racket
(vector 1 2 3)
;; clojure
(vector 1 2 3)
;; emacs-lisp
(vector 1 2 3)
;; common-lisp
(length #(1 2 3))
;; racket
(vector-length #(1 2 3))
;; clojure
(count [1 2 3])
;; emacs-lisp
(length [1 2 3])
;; common-lisp
(elt #(1 2 3) 0) or
(aref #(1 2 3) 0)
;; racket
(vector-ref #(1 2 3) 0)
;; clojure
(nth [1 2 3] 0)
;; emacs-lisp
(elt [1 2 3] 0)
;; common-lisp
(setq v [1 2 3])
(setf (aref v 2) 4)
;; racket
(define v (vector 1 2 3))
(vector-set! v 2 4)
;; clojure
(replace {2 4} [1 2 3])
;; emacs-lisp
(setq v #(1 2 3))
(setf (aref v 2) 4)
;; common-lisp
raises sb-kernel:index-too-large-error
;; racket
error
;; clojure
;; emacs-lisp
;; common-lisp
(coerce #(1 2 3) 'list)
;; racket
(vector->list #(1 2 3))
;; clojure
(seq [1 2 3])
;; emacs-lisp
(coerce [1 2 3] 'list)
;; common-lisp
(coerce '(1 2 3) 'vector)
;; racket
(list->vector '(1 2 3))
;; clojure
(vec '(1 2 3))
;; emacs-lisp
(coerce '(1 2 3) 'vector)
;; common-lisp
(reverse #(1 2 3))
;; racket
;; clojure
;; emacs-lisp
;; common-lisp
(sort #(2 4 1 3) #'<)
;; racket
;; clojure
;; emacs-lisp
;; common-lisp
(map 'vector (lambda (x) (* x x)) #(1 2 3))
;; racket
;; clojure
;; emacs-lisp
;; common-lisp
(remove-if-not (lambda (x) (> x 2)) #(1 2 3)); also remove-if
;; racket
;; clojure
;; emacs-lisp
;; common-lisp
;; racket
;; clojure
;; emacs-lisp
;; common-lisp
none
;; racket
; immutable:
#hash(("t" . 1) ("f" . 0))
;; clojure
; clojure.lang.PersistentArrayMap:
{"t" 1 "f" 0}
;; emacs-lisp
none
;; common-lisp
(defparameter *h* (make-hash-table :test 'equal)); default equality test is 'eql
;; racket
(define ih (make-immutable-hash '(("t" . 1) ("f" . 0)))); mutable:
(define h (make-hash '(("t" . 1) ("f" . 0))))
;; clojure
; immutable:
(def ih (hash-map "t" 1 "f" 0))
;; emacs-lisp
(setq h (make-hash-table :test 'equal))
;; common-lisp
(hash-table-p *h*)
;; racket
(hash? h); also true of assoc. lists and vectors:
(dict? h)
;; clojure
(map? ih)
;; emacs-lisp
(hash-table-p h)
;; common-lisp
(hash-table-count *h*)
;; racket
(hash-count h); also works with assoc lists and vectors:
(dict-count ih)
;; clojure
(count ih)
;; emacs-lisp
(hash-table-count h)
;; common-lisp
(gethash "t" *h*)
;; racket
(hash-ref h "t"); return -1 if not found:
(hash-ref h "m" -1); also works with assoc. lists and vectors:
(dict-ref ih "t")
(dict-ref ih "m" -1)
;; clojure
(get ih "t")
(find ih "t"); return -1 if not found:
(get ih "m" -1)
;; emacs-lisp
(gethash "t" h)
;; common-lisp
(setf (gethash "t" *h*) 1)
;; racket
(hash-set! h "t" 2)
(define ih2 (hash-set ih "t" 2)); also dict-set! and dict-set
;; clojure
(def ih2 (assoc ih "t" 2))
;; emacs-lisp
(puthash "t" 1 h)
;; common-lisp
returns nil
;; racket
error
;; clojure
returns nil
;; emacs-lisp
returns nil
;; common-lisp
(nth-value 1 (gethash "t" *h*))
;; racket
(hash-has-key? h "t"); also dict-has-key?
;; clojure
(contains? ih "t")
;; emacs-lisp
none
;; common-lisp
(remhash "t" *h*)
;; racket
(hash-remove! h "t")
(define ih2 (hash-remove ih "t")); also dict-remove! and dict-remove
;; clojure
(def ih2 (dissoc ih "t"))
;; emacs-lisp
(remhash "hello" h)
;; common-lisp
;; racket
;; clojure
; values in ih2 take precedence:
(define ih3 (merge ih ih2))
;; emacs-lisp
;; common-lisp
;; racket
;; clojure
(require 'clojure.set)
(define ih4 (clojure.set/map-invert ih))
;; emacs-lisp
;; common-lisp
(maphash (lambda (k v) (print k) (print v)) *h*)
;; racket
(hash-for-each h (lambda (k v) (printf "~a~n" k) (printf "~a~n" v))); also dict-for-each
;; clojure
(doseq [p ih] (println (first p)) (println (second p)))
;; emacs-lisp
(maphash (lambda (k v) (print k) (print v)) h)
;; common-lisp
none
;; racket
(hash-keys h)
(hash-values h); also dict-keys and dict-values
;; clojure
(def hkeys (map (fn [p] (first p)) ih))
(def hvals (map (fn [p] (second p)) ih))
;; emacs-lisp
none
;; common-lisp
(defstruct account id balance)
;; racket
(define-struct account (id (balance #:mutable)))
;; clojure
(defstruct account :id :balance)
;; emacs-lisp
(defstruct account id balance)
;; common-lisp
(setq a (make-account :id 3 :balance 17.12))
;; racket
(define a (make-account 3 17.12))
;; clojure
(def a (struct account 3 17.12))
;; emacs-lisp
(setq a (make-account :id 3 :balance 17.12))
;; common-lisp
(account-id a)
;; racket
(account-id a)
;; clojure
(:id a)
;; emacs-lisp
(account-id a)
;; common-lisp
(setf (account-balance a) 0)
;; racket
(set-account-balance! a 0)
;; clojure
none
;; emacs-lisp
(setf (account-balance a) 0)
;; common-lisp
(account-p a)
;; racket
(account? a)
;; clojure
none
;; emacs-lisp
(account-p a)
;; common-lisp
(defun add (x y) (+ x y))
;; racket
(define (add x y) (+ x y))
;; clojure
(defn add [x y] (+ x y))
;; emacs-lisp
(defun add (x y) (+ x y))
;; common-lisp
yes
;; racket
no
;; clojure
no
;; emacs-lisp
yes
;; common-lisp
(defun add (a &optional b) (if (null b) a (+ a b)))
;; racket
(define (add a (b null)) (if (null? b) a (+ a b)))
;; clojure
(defn add ([a] a) ([a b] (+ a b)))no syntax error if called with more than 2 args:
(defn add [a & [b]] (if (nil? b) a (+ a b)))
;; emacs-lisp
(defun add (a &optional b) (if (null b) a (+ a b))) ;; like ruby *args
(add 1) ; 1
(add 1 2) ; 2
;; common-lisp
(defun add (a &rest b) (if (null b) a (+ a (eval (cons '+ b)))))
;; racket
(define (add a . b) (if (null? b) a (+ a (apply + b))))
;; clojure
(defn add [a & b] (if (nil? b) a (+ a (apply + b))))
;; emacs-lisp
(defun add (a &rest b) (if (null b) a (+ a (eval (cons '+ b)))))
(add 1) ; 1
(add 1 2) ; 3
;; common-lisp
(defun add (a &optional (b 0)) (+ a b))
;; racket
racket:
(define (add a (b 0)) (+ a b))
;; clojure
(defn add ([a] (add a 0)) ([a b] (+ a b)))
;; emacs-lisp
none
;; common-lisp
(defun logarithm (&key number base) (/ (log number) (log base)))
(logarithm :base 2 :number 8)
;; racket
none
;; clojure
(defn logarithm [{x :number b :base}] (/ (Math/log x) (Math/log b)))
(logarithm {:base 2 :number 8})
;; emacs-lisp
(defun logarithm (&key number &key base) (if base (/ (log number) (log base)) (log number))) order significant, not key names:
(logarithm :foo 8 :bar 2)
;; common-lisp
(defun sqrts (x) (values (sqrt x) (- (sqrt x))))
;; racket
(define (sqrts x) (values (sqrt x) (- (sqrt x))))
;; clojure
(defn sqrts [x] (list (Math/sqrt x) (- (Math/sqrt x))))
;; emacs-lisp
values creates a list:
(defun sqrts (x) (values (sqrt x) (- (sqrt x))))
;; common-lisp
(multiple-value-bind (r1 r2) (sqrts 3) r2)
;; racket
(let-values (((r1 r2) (sqrts 3))) r2)
;; clojure
(let [[r1 r2] (sqrts 3)] r2)
;; emacs-lisp
(multiple-value-bind (r1 r2) (sqrts 3) r2)
;; common-lisp
(multiple-value-setq (r1 r2) (sqrts 3))
;; racket
(define-values (r1 r2) (sqrts 3))
;; clojure
none
;; emacs-lisp
(multiple-value-setq (r1 r2) (sqrts 3))
;; common-lisp
(values-list '(1 2 3))
;; racket
(apply values '(1 2 3))
;; clojure
multiple values are lists
;; emacs-lisp
multiple values are lists
;; common-lisp
(multiple-value-list (sqrts 3))
;; racket
(call-with-values (lambda () (sqrts 3)) list)
;; clojure
multiple values are lists
;; emacs-lisp
multiple values are lists
;; common-lisp
yes for sbcl
;; racket
yes
;; clojure
yes with recur
;; emacs-lisp
no
;; common-lisp
(lambda (x) (* x x))
;; racket
(lambda (x) (* x x))
;; clojure
#(* % %)
(fn [x] (* x x)); shortcut notation with two args:
#(* %1 %2)
;; emacs-lisp
(lambda (x) (* x x))
;; common-lisp
((lambda (x) (* x x)) 2)
(apply #'(lambda (x) (* x x)) '(2))
;; racket
((lambda (x) (* x x)) 2)
(apply (lambda (x) (* x x)) '(2))
;; clojure
(#(* % %) 2)
((fn [x] (* x x)) 2)
(apply #(* % %) '(2))
;; emacs-lisp
((lambda (x) (* x x)) 2)
(apply #'(lambda (x) (* x x)) '(2))
;; common-lisp
progn prog1 prog2
;; racket
begin none noner6rs:
begin begin0 none
;; clojure
do none none
;; emacs-lisp
progn prog1 prog2
;; common-lisp
(setq i 1)
(loop (print "hello") (if (> i 10) (return) (setq i (+ i 1))))
;; racket
none, use recursion
;; clojure
(loop [i 1] (if (<= i 10) (do (println "hello") (recur (+ i 1)))))
;; emacs-lisp
(setq i 1)
(loop (print "hello") (if (> i 10) (return) (setq i (+ i 1))))
;; common-lisp
(do ((i 1) (sum 0)) ((> i 100) sum) (setq sum (+ sum i)) (setq i (+ i 1)))do* initializes serially
;; racket
none
;; clojure
none
;; emacs-lisp
(do ((i 1) (sum 0)) ((> i 100) sum) (setq sum (+ sum i)) (setq i (+ i 1)))do* initializes sequentially
;; common-lisp
(dotimes (i 10 nil) (format t "hello~%"))
;; racket
none
;; clojure
(dotimes [_ 10] (println "hello"))
;; emacs-lisp
(dotimes (i 10 nil) (print "hello\n"))
;; common-lisp
(if (< x 0) (- x) x)
;; racket
(if (< x 0) (- x) x)
;; clojure
(if (< x 0) (- x) x)
;; emacs-lisp
(if (< x 0) (- x) x)
;; common-lisp
(when (< x y) (print "x is less ") (print "than y"))
;; racket
racket:
(when (< x y) (display "x is less ") (display "than y"))
;; clojure
(when (< x y) (println "x is less ") (println "than y"))
;; emacs-lisp
(when (< x y) (print "x is less ") (print "than y"))
;; common-lisp
(cond ((> x 0) 1) ((= x 0) 0) (t -1))
;; racket
(cond ((> x 0) 1) ((= x 0) 0) (else -1))
;; clojure
(cond (> x 0) 1 (= x 0) 0 true -1)
;; emacs-lisp
(cond ((> x 0) 1) ((= x 0) 0) (t -1))
;; common-lisp
;; racket
(define x (delay (/ 1 0)))
(promise? x)
(+ 1 (force x))
;; clojure
;; emacs-lisp
;; common-lisp
;; racket
(define cc null)
(+ 1 (call/cc (lambda (x) (set! cc x) 0)))
(cc 5)
;; clojure
;; emacs-lisp
;; common-lisp
(error "failed")
;; racket
(error "failed")
;; clojure
(throw (Exception. "failed"))
;; emacs-lisp
(error "failed")
;; common-lisp
(handler-case (error "failed") (simple-error (e) (format t "error: ~a" e)))
;; racket
(with-handlers ((exn:fail? (lambda (e) (printf "error: ~a" (exn-message e))))) (error "failed"))
;; clojure
(try (throw (Exception. "failure")) (catch Exception e (printf "error: %s" (.getMessage e))))
;; emacs-lisp
(condition-case e (error "failed") (error (message "error: %s" (error-message-string e))))
;; common-lisp
(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)))))
;; racket
(define exn:odd-err? "odd number")
;; clojure
;; emacs-lisp
only symbols and keywords can be thrown and caught
;; common-lisp
(error 'odd-err :num 7)
;; racket
(raise exn:odd-err?)
;; clojure
(throw (Exception. "failed"))
;; emacs-lisp
(throw 'odd-err t)
;; common-lisp
(handler-case (/ 1 0) (division-by-zero () (progn (format t "division by zero") nil)))
;; racket
(with-handlers ((exn:fail? (lambda (e) (begin (printf "division by zero~n") null)))) (/ 1 0))
;; clojure
(try (/ 1 0) (catch ArithmeticException _ (do (println "division by zero") nil)))
;; emacs-lisp
(catch 'failed (throw 'failed nil) t)
;; common-lisp
(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))
;; racket
;; clojure
none
;; emacs-lisp
none
;; common-lisp
(handler-bind ((odd-err (lambda (c) (invoke-restart 'round-down)))) (halve '(1 2 4 9)))
;; racket
;; clojure
none
;; emacs-lisp
none
;; common-lisp
(unwind-protect (error "failure") (print "clean up"))
;; racket
none
;; clojure
(try (throw (Exception. "failure")) (finally (println "clean up")))
;; emacs-lisp
(unwind-protect (error "failure") (print "clean up"))
;; common-lisp
*standard-input*
*standard-output*
*error-output*
;; racket
(current-input-port)
(current-output-port)
(current-error-port)
;; clojure
*in*
*out*
*err*
;; emacs-lisp
;; common-lisp
read-line returns two values, the 2nd set to T at end-of-file.
EOF-OF-FILE is signaled when reading past end of file.
;; racket
Returns the value eof.Use eof-object? to test for it.
;; clojure
.readLine on a java.io.Reader object returns nil.
;; emacs-lisp
;; common-lisp
(setq line (read-line))
;; racket
(let ((s (read-line))) #|use s|#)
;; clojure
(let [s (read-line)] (comment use s))
;; emacs-lisp
;; common-lisp
;; racket
read-line discards newline
;; clojure
read-line discards newline
;; emacs-lisp
;; common-lisp
(defun println (s) (format t "~a~%" s))
(println "hello")
;; racket
(write-string s)
(newline)
;; clojure
(println "hello")
;; emacs-lisp
;; common-lisp
(format t "~s ~d: ~2$~%" "foo" 7 13.7)
;; racket
(printf "~a ~a: ~a~n" "foo" 7 (/ (round (* 13.7 100)) 100))
;; clojure
(printf "%s %d %.2f\n" "foo" 7 13.7)
;; emacs-lisp
;; common-lisp
(setq in (open "/etc/hosts"))
;; racket
(let ((f (open-input-file "/etc/hosts"))) #| use f |#)
;; clojure
; f is java.io.Reader object:
(let [f (clojure.java.io/reader "/etc/hosts")] (.readLine f))
;; emacs-lisp
;; common-lisp
(setq out (open "/tmp/test" :direction :output :if-exists :supersede))
;; racket
(let ((f (open-output-file "/tmp/foo" #:exists 'truncate))) #| use f |#)
;; clojure
; f is java.io.Writer object:
(let [f (clojure.java.io/writer "/tmp/foo")] (.write f "lorem ipsum\n") (.close f))
;; emacs-lisp
;; common-lisp
(setq out (open "/tmp/test" :direction :output :if-exists :append))
;; racket
(let ((f (open-output-file "/tmp/foo" #:exists 'append))) #| use f |#)
;; clojure
(let [f (clojure.java.io/writer "/tmp/foo" :append true)] (.write f "lorem ipsum\n") (.close f))
;; emacs-lisp
;; common-lisp
(close in)
;; racket
(close-input-port f)
(close-output-port f)
;; clojure
(.close f)
;; emacs-lisp
;; common-lisp
(with-open-file (out #P"/tmp/test" :direction :output) (write-line "lorem ipsum" out))
;; racket
(call-with-input-file "/etc/hosts" (lambda (f) (#| use f |#)); also call-with-output-file
;; clojure
(with-open [f (clojure.java.io/reader "/etc/hosts")] (comment use f))
;; emacs-lisp
;; common-lisp
(setq line (read-line f))
;; racket
(define line (read-line in))
;; clojure
(.readLine f)
;; emacs-lisp
;; common-lisp
;; racket
(for ([line (in-lines (open-input-file "/etc/hosts"))]) (write-string line) (newline))
;; clojure
(loop [line (.readLine f)] (if (not= line nil) (do (println line) (recur (.readLine f)))))
;; emacs-lisp
;; common-lisp
;; racket
; to list of strings:
(sequence->list (in-lines (open-input-file "/etc/hosts")))
;; clojure
(vec (line-seq f))
;; emacs-lisp
;; common-lisp
;; racket
(define s (file->string "/etc/hosts"))
;; clojure
(let [s (slurp "/etc/hosts")] (print s))
;; emacs-lisp
;; common-lisp
;; racket
(write-string s f)
;; clojure
(.write f s)
;; emacs-lisp
;; common-lisp
;; racket
(write-string s f)
(newline f)
;; clojure
(.write f (println-str s))
;; emacs-lisp
;; common-lisp
;; racket
(flush-output f)
;; clojure
(f .flush)
;; emacs-lisp
;; common-lisp
;; racket
; Evaluates to non-negative integer:
(file-position f); Sets next read or write
; to beginning of file:
(file-position f 0)
;; clojure
; arg is characters from current position;
; moving backward not possible:
(.skip f 1000); arg is max characters to buffer:
(.mark f 1000000); move to position saved when .mark was called:
(.rest f)
;; emacs-lisp
;; common-lisp
(setq f (make-string-input-stream "lorem ipsum"))
(read-line f)
(setq f2 (make-string-output-stream)
(write-string "lorem ipsum)
(get-output-stream-string out)
;; racket
(define f (open-input-string "lorem ipsum"))
(read-line f)
(define f2 (open-output-string))
(write-string "lorem ipsum" f2)
(get-output-string f2)
;; clojure
; use *in* to read from string:
(with-in-str "lorem ispum" (read-line)); use *out* to write to string:
(with-out-str (println "lorem ipsum"))
;; emacs-lisp
;; common-lisp
;; racket
;; clojure
;; emacs-lisp
;; list of buffer objects:
(buffer-list);; name of first buffer in list:
(buffer-name (car (buffer-list)));; name of current buffer:
(buffer-name (current-buffer))
;; common-lisp
;; racket
;; clojure
;; emacs-lisp
;; name of current buffer:
(buffer-name (current-buffer));; open in current pane:
(switch-to-buffer "foo.txt");; open in other pane:
(switch-to-buffer-other-window "bar.txt")
;; common-lisp
;; racket
;; clojure
;; emacs-lisp
;; current buffer:
(erase-buffer);; buffer named "foo.txt:
(with-current-buffer "foo.txt" (erase-buffer))
;; common-lisp
;; racket
;; clojure
;; emacs-lisp
;; 1-based index of char under cursor:
(point);; go to beginning of current buffer:
(goto-char 1);; go to end of current buffer:
(goto-char (buffer-size))
;; common-lisp
;; racket
;; clojure
;; emacs-lisp
;; 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)
;; common-lisp
;; racket
;; clojure
;; emacs-lisp
;; takes 1 or more args:
(insert "lorem" " ipsum")
;; common-lisp
;; racket
;; clojure
;; emacs-lisp
(buffer-string)
;; common-lisp
;; racket
;; clojure
;; emacs-lisp
(insert-file "/etc/passwd")
;; common-lisp
;; racket
;; clojure
;; emacs-lisp
;; to beginning of current buffer:
(set-mark 1);; to point of current buffer:
(set-mark (point))
;; common-lisp
(osicat:file-exists-p "/tmp/foo")
(osicat:regular-file-exists-p "/tmp/foo")
;; racket
??
(file-exists? "/etc/hosts")
;; clojure
(.exists (io/file "/etc/hosts"))
;; emacs-lisp
(file-exists-p "/etc/hosts")
(file-regular-p "/etc/hosts")
;; common-lisp
;; racket
(file-size "/etc/hosts")
;; clojure
(.length (io/file "/etc/hosts"))
;; emacs-lisp
(eighth (file-attributes "/etc/hosts"))
;; common-lisp
;; racket
(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")))
;; clojure
(.canRead (io/file "/etc/hosts"))
(.canWrite (io/file "/etc/hosts"))
(.canExecute (io/file "/etc/hosts"))
;; emacs-lisp
;; common-lisp
;; racket
(file-or-directory-permissions "/tmp/foo" #o755)
;; clojure
;; emacs-lisp
(set-file-modes "/tmp/foo" #o755)
;; common-lisp
;; racket
(file-or-directory-modify-seconds "/tmp/foo")
;; clojure
; Unix epoch in milliseconds:
(.lastModified (java.io.File. "/tmp/foo"))
;; emacs-lisp
;; common-lisp
(cl-fad:copy-file #P"/tmp/foo" #P"/tmp/bar")
(delete-file #P"/tmp/foo")
(rename-file #P"/tmp/bar" #P"/tmp/foo")
;; racket
(copy-file "/tmp/foo" "/tmp/bar")
(delete-file "/tmp/foo")
(rename-file-or-directory "/tmp/bar" "/tmp/foo")
;; clojure
(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"))
;; emacs-lisp
(copy-file "/tmp/foo" "/tmp/bar")
(delete-file "/tmp/foo")
(rename-file "/tmp/bar" "/tmp/foo")
;; common-lisp
(osicat:make-link "/tmp/hosts" :target "/etc/hosts")
;; racket
(make-file-or-directory-link "/etc/hosts" "/tmp/hosts")
(link-exists? "/tmp/hosts")??
;; clojure
;; emacs-lisp
(make-symbolic-link "/etc/hosts" /tmp/hosts")returns target if symlink or nil:
(file-symlink-p "/tmp/hosts")
;; common-lisp
;; racket
(define tmp (make-temporary-file))
(path->string tmp)
;; clojure
; java.io.File:
(java.io.File/createTempFile "foo" ".txt")
;; emacs-lisp
(make-temp-file "foo")
;; common-lisp
(make-pathname :directory '(:absolute "etc") :name "hosts")
;; racket
; returns path; convert to string
; with path->string:
(build-path "/etc" "hosts")
;; clojure
(require '[clojure.java.io :as io]); returns java.io.File;
; convert to string with .getPath:
(io/file "/etc" "hosts")
;; emacs-lisp
;; common-lisp
(pathname-directory #P"/etc/hosts")
(pathname-name #P"/etc/hosts")
;; racket
(let-values (((dir file _) (split-path "/etc/hosts"))) #| use dir or file |#)
;; clojure
(require '[clojure.java.io :as io])
(.getParent (io/file "/etc/hosts"))
(.getName (io/file "/etc/hosts"))
;; emacs-lisp
(file-name-directory "/etc/hosts")
(file-name-nondirectory "/etc/hosts")
;; common-lisp
;; racket
(simplify-path (path->complete-path ".."))
;; clojure
(.getCanonicalPath (java.io.File. ".."))
;; emacs-lisp
(expand-file-name "..")
;; common-lisp
(dolist (file (osicat:list-directory "/tmp")) (format t "~a~%" file))
;; racket
(for ([path (directory-list "/etc")]) (write-string (path->string path)))
;; clojure
; file-seq returns java.io.File objects for files
; in arg directory and any subdirs recursively.
(filter #(= (.getParent %) "/etc") (file-seq (clojure.java.io/file "/etc")))
;; emacs-lisp
(dolist (file (directory-files "/etc")) (print file)))
;; common-lisp
;; racket
(make-directory* "/tmp/foo/bar")
;; clojure
(require '[clojure.java.io :as io])
(.mkdir (io/file "/tmp/foo"))
;; emacs-lisp
creates parents if 2nd arg non-nil:
(make-directory "/tmp/foo/bar" t)
;; common-lisp
;; racket
(copy-directory/files "/tmp/foo.d" "/tmp/bar.d")
;; clojure
;; emacs-lisp
;; common-lisp
(delete-directory "/tmp/foo.d")
;; racket
(delete-directory "/tmp/foo.d")
;; clojure
(clojure.java.io/delete-file "/tmp/foo.d")
;; emacs-lisp
(delete-directory "/tmp/foo.d")
;; common-lisp
(osicat:delete-directory-and-files "/tmp/foo.d")
;; racket
(delete-directory/files "/tmp/foo.d")
;; clojure
;; emacs-lisp
(delete-directory "/tmp/foo.d" t)
;; common-lisp
(osicat:directory-exists-p #P"/etc")
;; racket
(directory-exists? "/etc")
;; clojure
(.isDirectory (io/file "/etc"))
;; emacs-lisp
(file-directory-p "/etc")
;; common-lisp
*posix-argv*
;; racket
current-command-line-arguments
;; clojure
*command-line-args*
;; emacs-lisp
in shebang mode only:
command-line-args or argv
;; common-lisp
;; racket
;; clojure
;; emacs-lisp
;; common-lisp
(posix-getenv "HOME")
;; racket
(getenv "HOME")
;; clojure
(System/getenv "HOME")
;; emacs-lisp
(getenv "HOME")
;; common-lisp
;; racket
;; clojure
;; emacs-lisp
;; common-lisp
;; racket
;; clojure
;; emacs-lisp
;; common-lisp
(run-program "ls" '( "/etc"))
;; racket
(require scheme/system)
(system "ls /etc")
;; clojure
(.exec (Runtime/getRuntime) "ls")
;; emacs-lisp
(shell-command "ls /etc")
;; common-lisp
;; racket
;; clojure
;; emacs-lisp
(shell-command-to-string "ls /etc")
;; common-lisp
;; racket
;; clojure
$ cat b/a.clj
(ns b.a)
(def x 3)
$ java -cp clojure.jar:. clojure.main
=> (require 'b.a)
=> b.a/x
3
;; emacs-lisp
;; common-lisp
(compile-file "a.lisp")
;; racket
$ raco make a.rkt
;; clojure
(compile 'a)
;; emacs-lisp
$ emacs -batch -Q -L . \ -f batch-byte-compile a.el
;; common-lisp
(load "a.lisp")
;; racket
(require a)
;; clojure
(require 'a)
;; emacs-lisp
(require "a")
;; common-lisp
(load "b/a.lisp")
;; racket
(require "b/a.rkt")
;; clojure
(require 'b.a)
;; emacs-lisp
;; common-lisp
(load "a.lisp")
;; racket
none
;; clojure
(require 'b.a :reload)
;; emacs-lisp
(load "a")
;; common-lisp
raises sb-int:simple-file-error
;; racket
raises exn:fail:syntax:missing-module. Because require must be top-level, the exception cannot be handled.
;; clojure
raises FileNotFoundException
;; emacs-lisp
raises file-err
;; common-lisp
contains working directory at startup
;; racket
(require setup/dirs)
(get-collects-search-dirs)
;; clojure
same as path used by java VM
;; emacs-lisp
; adds directory to library path:
(add-to-list 'load-path ("/home/ed/.emacs.d/lib"))
;; common-lisp
none
;; racket
;; clojure
CLASSPATH
;; emacs-lisp
EMACSLOADPATH
;; common-lisp
none
;; racket
;; clojure
$ java -cp /foo/bar:/baz/quux
;; emacs-lisp
$ emacs -L /foo/bar
;; common-lisp
(defpackage :foo)
;; racket
(module mconst racket (provide pi) (define pi 3.14))
;; clojure
(ns mconst)
;; emacs-lisp
No namespaces; a common convention is to use a prefix on all identifiers in a library, separated from the rest of the identifier by a hyphen.
;; common-lisp
none
;; racket
;; clojure
; must be in b/a.clj:
(ns b.a)
;; emacs-lisp
;; common-lisp
:
;; racket
:
;; clojure
. and /
;; emacs-lisp
;; common-lisp
; set current *package* to foo and import symbol twiddle from bar:
(defpackage :foo (:import-from :bar :twiddle))
;; racket
;; clojure
;; emacs-lisp
;; common-lisp
; set current *package* to foo and import symbols from bar:
(defpackage :foo (:use :bar))
;; racket
;; clojure
;; emacs-lisp
;; common-lisp
;; racket
;; clojure
;; emacs-lisp
;; common-lisp
;; racket
;; clojure
;; emacs-lisp
;; common-lisp
;; racket
$ raco help
$ raco pkg --help
$ raco pkg install --help
;; clojure
;; emacs-lisp
;; common-lisp
;; racket
$ raco pkg show --all
;; clojure
;; emacs-lisp
M-x list packages
;; common-lisp
(ql:system-apropos "time")
;; racket
http://pkgs.racket-lang.org
;; clojure
;; emacs-lisp
M-x list-packages
;; common-lisp
; install quicklisp
(load "~/quicklisp/setup.lisp")
(ql:quickload "osicat")
;; racket
$ raco pkg install --deps search-auto srfi
;; clojure
;; emacs-lisp
Use M-x list-packages to bring up the package menu; i to select a package to install, and x to install it.
;; common-lisp
;; racket
$ raco pkg remove srfi
;; clojure
;; emacs-lisp
In the package menu, use d to select a package to uninstall and x to uninstall it.
;; common-lisp
(defclass rectangle () ( (height :accessor rectangle-height :initarg :height) (width :accessor rectangle-width :initarg :width)))
;; racket
(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))))
;; clojure
use java:
public class Rectangle { public float height; public float width; public Rectangle(float h, float w) { this.height = h; this.width = w; } public void setHeight(float h) { this.height = h; } public void setWidth(float w) { this.width = w;
}
;; emacs-lisp
;; common-lisp
(make-instance 'rectangle :height 3 :width 7)
;; racket
(define rect (new rectangle (height 7) (width 3)))
;; clojure
(import 'Rectangle)
(def r (Rectangle. 7 3))
;; emacs-lisp
;; common-lisp
(rectangle-height rect)
;; racket
(send rect get-height)
;; clojure
(.height r)
;; emacs-lisp
;; common-lisp
(setf (rectangle-height rect) 4)
;; racket
(send rect set-height 4)
;; clojure
(.setHeight r 8)
;; emacs-lisp
;; common-lisp
(defmethod area ((figure rectangle)) (* (rectangle-height figure) (rectangle-width figure)))
;; racket
(define/public (area) (* curr-height curr-width))
;; clojure
(defmulti area class)
(defmethod area Rectangle [r] (* (.height r) (.width r)))
;; emacs-lisp
;; common-lisp
(area rect)
;; racket
(send rect area)
;; clojure
(area r)
;; emacs-lisp
;; common-lisp
standard-object t
;; racket
object%
;; clojure
Object
;; emacs-lisp
;; common-lisp
yes
;; racket
no
;; clojure
only one direct superclass; can implement multiple interfaces
;; emacs-lisp
;; common-lisp
(setq op '+)
(eval `(,op 1 1))
;; racket
(define op '+)
(eval `(,op 1 1))
(eval (quasiquote ((unquote op) 1 1)))
;; clojure
(def op +)
(eval `(,op 1 1))
;; emacs-lisp
(setq op '+)
(eval `(,op 1 1))
;; common-lisp
(defmacro rpn (arg1 arg2 op) (list op arg1 arg2))
;; racket
(define-syntax-rule (rpn arg1 arg2 op) (op arg1 arg2))
;; clojure
(defmacro rpn [arg1 arg2 op] (list op arg1 arg2))
;; emacs-lisp
(defmacro rpn (arg1 arg2 op) (list op arg1 arg2))
;; common-lisp
(defmacro rpn (arg1 arg2 op) `(,op ,arg1 ,arg2))
;; racket
(define-syntax-rule (rpn3 arg1 arg2 op) (eval ‘(,op ,arg1 ,arg2)))
;; clojure
(defmacro rpn [arg1 arg2 op] `(~op ~arg1 ~arg2))
;; emacs-lisp
(defmacro rpn (arg1 arg2 op) `(,op ,arg1 ,arg2))
;; common-lisp
(macro-function rpn)
;; racket
none
;; clojure
none
;; emacs-lisp
none
;; common-lisp
(macroexpand ’(rpn 1 2 +))
;; racket
(syntax-object->datum (expand-to-top-form '(rpn 1 2 +)))
;; clojure
(macroexpand '(rpn 1 2 +))
;; emacs-lisp
(macroexpand '(rpn 1 2 +))
;; common-lisp
(defmacro add ( &rest args ) `(+ ,@args))
;; racket
(define-syntax-rule ( add first …) (+ first …))
;; clojure
(defmacro add [ & args ] `(+ ~@args))
;; emacs-lisp
(defmacro add ( &rest args ) `(+ ,@args))
;; common-lisp
(defmacro add (a &rest b) `(if (null ',b) (+ ,a) (+ ,a (add ,@b))))
;; racket
(define-syntax add (syntax-rules () [(add x) x] [(add x y) (+ x y)] [(add x y …) (+ x (add y …))]))
;; clojure
(defmacro add ([a] `(+ ~a)) ([a & b] `(+ ~a (add ~@b))))
;; emacs-lisp
(defmacro add (a &rest b) `(if (null ',b) (+ ,a) (+ ,a (add ,@b))))
;; common-lisp
no
;; racket
yes
;; clojure
with # suffix
;; emacs-lisp
no
;; common-lisp
(defmacro square-sum (x y) (let ((sum (gensym))) `(let ((,sum (+ ,x ,y))) (* ,sum ,sum))))
;; racket
(define-syntax-rule (square-sum x y) (let ((sum (+ x y))) (* sum sum)))
;; clojure
(defmacro two-list [x] `(let [arg# ~x] (list arg# arg#)))
;; emacs-lisp
(defmacro square-sum (x y) (let ((sum (gensym))) `(let ((,sum (+ ,x ,y))) (* ,sum ,sum))))
;; common-lisp
(type-of '(1 2 3))
(typep '(1 2 3) 'list)
(listp '(1 2 3))
;; racket
(list? '(1 2 3))
;; clojure
(= (type 1) java.lang.Long)
(= (class 1) java.lang.Long)
(integer? 1)
;; emacs-lisp
(type-of [1 2 3] 'vector)
(typep [1 2 3] 'vector)
(vectorp [1 2 3])
;; common-lisp
;; racket
;; clojure
instance?
;; emacs-lisp
;; common-lisp
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-bytesymbols and strings:
base-character character extended-character keyword simple-string standard-char string symboldata structures:
array atom bit-vector cons hash-table list sequence simple-array simple-bit-vector simple-vector vectorother:
compiled-function function package pathname random-state stream
;; racket
;; clojure
;; emacs-lisp
;; common-lisp
list vector
;; racket
list vector hash-table string input-port range
;; clojure
all collections and strings
;; emacs-lisp
list vector
;; common-lisp
(describe #'mapcar)
;; racket
none
;; clojure
(doc map)
;; emacs-lisp
(describe-function 'mapcar)
;; common-lisp
(defun add (x y) "add x and y" (+ x y))
;; racket
none
;; clojure
(defn add "add x and y" [x y] (+ x y))
;; emacs-lisp
(defun add (x y) "add x and y" (+ x y))
;; common-lisp
none
;; racket
none
;; clojure
(apropos #"^add$")
(find-doc #"add \S+ and \S+")
;; emacs-lisp
(apropos "^add$")none
;; common-lisp
;; racket
;; clojure
(def rnd (new java.util.Random))
(def rnd (java.util.Random.))
;; emacs-lisp
;; common-lisp
;; racket
;; clojure
(. rnd nextFloat)
(.nextFloat rnd)
(. rnd nextInt 10)
(.nextInt rnd 10)
;; emacs-lisp
;; common-lisp
;; racket
;; clojure
(Math/sqrt 2)
;; emacs-lisp
;; common-lisp
;; racket
;; clojure
;; emacs-lisp
;; common-lisp
;; racket
;; clojure
(import '(java.util Random))
(def rnd (Random.))
;; emacs-lisp
;; common-lisp
;; racket
;; clojure
(to-array '(1 2 3))
(into-array Integer '(1 2 3))
;; emacs-lisp