記号のみを使った Julia プログラミングをしたかった

punctuations のみを使ってプログラミングすることを記号プログラミングと呼ぶ人がいるらしいです。*1

記号プログラミング Advent Calendar がアツい! - 葉っぱ日記

これを真似て Julia で記号のみのプログラミングをやってみようと思いました。上のリンク先の内容(特にPerlの記事)をなぞっただけなので新規性はないです。

記号のみでプログラミングをするための方策は次の2ステップに分解できます。

  1. 任意のAscii文字列を記号のみで表現する
  2. 作った文字列を eval する

この記事では 1. についてはやりましたが 2. は妥協しました。eval を記号で済ます方法は Julia にはないように思われたからです。

さて、まずは 1.を実現するために、任意の文字 [a-zA-Z] が2つの文字記号の論理演算から作れるということを利用します。

julia> bin('`')
"1100000"

julia> bin('!')
"100001"

julia> bin('A')
"1000001"

julia> '`' $ '!'
'A'

この組み合わせは手作業で探してもいいですが、面倒なのでプログラムで全探索して辞書を作りました。

punctuations = "!\"#\$%&'()*+,-./:;<=>?@[\\]^_`{|}~"

println("{")
for i in ['A':'Z', 'a':'z']
  lists = (Char, Char)[]
  for p in punctuations
    x = i $ p
    if (p, x) in lists
      continue
    end
    if x in punctuations
      push!(lists, (x, p))
    end
  end
  println("  '$i' => $lists,")
end
println("}")

この辞書を元に好きな文字列を作ります。Julia では Char と String の扱いが異なり、+記号を使ってカジュアルに Char を結合したりすることはできません。なので文字列挿入記法を使います。

julia> "$('`'$'(')$('['$'>')$('@'$',')$('@'$',')$('@'$'/'),$('^'$')')$('@'$'/')$('^'$',')$('@'$',')$('_'$';')!"
Hello,world!

以上で任意の文字列を作ることに成功しましたが、ではこれを実行するにはどうしたらいいでしょう。Julia で文字列をプログラムとして評価するには parse してから eval する必要がありますが、これを記号だけで行う方法は見つけられませんでした。なので次のように単にアンダースコアで置き換えて妥協しました。これはひどい

_   = parse
__  = eval

こうすれば他の関数は記号のみで参照を得ることができます。例えば次のようにすれば記号のみで println を使えるようになります。

julia> "$('^'$'.')$('^'$',')$('@'$')')$('@'$'.')$('\\'$'(')$('@'$',')$('@'$'.')"
"println"
julia> ___ = __(_("$('^'$'.')$('^'$',')$('@'$')')$('@'$'.')$('\\'$'(')$('@'$',')$('@'$'.')"))
println (generic function with 2 methods)

これにより、(ほぼ)記号のみの Hello world プログラムを得ることができました。わーパチパチパチパチ!

_   = parse
__  = eval
___ = __(_("$('^'$'.')$('^'$',')$('@'$')')$('@'$'.')$('\\'$'(')$('@'$',')$('@'$'.')"))
___("$('`'$'(')$('@'$'%')$('@'$',')$('@'$',')$('@'$'/'), $('\\'$'+')$('@'$'/')$('^'$',')$('@'$',')$('^'$':')!")))
# => Hello, world!

やってみたかっただけなので妥協部分をどうにかしようというモチベーションはありません。

*1:記号プログラミングという言葉を記号のみを使うプログラミングという意味で使うことは少し憚られます。Symbolic programming と混同する恐れがあるからです。なのでタイトルは記号のみプログラミングとしました。