* Autodidactism at 700nm

** Bootstrapping
#+BEGIN_SRC elisp
    (let* ((args '("-J-Dclojure.server.repl={:port,9457,:accept,clojure.core.server/repl}"))
           (clojure-program "clojure")
           (buffer (get-buffer-create "*clojure*"))
           (proc-alive (comint-check-proc buffer))
           (process (get-buffer-process buffer)))
      (unless proc-alive
        (with-current-buffer buffer
          (apply 'make-comint-in-buffer "Clojure" buffer clojure-program nil args)))
      (when buffer
        (pop-to-buffer buffer)))
#+END_SRC


#+BEGIN_SRC elisp
  (defun org-babel-execute:clojure (body params)
    "Execute a block of clojure code with org-babel."
    (message "executing Foma source code block %s" body)
    (org-babel-eval "nc localhost 9457" body))
#+END_SRC


#+RESULTS:
: org-babel-execute:clojure


#+BEGIN_SRC clojure
  (future
    (with-open [sock (java.net.ServerSocket. 32466)]
      (loop []
        (try
          (with-open [s (.accept sock)
                      i (clojure.lang.LineNumberingPushbackReader.
                         ((requiring-resolve 'clojure.java.io/reader) (.getInputStream s)))
                      o ((requiring-resolve 'clojure.java.io/writer) (.getOutputStream s))]
            (binding [*in* i
                      ,*out* o]
              ((requiring-resolve 'clojure.main/repl)
               :prompt (constantly nil))))
          (catch Throwable t
            (prn t)))
        (recur))))
#+END_SRC

#+RESULTS:
: #object[clojure.core$future_call$reify__8544 0x730278dc {:status :pending, :val nil}]

#+BEGIN_SRC elisp
  (defun org-babel-execute:clojure (body params)
    "Execute a block of clojure code with org-babel."
    (message "executing Foma source code block %s" body)
    (org-babel-eval "nc localhost 32466" body))
#+END_SRC

#+RESULTS:
: org-babel-execute:clojure


** Motivation
 Every home automation project eventually needs to control devices
 that use an infrared remote. I have arrived that place.

 For some devices there are lists of IR codes, numeric values and
 combined with some timing information describe how to pulse an ir
 led on and off to send commands to a device, available online.  But
 luckily for me I am having trouble finding IR codes for some of my
 devices so I get to do this from scratch.

 This involves setting up an IR receiver, and recording what it
 receives for different button presses on remotes. In my case what I
 get back is something like:
^{:nextjournal.clerk/visibility {:code :hide}}
[9136 4429 599 479 595 492 613 503 616 1581 588 534 597 493 598 1594 587 503 616 495 595 497 576 539 595 1584 579 1613 615 506 580 502 588 525 600 1581 580 518 609 507 596 1580 593 558 569 471 619 495 576 1623 605 521 570 494 594 527 596 494 596 493 578 517 611 503 596 498 595]
 This list of numbers that a receiver reports for a single button
 press is a _message_.  Buttons on a remote will (usually) result in
 different messages. A message from the remote to the device tells
 the device to do something. Different messages usually tell it to
 do different things.

 I can take this list of numbers and feed it backout through an IR
 emitter to send the message to a device. Remote cloned, job done.

 But this long list of numbers is annoying to work with, and
 depending on the remote you can easily end up with 50+ of these
 lists per remote. Each number in theory has the range of unsigned
 16 bit number, so two bytes per for storage. And I want to to
 reprogram my IR emitter on the fly. That is a lot of data to be
 pushing into a poor little microntroller over a bluetooth radio.

 Ideally I should be able to factor out commonality in these
 messages to reduce their size, doing some kind of domain specific
 compression.

 There is a lot of noise is these numbers. So before attempting any
 kind of more succint encoding of the information, I need to remove
 the noise so the messages will _compress_ better. Removing noise
 will make redundancy more evident.

 I can use some structural knowledge of how these IR messages tend
 to work to make a best guess at the amount of noise. After removing
 the noise I can derive the _alphabet_ of _symbols_ that each remote
 uses to write it's messages, and generate an efficient binary
 encoding for that alphabet.

 To do this I'll need a nice representive sample of messages from
 the target remote:


#+BEGIN_SRC clojure
  (defn foo [x]
    (inc x))
#+END_SRC

#+RESULTS:
: #'user/foo
