OR
#+BEGIN_SRC emacs-lisp (defun FUNCTION-NAME (ARGUMENTS…) "OPTIONAL-DOCUMENTATION…" (interactive ARGUMENT-PASSING-INFO) ; optional BODY…)
#+END_SRC
The cool thing about lisp is that you DO NOT need to use (return) to return a value. Instead, the last evaluated form in a defun is what is returned!
Here is a sharp quote:
(add-hook 'org-mode-hook #'toggle-word-wrap)
You should only sharp quote something when you are quoting a named function. This gives the byte compiler more useful information in case of future debugging. BUT there's no need to sharp quote a lambda expression. So don't do this:
(add-hook 'org-mime-html-hook #'(lambda ()
(org-mime-change-element-style
"pre" (format "color: %s; background-color: %s; padding: 0.5em;"
"#E6E1DC" "#232323"))))
Lisp Date types are a way of categories each lisp object. Every object has at least one type, but it can also have more than 1 type. This is why you can ask if an object is of type a
, but you cannot ask what type an object is.
Each object in lisp not only stores that object's value, it also stores that objects type/s. This means that if an object is of type number, then you cannot concatenate a string to it, because lisp knows that that object is a number, NOT a string, which is why this will fail:
(setq number 5)
(print (concat "5" number))
A sequence in lisp is a set of elements. It can either be a "list" or a "array".
A list can hold elements of any type. ie: #+BEGIN_SRC emacs-lisp '(hello '(I am supper cool) '(hello again ) yup that is me) #+END_SRC
So a list is like a digital shopping list. The shopping list can have items from ANY store, and it can be nearly infinitely long!
An array is a fixed length sequence. If the array can hold any element, then it is a vector array. A vector array is like a written shopping list, because a written shopping list can only hold soo many items on it.
Strings just hold characters. So string arrays are like a written novel w/o pictures. The book can only have words and a written book cannot be infinitely long.
Bool-vectors are a sequence of t and nil in any order. So bool vector are like lie detector games where you can only answer yes or no.
info:elisp#Sequence Type Char tables are like strings, except they can hold any valid character code like =?\C-t=
Lists string and arrays share some similiarities. ie: all have a length L, and all are indexed from 0 to L minus one.
Also take Integers are whole numbers lacking any fractional part. So the following are all -1
-1
-1.
and the following are all 1
1
+1
1.
+1.
Floats are for storing numbers that contain fractional parts. They can be written with an explicit decimal part, or they can be written in scientific notation to be considered a float.
All of the following numbers represent 150.0.
150.0
15e1
.15e3
1500e-1
150.0
A character is a letter. Internally elisp stores chars as an integer, so "R" has the value:
?R
82
You can also discover the syntax for the special characters.
?\(
?\\
92
?\a ⇒ 7 ; control-g, ‘C-g’
?\b ⇒ 8 ; backspace, <BS>, ‘C-h’
?\t ⇒ 9 ; tab, <TAB>, ‘C-i’
?\n ⇒ 10 ; newline, ‘C-j’
?\v ⇒ 11 ; vertical tab, ‘C-k’
?\f ⇒ 12 ; formfeed character, ‘C-l’
?\r ⇒ 13 ; carriage return, <RET>, ‘C-m’
?\e ⇒ 27 ; escape character, <ESC>, ‘C-[’
?\s ⇒ 32 ; space character, <SPC>
?\\ ⇒ 92 ; backslash character, ‘\’
?\d ⇒ 127 ; delete character, <DEL>
nil has 3 separate values. It can mean false, a symbol, and it is the empty list ()
.
t is the boolean value true. Technically any non-nil value will evaluate to a true value.
For example (when 5 BODY)
will evaluate the body forms because 5 is non-nil.
(when 5 (print "hello"))
hello
BUT =(booleanp 5) produces no output, because 5 is not boolean.
(booleanp 5)
A cons cell is an object has two slots the CAR and the CDR. Each slot can "hold" any lisp object.
(CAR . CDR)
Emacs uses cons cells to link together elements to form lists.
So the list (a b c d)
internally looks like =(a . (b . (c . (d . nil))))
Associated lists are also alists is a lisp list, where each element is a cons cell. So for example:
(setq fibanocci-alist
'((0 . 1) (1 . 1) (2 . 2) (3 . 3) (4 . 5) (5 . 8)))
In the fibanocci-alist, the CARs of each element in the list, are reference points to each respective values of the list.
If you have experience with C-like languages this is like an array.
char string[5] = "hello";
printf ("%d", string[3]);
108
foo
and Foo
are symbols
A good example of a hash-table is buffer objects like (current-buffer)
. Lisp tells you this when you evaluate
(current-buffer)
#
The syntax # lets you know that that buffer is a hash table.
Let looks like
#+BEGIN_SRC emacs-lisp (let VAR-LIST BODY) #+END_SRC
http://www.emacswiki.org/emacs/DynamicBindingVsLexicalBinding An interesting example:
A ‘let’ expression is indeed just “syntatic sugar”, a convenience, for the corresponding ‘lambda’ form:
#+BEGIN_SRC emacs-lisp (let ((a 1) (b 3)) (+ a b))
#+END_SRC
is equivalent to:
#+BEGIN_SRC emacs-lisp
((lambda (a b) (+ a b)) 1 3)
#+END_SRC When you create a new frame, it is set up with the "default-frame-alist".
Lisp is a functional programming language. It's not a truly functional language like Haskell, but it is close. Functional programming, in the simplest terms does not use loops: no for loops, no while loops, no do until loops, etc. Instead any sort of looping construct is done via recursion. Recursion occurs when a function calls itself to evaluate some result. Recursive functions tend to be extremely short and remarkably easy to understand. 1 However, any recursive function can be written non-recursively.
Emacs Lisp does have loops. This is why it is not a purely functional programming language. BUT here is a functional method to add all the numbers less than a number n.
(defun sum-numbers-less-than-n (n)
"sum all the numbers less than n"
;; if the number is 1, then return 1
(cond ((eq n 1) 1)
;; if the number is greater than 1, then return the sum of n plus sum-numbers-less-than-n (- n 1)
((+ n (sum-numbers-less-than-n (- n 1))))))
sum-numbers-less-than-n
Suppose we wish to sum all the integers less than 3. The function call would look like this
(sum-numbers-less-than-n 3)
|
|
\ /
(+ 3 (sum-numbers-less-than-n 2))
|
|
\ /
(+ 3 (+ 2 (sum-numbers-less-than 1)))
|
|
\ /
(+ 3 (+ 2 1))
|
|
\ /
(+ 3 3)
|
|
\ /
6
Here is another recursive example that will create the nth fibonacci number.
(setq fibonacciCalls 0)
(defun fibonacci (n)
"generate the nth fibonacci number"
(setq fibonacciCalls (+ 1 fibonacciCalls))
(cond
((eq n 0) nil)
((eq n 1) 0)
((eq n 2) 1)
((+ (fibonacci (- n 1)) (fibonacci (- n 2)) ))))
fibonacci
(fibonacci 30)
(fibonacci 5)
|
|
|
\ /
(+ (fibonacci 4) (fibonacci 3))
|
|
|
\ /
(+ (+ (fibonacci 3) (fibonacci 2)) (+ (fibonacci 2) (fibonacci 1)))
|
|
|
\ /
(+ (+ (+ (fibonacci 2) (fibonacci 1)) (fibonacci 2)) (+ (fibonacci 2) (fibonacci 1)))
To calculate the 11th fibonacci number, it has to call fibonacci 177 times. To calculate the 30th fibonacci number, there are 1,664,079 recursive function calls!
But maybe we can rewrite the elisp fibonacci generator, so that it doesn't have to calculate numerous fibonacci numbers multiple times. So every time that it calculates a fibonacci number, it'll add it to a hash table. Then when calculating another fibonacci (n) it'll check to see if that number is already in the hash table.
(defvar fibonacciCalls 0 "How many times fibonacci has been called.")
(defvar fibonacciHashTable (make-hash-table :weakness t))
(defun fibonacci (n)
"generate the nth fibonacci number"
(setq fibonacciCalls (+ 1 fibonacciCalls))
(cond
((eq n 0) nil)
((eq n 1.0) 0)
((eq n 2.0) 1)
((if (gethash n fibonacciHashTable)
(gethash n fibonacciHashTable)
(puthash n (+ (fibonacci (- n 1)) (fibonacci (- n 2)) ) fibonacciHashTable)))))
fibonacci
(fibonacci 110)
This function returns true, if the object is a string
(stringp "hello")
t
This function will return true if the object is a string or a char.
(char-or-string-p "t")
t
If a function returns a type looking like #("point" 0 5 (fontified t))
, then that is a string with some text properties.
A list is a sequence of 0 or more elements. You can insert or delete any of the elements in a list.
A list is made of up cons cells, which are a pair of elements. The first is the CAR and the second is the CDR. So
'("CAR" . nil)
CAR |
That cons cell is a list, whose only element is the string "CAR".
In a true list, the CDR refers to the next element in the list and the last CDR in the last cons cell is the symbol 'nil'. For example
'("This" . ("is" . ("a" . ("true" . ("list" . nil)))))
This | is | a | true | list |
If the list's last CDR is not the symbol 'nil', then it is a dotted list. Like this:
'("this" . ("is" . ("a" . ("dotted" . "list"))))
(this is a dotted . list)
A list can also be circular, which means the last CDR refers to another item in the list.
#+RESULTS:
t
#+BEGIN_SRC emacs-lisp (consp '(nil)) #+END_SRC
#+RESULTS:
t
#+BEGIN_SRC emacs-lisp (consp '("list" . ("item" . nil))) #+END_SRC
#+RESULTS:
t
#+RESULTS:
t
(listp '("cons" . ("cell" . nil))
t
String manipulation library (use-package f)
String manipulation library (use-package dash)
String manipulation library (use-package s)
When you begin an edebug session, you can press "?" to see a list of available commands. A macro expands a bit of code into another bit of code.
When I press "q" to exit the agenda, then org-mode and evil-mode would be loaded.