Keyboard shortcuts

Press or to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

Combining Operators: Real-World Example

Let’s implement a simple permission system using bit flags:

(defun perm-read () 1)      ; #b001
(defun perm-write () 2)     ; #b010
(defun perm-execute () 4)   ; #b100

(defun grant-permission (current perm)
  "Grant a permission."
  (bor current perm))

(defun revoke-permission (current perm)
  "Revoke a permission."
  (band current (bnot perm)))

(defun has-permission? (permissions perm)
  "Check if permission is granted."
  (=:= perm (band permissions perm)))

(defun describe-permissions (perms)
  "Human-readable permission description."
  (let ((r (if (has-permission? perms (perm-read)) "r" "-"))
        (w (if (has-permission? perms (perm-write)) "w" "-"))
        (x (if (has-permission? perms (perm-execute)) "x" "-")))
    (++ r w x)))

Testing:

lfe> (let* ((p0 0)
            (p1 (grant-permission p0 (perm-read)))
            (p2 (grant-permission p1 (perm-write)))
            (p3 (grant-permission p2 (perm-execute)))
            (p4 (revoke-permission p3 (perm-write))))
       (list (describe-permissions p0)
             (describe-permissions p1)
             (describe-permissions p2)
             (describe-permissions p3)
             (describe-permissions p4)))
("---" "r--" "rw-" "rwx" "r-x")

This permission system is both space-efficient (3 bits vs. 3 booleans) and fast (bit operations are among the fastest CPU instructions).