T10-emacs-lisp-idioms
docs
Summary
I will take time for self-reflection and listen to my inner voice.
Idioms
#001 Print Hello World
(print "Hello, World!")
"Hello, World!"
#002 Print hello 10 times
- `princ`: Outputs a string or character without additional formatting.
- `message`: Prints a message to the minibuffer.
- `insert`: Inserts text into the current buffer.
- `print`: Outputs a Lisp object with additional formatting and a newline.
- `prin1`: Outputs a Lisp object without additional formatting.
(dotimes (i 10) (princ "Hello\n"))
Hello Hello Hello Hello Hello Hello Hello Hello Hello Hello
#003 Create a procedure
(defun show (message) "Display a message in the echo area." (message "Hello: %s" message)) (show "again!")
#004 Create a Function
Functions in Emacs Lisp are defined using `defun`. The function `square` here takes a parameter `x` and returns its square by multiplying `x` by itself. Emacs Lisp automatically returns the value of the last evaluated expression. Functions are used for modularity and reuse of code. The provided function is a common example of mathematical operations often implemented in scripts.
(defun square (x) "Return the square of a number." (* x x)) (setq a 16) (print (format "Square of %d is %d" a (square a)))
"Square of 16 is 256"
#005 Create a 2D Point data structure
In Emacs Lisp, a 2D point structure can be represented using various methods. One common approach is to use a list or vector to store the x and y coordinates. This example shows a simple implementation using a list and how to create a point and access its coordinates.
(defun make-point (x y) "Create a point with coordinates x and y." (list x y)) (defun point-x (point) "Get the x coordinate of POINT." (car point)) (defun point-y (point) "Get the y coordinate of POINT." (cadr point)) (let ((p (make-point 3.0 4.0))) (print (format "Point: (%f, %f)" (point-x p) (point-y p))))
"Point: (3.000000, 4.000000)"
#006 Iterate Over List Values
In Emacs Lisp, iterating over list values can be achieved using several methods, such as `dolist`, `mapcar`, and `while` loops. This example demonstrates how to use `dolist` to iterate over a list and print each value.
(setq items '(1 2 3 4 5)) (dolist (x items) (princ (format "Item: %d\n" x)))
Item: 1 Item: 2 Item: 3 Item: 4 Item: 5
Other methods include `mapcar`, which applies a function to each element of a list and returns a new list with the results. For side effects only, use `mapc` instead. The `while` loop provides a more manual approach, giving full control over iteration conditions and index management.
#007 Iterate Over List Indexes and Values
In Emacs Lisp, you can iterate over both the indexes and values of a list using a combination of dotimes and nth. This approach is useful when you need to access each element along with its index.
(setq items '(10 20 30 40 50))
(dotimes (i (length items))
(let ((x (nth i items)))
(print (format "Index %d: Value %d" i x))))
"Index 0: Value 10" "Index 1: Value 20" "Index 2: Value 30" "Index 3: Value 40" "Index 4: Value 50"
This example demonstrates iterating over a list items, retrieving each value using nth, and printing both the index and the value. The dotimes loop runs from 0 to the length of the list minus one, ensuring each element is processed.
#008 Create a Map (Associative Array)
In Emacs Lisp, a map or associative array can be represented using a hash table. Hash tables allow for efficient storage and retrieval of key-value pairs. Here's an example of creating and using a hash table:
(setq my-map (make-hash-table :test 'equal)) (puthash "one" 1 my-map) (puthash "two" 2 my-map) (puthash "three" 3 my-map) (princ (format "Value for 'one': %d\n" (gethash "one" my-map))) (princ (format "Value for 'two': %d\n" (gethash "two" my-map))) (princ (format "Value for 'three': %d\n" (gethash "three" my-map)))
Value for 'one': 1 Value for 'two': 2 Value for 'three': 3
This example creates a hash table my-map using make-hash-table with :test 'equal for key comparison. The puthash function is used to store key-value pairs, and gethash retrieves values associated with specific keys. Finally, print is used to display the values to verify the contents of the hash table.
#009 Create a Binary Tree Data Structure
In Emacs Lisp, a binary tree can be represented using an alist (association list) where each node contains a value and pointers to its left and right children. This setup is useful for hierarchical data structures.
(defun make-node (value left right) "Create a binary tree node with VALUE, LEFT child, and RIGHT child." (list (cons 'value value) (cons 'left left) (cons 'right right))) (defun node-value (node) "Get the value of NODE." (cdr (assoc 'value node))) (defun node-left (node) "Get the left child of NODE." (cdr (assoc 'left node))) (defun node-right (node) "Get the right child of NODE." (cdr (assoc 'right node))) (setq root (make-node 10 (make-node 5 nil nil) (make-node 15 nil nil))) (princ (format "Root: %d\n" (node-value root))) (princ (format "Left Child: %d\n" (node-value (node-left root)))) (princ (format "Right Child: %d\n" (node-value (node-right root))))
Root: 10 Left Child: 5 Right Child: 15
This example includes the following Emacs Lisp keywords and their functions:
list: Creates a list of elements. Used here to define a node structure.cons: Constructs a cons cell, which is a pair of two values. In this context, it creates key-value pairs like ('value . value) for easy lookup.assoc: Finds the first pair in an alist whose key matches the given key. Used to retrieve specific parts of the node structure.cdr: Returns the second part of a cons cell. Here, it extracts the actual value associated with a key in a cons pair.princ: Outputs a string to the standard output. It is used to print the formatted results.
This structure efficiently represents a binary tree, with each node capable of storing data and references to its children, facilitating various operations like traversal and manipulation.
#010 Shuffle a List
To shuffle a list in Emacs Lisp, you can implement a Fisher-Yates shuffle algorithm. This is an efficient way to randomize the elements of a list.
(defun shuffle (list)
"Shuffle LIST randomly using the Fisher-Yates algorithm."
(let ((vector (vconcat list))
(len (length list)))
(dotimes (i len)
(let ((j (+ i (random (- len i)))))
(cl-rotatef (aref vector i) (aref vector j))))
(append vector nil)))
(setq my-list '(1 2 3 4 5))
(princ (shuffle my-list))
(3 5 1 4 2)
vconcat: Converts a list to a vector, which allows for element swapping.dotimes: Iterates a specified number of times, here used to traverse the list.cl-rotatef: Swaps the values of two places in the vector.
This method ensures that each element has an equal probability of ending up in any position, providing an unbiased shuffle.