Created
August 15, 2012 12:41
-
-
Save bayan/3359817 to your computer and use it in GitHub Desktop.
Transliterajure - Clojure macros to internationalize source code
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
;; 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