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

Practical Example: Morse Code

Morse code is naturally represented as a bitstring—dots and dashes of varying length. Let’s build a simple encoder:

(defun encode-morse (char)
  "Encode a single character to Morse (1=dah, 0=dit)."
  (case char
    (#\A (binary ((1 (size 1)) (0 (size 1)))))      ; .-
    (#\B (binary ((0 (size 1)) (1 (size 1))
                  (1 (size 1)) (1 (size 1)))))     ; -...
    (#\C (binary ((0 (size 1)) (1 (size 1))
                  (0 (size 1)) (1 (size 1)))))     ; -.-.
    (#\E (binary ((1 (size 1)))))                   ; .
    (#\T (binary ((0 (size 1)))))                   ; -
    (_ (binary ()))))  ; Unknown character

(defun encode-word (word)
  "Encode a word to Morse bitstring."
  (let ((chars (string:to_upper word)))
    (lists:foldl
      (lambda (char acc)
        (binary ((acc bitstring) ((encode-morse char) bitstring))))
      (binary ())
      chars)))

Testing:

lfe> (encode-word "BEAT")
#B(27:10)  ; -... . .- -

lfe> (bit_size (encode-word "BEAT"))
10  ; Total bits needed

Each letter uses a different number of bits, so the result is naturally a bitstring. This is more space-efficient than using full bytes for each letter, and more faithful to the actual structure of Morse code.