;; S-Expression (SYMBOL PARAMETER1 PARAMETER2 ...) ;; 1 + 2 + 3 + 4 (+ 1 2 3 4) ; => 10 ;; (1 + 2) * (3 + 4) (* (+ 1 2) (+ 3 4)) ; => 21 ;; show "Hello LISP!" in emacs (message "Hello LISP!") ; => Hello LISP! ;; `quote' means not eval it '(1 2 3 4) ; => (1 2 3 4) (quote (1 2 3 4)) ; => (1 2 3 4) ;; t is `true', nil is `false' (if t "true" "false") ; => true (if nil "true" "false") ; => false
(require 'cl) ; import library `cl.el' (defvar aa--count 0 "A private variable to store current count value.") (defun aa-add (a b) "Return A + b." (+ a b)) (defun aa-add-to (a) "Add a to count, return count." (let ((s (+ aa--count a))) (setq aa--count s))) (provide 'aa) ;; aa.el ends here
t ; => true nil ; => false ;; `nil' is null in emacs-lisp
true ; => true false ; => false nil ; => nil (= nil false) ; => false
1 ; => 1 1.2 ; => 1.2 1e6 ; => 1000000.0 ;; different from clojure #b101 ; => 5 #x12 ; => 18
;; same as emacs-lisp 1 ; => 1 1.2 ; => 1.2 1e6 ; => 1000000.0 ;; different from emacs-lisp 2r101 ; => 5 25/3 ; => 25/3 0x12 ; => 18
"Hello LISP!" ; => "Hello LISP!"
?a ; a => 97 ?A ; A => 65
\a ; a => 97 \A ; A => 65
'(1 2 3 4 5) ; => (1 2 3 4 5) (nth 2 '(1 2 3 4 5)) ; => 3 (length '(1 2 3 4 5)) ; => 5 (cons '3 '(1 2)) ; (3 1 2)
'(1 2 3 4 5) ; => (1 2 3 4 5) (nth '(1 2 3 4 5) 2) ; => 3 (count '(1 2 3 4 5)) ; => 5 (conj '(1 2) 3) ; (3 1 2)
'[3 4 5] ; => [3 4 5] (vector 3 4 5) ; => [3 4 5] (length (vector 3 4 5)) ; => 3 (elt '[3 4 5] 1) ; => 4
[3 4 5] ; => [3 4 5] (vector 3 4 5) ; => [3 4 5] (count [3 4 5]) ; => 3 (nth [3 4 5] 1) ; => 4
;; seems like emacs-lisp doesn't has `hash-set' ?
#{1 2 3} ; => #{1 2 3} (hash-set 1 2 3) ; => #{1 2 3} (hash-set 1 2 3 3) ; => #{1 3 2}
'(:Apple "Mac" :Microsoft "Windows") ; => (:Apple "Mac" :Microsoft "Windows") (plist-get '(:Apple "Mac" :Microsoft "Windows") :Apple) ; => "Mac"
{:Apple "Mac" :Microsoft "Windows"} ; => {:Apple "Mac" :Microsoft "Windows"} (:Apple {:Apple "Mac" :Microsoft "Windows"}) ; => "Mac" ({:Apple "Mac" :Microsoft "Windows"} :Apple) ; => "Mac"
(defvar hello "hi" "variable doc") ; => "hi" (setq hello "world") ; => "world" hello ; => "world"
(def hello "variable doc" "hi") ; => "hi" ;; No `setq` like function for clojure since variable is immutable ;; NOTE: for java mutable variable, you can use `set!` to set the variable
(let ((x 1) (y 2)) (+ x y)) ; => 3 (defvar a 1) (let ((hello "hi")) (setq hello "world") hello) ; => "world"
(let [x 1 y 2] (+ x y)) ; => 3 (with-local-vars [hello "hi"] (var-set hello "world") @hello) ; => world
(if "foo" "truthy" "falsey") ;=> "truthy" (if 0 "truthy" "falsey") ;=> "truthy" (if [] "truthy" "falsey") ;=> "truthy" (if nil "truthy" "falsey") ;=> "falsey" (if t (progn (print "print-true") "true") "false")
(if "foo" "truthy" "falsey") ;=> "truthy" (if 0 "truthy" "falsey") ;=> "truthy" (if [] "truthy" "falsey") ;=> "truthy" (if false "truthy" "falsey") ;=> "falsey" (if nil "truthy" "falsey") ;=> "falsey" (if t (do (println "print-true") "true") "false")
(require 'cl) ; for `cl-loop' (let ((i 1)) (cl-loop (print (format "hello: %d" i)) (if (> i 10) (return) (setq i (+ i 1)))))
(loop [i 1] (println (str "hello: " i)) (if (< i 10) (recur (inc i)))) ; tail recursion
(defun add (x y &optional z) "Function Doc." (+ x y (or z 0))) (add 1 2) ; => 3 (add 1 2 3) ; => 6 (defun sum (x y &rest args) (+ x y (apply '+ args))) (sum 1 2 3 4 5 6) ; => 21
(defn add "Function Doc." ([x y] (add x y 0)) ([x y z] (+ x y z))) (add 1 2) ; => 3 (add 1 2 3) ; => 6 (defn sum [x y & args] (+ x y (apply + args))) (sum 1 2 3 4 5 6) ; => 21
(defun logarithm (&key number &key base) (if base (/ (log number) (log base)) (log number))) ;; order significant, not key names: (logarithm :foo 8 :bar 2) ; => 3.0 (logarithm :bar 2 :foo 8) ; => 0.3333333
(defn logarithm [{x :number b :base}] (/ (Math/log x) (Math/log b))) (defn logarithm* ; same as `logarithm' [{:keys [number base]}] (/ (Math/log number) (Math/log base))) ;; Order is not importent (logarithm {:base 2 :number 8}) ; => 3.0 (logarithm {:number 8 :base 2}) ; => 3.0 (logarithm* {:base 2 :number 8}) ; => 3.0 (logarithm* {:number 8 :base 2}) ; => 3.0
((lambda (a b) (+ a b)) 1 2) ; => 3
((fn [a b] (+ a b)) 1 2) ; => 3 (#(+ %1 %2) 1 2) ; => 3 (#(+ 2 %) 1) ; => 3
(require 's) (s-trim " Hello ") ; => "Hello"
(require '[clojure.string :as str]) (str/trim " Hello ") ; => "Hello" (clojure.string/trim " Hello ") ; => "Hello"
;; Emacs-Lisp no Atoms
(def aa (atom nil)) (reset! aa 123) ; => aa becomes `123' @aa ; => 123 (swap! aa inc) ; => aa becomes `124' (def bb (atom {:a "aaa" :b "bbb"})) @bb ; => {:a "aaa" :b "bbb"} (swap! bb assoc-in [:b] 1) ; => bb becomes `{:a "aaa" :b 1}' @bb ; => {:a "aaa" :b 1} (def bb (atom {:b {:c 12}})) ; => {:b {:c 12}} (swap! bb assoc-in [:b :c] 1) ; => bb becomes `{:b {:c 1}}' @bb ; => {:b {:c 1}}
;; Emacs-Lisp doesn't has `thread' support
(do (Thread/sleep 3000) (println "hello")) ;; Wait for 3 sec and then "hello" is printed (do (future (Thread/sleep 3000) (println "after sleep")) (println "hello")) ;; hello ;; nil ;; after sleep
(defmacro infix (expr) (list (cadr expr) (car expr) (caddr expr))) (macroexpand-1 '(infix (1 + 3))) ; => (+ 1 3) (infix (1 + 3)) ; => 4
(defmacro infix [expr] (list (second expr) (first expr) (nth expr 2))) (macroexpand-1 '(infix (1 + 3))) ; => (+ 1 3) (infix (1 + 3)) ; => 4 (defmacro when "Evaluates test. If logical true, evaluates body in an implicit do." {:added "1.0"} [test & body] (list 'if test (cons 'do body)))
(require 'dash) ; https://github.com/magnars/dash.el (-> 2 (+ 3) (- 4) (* 5) (- 3)) ; => 2 (macroexpand-all '(-> 2 (+ 3) (- 4) (* 5) (- 3))) ; => (- (* (- (+ 2 3) 4) 5) 3)
(-> 2 (+ 3) (- 4) (* 5) (- 3)) ; => 2 (first (.split (.replace (.toUpperCase "a b c d") "A" "X") " ")) (-> "a b c d" .toUpperCase (.replace "A" "X") (.split " ") first) ; => "X"
(require 'dash) ; https://github.com/magnars/dash.el (->> 5 (+ 3) (/ 2) (- 1)) ; => 1 (macroexpand-all '(->> 5 (+ 3) (/ 2) (- 1))) ;; => (- 1 (/ 2 (+ 3 5)))
(reduce + (take 10 (filter even? (map #(* % %) (range))))) (->> (range) (map #(* % %)) (filter even?) (take 10) (reduce +)) ; => 1140
(import [java.util ArrayList]) (def foo (ArrayList. [1 2 3 4])) ; => [1 2 3 4] (.containsAll foo [2 3 4]) ; => true
(.toUpperCase "fred") ; => "FRED" (.getName String) ; => java.lang.String (.x (java.awt.Point. 1 2)) ; => 1 (System/getProperty "java.vm.version") ; => "25.51-b03" Math/PI ; => 3.141592653589793
(doto (new java.util.HashMap) (.put "a" 1) (.put "b" 2)) ; => {"a" 1, "b" 2} (let [h (new java.util.HashMap)] (.put h "a" 1) (.put h "b" 2) h) ; => {"a" 1, "b" 2}
coldnew@Sara ~ $ lein new nice-project Generating a project called nice-project based on the 'default' template. The default template is intended for library projects, not applications. To see other templates (app, plugin, etc), try `lein help new`.
. ├── CHANGELOG.md ├── LICENSE ├── README.md ├── doc │ └── intro.md ├── project.clj ├── resources ├── src │ └── nice_project │ └── core.clj └── test └── nice_project └── core_test.clj
(defproject nice-project "0.1.0-SNAPSHOT" :description "FIXME: write description" :url "http://example.com/FIXME" :license {:name "Eclipse Public License" :url "http://www.eclipse.org/legal/epl-v10.html"} :dependencies [[org.clojure/clojure "1.8.0"]])
(ns nice-project.core) (defn add-3 "Return x + 3" [x] (+ x 3)) (defn -main [] (println "Hello CLojure!"))
coldnew@Sara ~ $ lein run -m nice-project.core Hello CLojure!
(ns nice-project.core-test (:require [clojure.test :refer :all] [nice-project.core :refer :all])) (deftest add-3-test (testing "I will success." (is (= (add-3 10) 13)))) (deftest add-3-test-failed (testing "I fail." (is (= (add-3 10) 10))))
coldnew@Sara ~ $ lein test nice-project.core-test lein test :only nice-project.core-test/add-3-test-failed FAIL in (add-3-test-failed) (core_test.clj:11) I fail. expected: (= (add-3 10) 10) actual: (not (= 13 10)) Ran 2 tests containing 2 assertions. 1 failures, 0 errors. Tests failed.