Skip to content

Instantly share code, notes, and snippets.

@bayan
Created August 15, 2012 12:41
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save bayan/3359817 to your computer and use it in GitHub Desktop.
Save bayan/3359817 to your computer and use it in GitHub Desktop.
Transliterajure - Clojure macros to internationalize source code
;; English is the defacto standard when it comes to programming languages.
;; It is used to derive the names of special forms (e.g. if, def, etc) and core functions (find, map, etc).
;;
;; What about when you can't or just don't want to write in English?
;; For example: http://en.wikipedia.org/wiki/Language_policy_in_France
;;
;; How hard would it be to write code using another language?
;; Preprocessing source files using substitution before compiling/running won't allow us to run the code from a REPL.
;; Let's see what we can do in Clojure.
;;
;; The following Clojure function generates the fibonacci sequence:
;;
;; (defn fibs []
;; (map first (iterate (fn [[a b]] [b (+ a b)]) [0 1])))
;;
;; We will rewrite this in Japanese... using google translate since I don't know any Japanese ;)
;;
;; We can already rename the function and local variables:
;;
;; (defn フィボナッチ []
;; (map first (iterate (fn [[アルファ ベータ]] [ベータ (+ アルファ ベータ)]) [0 1])))
;;
;; Since functions are just values in Clojure, we could also easily alias functions such as map like this:
;;
;; (def 収集する map).
;;
;; But we can't do this for a macro like defn, or a special form like fn.
;;
;; The following Clojure macros can be used to write code using another language:
(defmacro transliterate
[from to]
(if (or (special-symbol? from)
(:macro (meta (resolve from))))
`(defmacro ~to
[~'& ~'body]
`(~'~from ~@~'body))
`(def ~to ~from)))
(defmacro transliterate-all
[& mappings]
(cons 'list
(map (fn [[from to]] `(transliterate ~from ~to))
(partition 2 mappings))))
;; We can now map the english names to their Japanese equivalent:
;;
;; (transliterate-all
;; + 合計
;; defn 関数を定義する
;; first 最初の
;; fn 機能
;; iterate 反復する
;; map 収集する
;; )
;;
;; Now we can write the fibonacci function almost entirely in Japanese:
;;
;; (関数を定義する フィボナッチ []
;; (収集する 最初の (反復する (機能 [[アルファ ベータ]] [ベータ (合計 アルファ ベータ)]) [0 1])))
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment