Emacs, echo mike alpha charlie sierra

Having moved to a different country spelling words over the phone is a real pain as its not easy for people to understand a foreign name, and because I don’t know the military alphabet in english. So even when I decide spell things out I get stuck on letters as I don’t know what the common word would be. After not remembering how to spell out my last name over the phone again today I decide to create a quick little helper, after all I almost always take notes on my laptop anyway when calling.

Here we go quick emacs string-to-military, with configurable alphabet.

(defun string-to-military (s)
  (interactive "sEnter string to transfor to military: ")
  (flet ((string-blank-p (s) (string-match-p "^\\s-*$" s))
         (military-get-string (s)
                              (if (string-blank-p s) " "
                                  (alist-get s military-alphabet "" nil #'equal))))
    (let* ((chars (mapcar 'string s))
           (normalized-chars (mapcar 'downcase chars)))
      (string-join (mapcar 'military-get-string normalized-chars) " "))))


(defun string-to-military-region (start end)
  (interactive "r")
  (let ((content (buffer-substring-no-properties start end)))
    (delete-region start end)
    (insert (string-to-military content))))

and for the curious

(defvar military-alphabet '(("a" . "alpha")
                            ("b" . "bravo")
                            ("c" . "charlie")
                            ("d" . "delta")
                            ("e" . "echo")
                            ("f" . "foxtrot")
                            ("g" . "golf")
                            ("h" . "hotel")
                            ("i" . "india")
                            ("j" . "juliet")
                            ("k" . "kilo")
                            ("l" . "lima")
                            ("m" . "mike")
                            ("n" . "november")
                            ("o" . "oscar")
                            ("p" . "papa")
                            ("q" . "quebec")
                            ("r" . "romeo")
                            ("s" . "sierra")
                            ("t" . "tango")
                            ("u" . "uniform")
                            ("v" . "victor")
                            ("w" . "whiskey")
                            ("x" . "x-Ray")
                            ("y" . "yankee")
                            ("z" . "zulu"))
  "Military alphabet alist (CHARACTER . WORD), all characters are
lowercase for lookup.")

now part of my coders-little-helper.el in my local emacs.

Setup use-package

I like my emacs configuration to be managable in git installing everything on first start, as I migrated away from my home grown install and package manage to use-package I wanted to keep this nicety, so I need to make sure use-package gets installed if it isn’t already present.

;; setup use-package, if we don't have it, install it
(require 'use-package nil t)

(unless (featurep 'use-package)
  (package-refresh-contents)
  (package-install 'use-package)
  (require 'use-package))

Setting up Emacs on Windows 10

Emacs runs quite well on Windows 10, but to get it to work correctly it needs to be setup with a couple of other requirements

  1. Setup HOME environment variable, find it via “environment” in cortana search
  2. Download Emacs and Emacs Deps
  3. Combine both into a folder under C:\Program Files\emacs

With this in place the runemacs.exe will start an emacs session, and with the dependencies in place TLS will work as well for getting packages from melpa, elpa, etc.

I also use org-mode for my notes and todo list, to allow it to sync with mobile it requires sha1sum.exe, available as a binary download. With the binary copied in place of the emacs binary org-mobile-push org-mobile-pull will work.

Clojure + Ring + API Gateway + Lambda

Serverless is all the rage right now, so I’ve been playing with AWS Lambda, and just by the name itself what could possibly be a better fit for lambda than using Clojure on it? Since I’m mostly interested in webapps I decied to give API Gateway a spin with lambda, sadly it does not immedialty work with the awesome Ring library for building web applications in clojure. Luckily it is reasonably easy to map between the two, and inspired by ring-aws-lambda-adapter some time later I now have a working version of Ring + API Gateway. Together with AWS SAM and AWS SAM CLI this makes for quite a nice, local or cloud, development and hacking experience. And all it took is about 90 lines of Clojure

(ns playground.core
  (:require [clojure.data.json :as json]
            [clojure.java.io :as io]
            [clojure.string :as s]
            [ring.util.codec :as codec]
            [ring.util.response :as r])
  (:gen-class
   :name playground.core.Handler
   :implements [com.amazonaws.services.lambda.runtime.RequestStreamHandler])
  (:import [com.amazonaws.services.lambda.runtime RequestStreamHandler]
           [java.io InputStream File]
           [clojure.lang ISeq]))

(defn sample-handler
  [event]
  (r/response "Hello Lambda, from ring!"))

(defn stream->event
  [in]
  (json/read (io/reader in) :key-fn keyword))

(defn str->int
  [s]
  (try
    (Integer/parseInt s)
    (catch NumberFormatException _)))

(defn maybe-remote-address
  "Take a guess at the remote client ip based on the X-FORWARDED-FOR header.
  This is not perfect as the X-FORWARDED-FOR can easily be spoofed. "
  [x-forwarded-for]
  (some-> x-forwarded-for
          (s/split #"," 2)
          first
          s/trim))

(defn maybe-http-version
  "Take http version frim VIA header if present"
  [via]
  (some-> via
          (s/split #" " 2)
          first
          s/trim))

(defn api-gw-event->ring-request
  ([ev] (api-gw-event->ring-request ev nil))
  ([ev ctx]
   (let [headers (get ev :headers {})]
     {:server-port (str->int (:X-Forwarded-Port headers))
      :body (:body ev)
      :server-name (:Host headers)
      :remote-addr (maybe-remote-address (:X-Forwarded-For headers))
      :uri (:path ev)
      :query-string (codec/form-encode (get ev :queryStringParameters {}))
      :scheme (maybe-http-version (:Via headers))
      :request-method (:httpMethod ev)
      :protocol (:X-Forwarded-Proto headers)
      :headers headers
      :event ev
      :context ctx})))

(defmulti wrap-body class)
(defmethod wrap-body String [body] body)
(defmethod wrap-body ISeq [body] (s/join body))
(defmethod wrap-body File [body] (slurp body))
(defmethod wrap-body InputStream [body] (slurp body))

(defn ring-response->api-gw-response
  [response]
  {:statuCode (:status response)
   :headers (:headers response)
   :body (wrap-body (:body response))})

(defn handle-request
  "Handle an api-gateway request from IN via a RING-HANDLER writing
  response to OUT."
  [ring-handler in out ctx]
  (let [event (stream->event in)
        request (api-gw-event->ring-request event ctx)
        response (ring-handler request)
        event-response (ring-response->api-gw-response response)]
    (with-open [w (io/writer out)]
      (json/write event-response w))))

(defn -handleRequest
  "Implementation for RequestStreamHandler handleRequest using IN
  instream OUT outstream and CTX context object, delegating to
  handle-request to handle request using ring"
  [_ in out ctx]
(handle-request sample-handler in out ctx))

All I want for XMas … is a Brainfuck interpreter in Clojure?

Over the holidays I felt it was time to play with a little Clojure, and since I recently became interested in compilers and interpreters I felt like it was a good idea to start extremly simple, it is the holidays after all. So I built the simplest possible interpreter, a Brainfuck interpreter. It is quite a need excercise and most certainly made me more interesting in building more complex ones.

So here it goes clojure-brainfuck for anyone interested.

Projectile and TRAMP

Projectile requires a lot of file system interaction to stay up to date, this does not work well when accessing remote files and causes massive slowdowns when used over a less than ideal SSH connection. My solution based on a comment regarding this issue has been to deactivate projectile on remote files, sadly its not just files but also dired buffers which suffer so a small addition is needed to the solution in the comment adding dired buffers to the list of things dired should not be enabled for.

(defadvice projectile-on (around exlude-tramp activate)
  "This should disable projectile when visiting a remote file"
  (unless  (--any? (and it (file-remote-p it))
                   (list
                    (buffer-file-name)
                    list-buffers-directory
                    default-directory
                    dired-directory))
    ad-do-it))

furthermore to avoid unneeded calculation of the current project the projectile modeline needs to be set static.

(setq projectile-mode-line "Projectile")

with this in place projectile works nicely locally and remote file interactions are as quick as they can be.

First class functions over channels

TLDR;;

Inspired by reading go-cache and reading about core.async I was interested how well sending functions over a channel can work, here is the quick hacky result.

Why?

Clojure with its access to a very concise way to construct functions lends itself very nicely to the idea of using CSP with first class functions as messages passed over a channel.

(let [c (chan)]
  (>!! c #(zero? %)))

Given that a channel is only consumed by one thread, this provides an interesting way to sync on a data structure without the need for explicit locking as the channel with by itself serialize the operations. This could be quite performant depending on the consumer as multiple operations could be pipelined for example by polling the channel for a batch of operations to be dispatched to different workers.

Why not?

This is mainly an idea taken from playing with go-lang and implemented in clojure, for access to a basic data structure like a map, even so it can now be a transient map, the built in transactions will provide much better performance.

Installing golang-1.7 on ubuntu 16.10

Ubuntu, and in fact any debian as far as I’m aware has the the

$ update-alternatives

command to manage different versions of installed software. Currently when installing golang ubuntu will default to 1.6, but the repository contains 1.7 as well as package golang-1.7. To allow switching between the versions with the builtin system it can be setup via

$ update-alternatives --install /usr/bin/go go /usr/lib/go-1.7/bin/go 1

Where 1 is the priority, when using auto setup.

$ update-alternatives --config go

Now allows switching between the favorite go version.

GoGuru scope in emacs

GoGuru is an amazing tool and can be really useful when exploring a project, setting up the scope can be a bit of a pain so as the default function doesn’t even support autocompleting. After some quick hacking here is the first attempt to make at least allow for some easier setup, taking the current file and assuming it is the main package, this little function will setup the scope relative to this file.

https://gist.github.com/sideshowcoder/0d37c53bbf1d62299600bb723cc20af0.js

Building hack-lang on Ubuntu 16.10

Having hacked with PHP every now and then, and running my blog on wordpress I wanted to give hack-lang a spin. Obviously wanting to be bleeding edge I decided to build hhvm from source on my Ubuntu 16.10 machine. It almost worked straight out the box but some poking was needed as I first encountered an error on the build following the instructions on the page. Here is what got me past the initial errors.

Install the packages documented on the page, but using gcc-4.9

$ sudo apt install autoconf automake binutils-dev build-essential cmake g++-4.9 gcc-4.9 gawk git 
  libboost-dev libboost-filesystem-dev libboost-program-options-dev libboost-regex-dev 
  libboost-system-dev libboost-thread-dev libboost-context-dev libbz2-dev libc-client-dev libldap2-dev 
  libc-client2007e-dev libcap-dev libcurl4-openssl-dev libdwarf-dev libelf-dev 
  libexpat-dev libgd2-xpm-dev libgoogle-glog-dev libgoogle-perftools-dev libicu-dev 
  libjemalloc-dev libmcrypt-dev libmemcached-dev libmysqlclient-dev libncurses-dev 
  libonig-dev libpcre3-dev libreadline-dev libtbb-dev libtool libxml2-dev zlib1g-dev 
  libevent-dev libmagickwand-dev libinotifytools0-dev libiconv-hook-dev libedit-dev 
  libiberty-dev libxslt1-dev ocaml-native-compilers libsqlite3-dev libyaml-dev libgmp3-dev 
  gperf libkrb5-dev libnotify-dev libpq-dev

Checkout the hhvm source from github

$ git clone git://github.com/facebook/hhvm.git --depth=1
$ cd hhvm
$ git submodule update --init --recursive

I updated the submodules and they are now at the following versions for me

$ git submodule status --recursive
 af252b08f715a0e348175d0754d533949f2e390c third-party (af252b0)
 98ed7a23a83d64133b0a36a884e489bffb0eb864 third-party/brotli/src (v0.3.0)
 8bb673f4410819df06920fdcfd24e18d235d84f7 third-party/brotli/src/terryfy (third-15-g8bb673f)
 f1b955eee1cb94c51074878264aecdd6ee1350dd third-party/double-conversion (v1.1-86-gf1b955e)
 f1217348a868bdb9ee0730244475aee05ab329c5 third-party/fastlz/src (heads/master)
 e21df038e0b58855ef9344d1a3a4389e03ba2cc7 third-party/fatal (0.2-573-ge21df03)
 1d2d4f326acc0825690c151c38ac92d146b78146 third-party/folly/src (v2016.11.07.00-21-g1d2d4f3)
 eb021a100e761616b35ad62c910d6c336e0711d2 third-party/libafdt/src (heads/master)
 1d8b1ac4d20b8ef8d3f5d496dabebaa0ff9019ff third-party/libzip/src (rel-1-1-3-3-g1d8b1ac)
 d86dc916771c126afb797637dda9f6421c0cb998 third-party/lz4/src (r131)
 dbf8878c0136e5f94e4bb0aef6f931d5aecfa74d third-party/mcrouter/src (v0.34.0-2-gdbf8878)
 931a3231375201ee58fb495f4fad0d8fdfc36251 third-party/proxygen/src (v0.32.0-410-g931a323)
 718df09610fee584c9038d8d519697e507e09c9b third-party/re2/src (2016-07-01-6-g718df09)
 8468f07fcc8d96b4af69f1c8b75d404458f8e6b4 third-party/squangle/src (8468f07)
 5e5773be567eeb53a75565a911ece7de2c89ee2b third-party/thrift/src (v2016.11.07.00-8-g5e5773b)
 34a04f01668ae88f0dd7ca18aedf50e41689e8f9 third-party/wangle/src (v2016.11.21.00)
 a9e580b5a0baa768210ef10544c8fab52003ec0b third-party/webscalesqlclient/mysql-5.6 (a9e580b)
 dcc898b0215cee3b1baa88149c1f39e37e9bfd09 third-party/webscalesqlclient/mysql-5.6/rocksdb (rocksdb-3.13-431-gdcc898b)

with those versions building with gcc-4.9 seems to work fine

$ cmake -DCMAKE_C_COMPILER=/usr/bin/gcc-4.9 
        -DCMAKE_CXX_COMPILER=/usr/bin/g++-4.9 
        -DMYSQL_UNIX_SOCK_ADDR=/var/run/mysqld/mysqld.sock .
$ make -j <number of cores for me 4>

Happy hack-ing!