I'm trying to find pangrams ie sentences that contain all the letters of the alphabet, for instance "The quick brown fox jumps over the lazy dog".
I'm an absolute beginner in elisp, and it ended up being a really difficult exercice for me. My idea what to put all the letters in a set check if all the letters of the alphabet are in this set.
I don't think it was a very good idea because elisp doesn't seem to really have sets, so I ended up using a hashmap, which seems very clunky.
Another things that really bothers me is the two
is-pangram. I feel that they make the function really difficult to reason about, although it's doing something very basic.
(defun add-to-hashmap (hashmap item) "Insert ITEM into HASHMAP and return HASHMAP." (puthash item t hashmap) hashmap) (defun iter-hashmap-keys (hashmap) "Return a sequence of the keys in HASHMAP" (let ((keys '())) (maphash (lambda (key _) (setq keys (cons key keys))) hashmap) keys)) (defun get-letters (s) "Return the set of letters in S. The set is a hashmap where keys are ascii characters and values are `t`." (setq letters (make-hash-table :test 'equal)) (seq-reduce (lambda (hashmap letter) (add-to-hashmap hashmap (downcase letter))) (split-string s "") letters)) (defvar ALPHABET (let* ((letters (get-letters "abcdefghijklmnopqrstuvwxyz")) (_ (remhash "" letters))) letters)) (defun is-pangram (s) "Return `t` is S is a pangram, `nil` otherwise." (setq letters (get-letters s)) (if (seq-some ;; this function returns returns `nil` if the given letter is ;; *present* in the set, and `t` otherwise. That way, seq-some ;; returns a non-nil value when there's a letter that is *not* in ;; the set. (lambda (letter) (if (gethash letter letters) nil t)) (iter-hashmap-keys ALPHABET)) nil t)) (provide 'pangram) ```