パスワードを忘れた? アカウント作成
42680 story

「Rubyで作る奇妙なプログラミング言語 ~Esoteric Language~」 発売 31

ストーリー by GetSet
RUBYYYYYYYYYYYYYYYY! 部門より

転職活動中のAC 曰く、

ネタ用プログラミング言語としては BrainFuckWhitespace などが有名ですが、この度、それらの「奇妙なプログラミング言語(Esoteric Language)」を Ruby で実装し、新しい言語を作ろうという本、「Rubyで作る奇妙なプログラミング言語 ~Esoteric Language~」が 2008/12/20 に発売になります。
扱っている言語こそネタ臭がプンプンしますが、この本自体は、目次筆者が語るように「裏テーマ(?)である『チューリング・マシン』『λ計算』『構造化定理』について触れ」られており、本格的な言語作成本であるようです。

冬のひとときに、また、Ruby 学習の一助として、(あるいはネタとして)、読んでみるのはいかがでしょうか。

この議論は賞味期限が切れたので、アーカイブ化されています。 新たにコメントを付けることはできません。
  • そのうちに (スコア:3, 興味深い)

    by hohehohe (11394) on 2008年12月13日 21時01分 (#1472816)
    Rubyの機能を制限したRestricted Ruby(RRuby)を作って静的にコンパイルできるようにし、更にLLVMのIRに変換してnativeコードに変換するようにでき、RRubyでEsoteric LanguageやRuby自身を作ってコンパイルできるようになります。
    参考 [wikipedia.org]
    --
    AVG anti-virus data base out of date
    • by Anonymous Coward
      そういやSqueakもそんな感じだっけ。
      制限つきSmalltalk→Cのトランスレータをまず書き、
      SqueakのVMじたいはその制限言語で書き…というブートストラップ。

      #そのへんは機能じゃなく性能の問題なので、べつに最初から搭載することにこだわる必要は無く、あとから追加すればそれでいいと思う。
  • 誰かリンゴとバナナで説明してください。
    --
    妖精哲学の三信
    「だらしねぇ」という戒めの心、「歪みねぇ」という賛美の心、「仕方ない」という許容の心
    • by kr (10950) on 2008年12月14日 8時48分 (#1472952) 日記

      > 誰かリンゴとバナナで説明してください。

      よっしゃ、リンゴとバナナね。 おいしい果物に置き換えれば、 小難しいラムダ算法も簡単になるに違いない!

      そもそも、ラムダ算法の教科書なんか眺めても、なんだか意味がわからないし。 どれどれ、例えば、こんなことが書いてあるぞ……。

      ラムダ算法では、Church booleanを用いて、論理値を以下の様に表わせる。
          TRUE := λ x y. x
          FALSE := λ x y. y
      すると論理演算子を次のように定義できる。
          NOT := λ p. λ a b. p b a
          AND := λ p q. p q p
          OR := λ p q. p p q
          IFTHENELSE := λ p a b. p a b

      ほうら、変な記号が並んでいてワケワカメだ。 そういやRubyにもtrue, false, and, or, not, ifthenelseってのはあるけど、 ラムダなんちゃらいうこの記号でどうして計算ができるっていうだ?

      そこで、リンゴとバナナだ。

      使うのはリンゴとバナナだけ、わけの分からない記号は一切使わない。

      実はどんなラムダ式も、リンゴとバナナを並べて代用できる、と言ったら驚くかな? さてここからはリンゴとバナナを沢山使うから、先にスーパーに行って、 懐の許す限りリンゴとバナナを買って来よう!

      準備は良い? じゃあ、手始めにさっき出てきた、 TRUEとやらをリンゴとバナナに置き換えるよ! 一緒にリンゴとバナナを並べてね!

      リンゴ バナナ リンゴ バナナ リンゴ バナナ バナナ

      並べたかな? 順序を間違えちゃ駄目だよ。

      甘い香りが漂ってくる。無味乾燥な記号と違って、一目瞭然、とっても美味しそうだね! ん? 今一実感が湧かないって? お金が無くてリンゴとバナナを買えなかった? そうか、まあスーパーで買い占めなんかしても人様に迷惑だし、 ここは臨場感溢れる絵文字を並べて我慢しよう。

      σισισιι

      言うするまでもなく、σがリンゴでιがバナナだ。 なんて写実的な表現だろう! よだれが出てくるね!

      じゃあどんどん行くよ。っていうか、もう面倒だからまとめて書くよ。

      TRUE := σισισιι
      FALSE := σσισισιισιι
      NOT := σσσισισισιισσσισισισιισιισσσισισισιισσισισιισισισιισσισισιισιισσισισιισισισιι

      うーん、おいしそうだ。え、ANDORはどうしたって? あんまり続けてると、荒らしモデが付きそうだから自粛したんだ。

      ともかく、これでラムダ計算がリンゴとバナナに置き換えられたから、 もうラムダ計算が分かったよね! そう、つまり、「リンゴとバナナはおいしい(でもあんまり沢山有っても飽きる)」ということだ。以上。さあ、帰った帰った。

      は? 本当にラムダ式がリンゴとバナナに置き換えられているのか信用できない? 疑い深いなあ、じゃあストーリーの趣旨に合わせて、Rubyプログラムを置いておくから、 自分で試してごらんよ。

      def iota (s)
        $s = s
        rec = lambda do
          i = $s[0]
          $s = $s[1..-1]
          if i == ?* then
            f = rec[]
            f[rec[]]
          elsif i == ?i then
            lambda {|c| c[lambda {|x| lambda {|y| lambda {|z| (x[z])[y[z]] } } } ][lambda {|x| lambda {|y| x} } ]}
          else
            raise "invalid char"
          end
        end
        rec[]
      end

      使い方は、こんな感じだ。irbを使うと便利だ。

      irb> t = iota("*i*i*ii")
      => #<Proc:…>
      irb> f = iota("**i*i*ii*ii")
      => #<Proc:…>
      irb> n = iota("***i*i*i*ii***i*i*i*ii*ii***i*i*i*ii**i*i*ii*i*i*ii**i*i*ii*ii**i*i*ii*i*i*ii")
      => #<Proc:…>

      iotaって何かって? なんだかバナナの絵文字ιのことを、そう言うらしいよ。 なので、バナナの代わりにiと書いてある。 リンゴの代わりは*だ。 こっちは陽を浴びて輝く真っ赤なリンゴを表わしているわけさ。

      ラムダ計算をリンゴとバナナだけで表わしたバナナ言語を Rubyオブジェクトにコンパイルするのがiota関数だ。 コンパイル

      親コメント
    • by Anonymous Coward on 2008年12月13日 16時22分 (#1472707)
      > リンゴとバナナで

      まず、バナナ2本でこうする。これがラムダだ。
      そこにリンゴとバナナを加える。これがオングストロームだ。
      もうわかったな?
      親コメント
    • りんごの種を一粒手に入れて、それを地面に植えなさい。
      そしてそれが大きく育って、りんごがたわわに手に実るようになるまで育てなさい。
      そしてそうやって実った実をひとつ食べて御覧なさい。

      あなたが植えた種が持っていたDNAがラムダ関数に与えた入力、あなたが今食べたりんごが実行結果です。

      大雑把に言うとそういうこと。
      --
      fjの教祖様
      親コメント
    • by Anonymous Coward on 2008年12月13日 21時41分 (#1472838)
      ネタなんだろうけど本当にラムダ計算って何だろうって人のために

      プログラマの視点から見たラムダ計算はコールバックや関数オブジェクトをさらに
      柔軟にしたものと考える事が出来ます。つまり、関数同士で演算を行って新しい関
      数を作る事が出来るのがラムダです。
      背後にある理論から勉強するより、先にHaskelやC++のboostで実際に使ってみたほ
      うが感覚が掴みやすいものの典型かと思われます。

      # 間違ってたらレスで指摘よろ
      親コメント
      • 昔々初めてλの勉強会をしたころ、私はどっちかっていうと1引数のマクロ展開っぽい印象だったな。
        関数って実はマクロ展開で表現できるんだなーと思った24歳の春。
        関数のインライン展開とかまさにマクロ展開だしねと納得したものであったことよ。

        ただし展開順序(関数で言うなら評価順序)は決まってないので式の形によっては展開順序の違いで結果が変わる。
        (どう展開しても変わらない式もある。)
        また展開が永遠に終わらないような式もある。
        この性質のため展開される過程によって計算過程としての関数が表現できる。
        (数学では普通、関数と言えば計算過程じゃなくて値の対応関係を表す。)

        でも、考えてみれば数学では人間が規則に従って式の書き換えを繰り返すことで様々な計算を実現してるんだからそれを突き詰めて
        普通の代数式ですらない純粋な書き換えのためのマクロとしての関数と変数だけからなる形で
        計算手順を抽象化したモデルとして書き換えシステムだけを抽出したのがλ計算といえばそう。

        ただそんななんで変数と1引数関数定義と書き換え規則だけしかなくて他のオブジェクトもタイプも何もないから、
        何か計算をするには関数定義をいろいろに見立てないといけない。
        で見立てると論理や自然数、それらを利用した制御構造、そしてそれらを使った各種の計算が記述できることがわかって
        エライ人がその記述&計算能力がチューリング・マシンと同等だと証明したと。
        そうなってみるとチューリングマシンよりは式を書くのが楽なのでプログラム関係の様々な性質の証明によく使われるようになったと。
        (特にそれを拡張した型付きλ計算が人気)

        さらにはλの成功にヒントを得て関数ではなくてオブジェクトを基本単位とするσ計算とか、π計算(こっちはよく知らない)とかが近年では出てきたと。
        親コメント
        • by Anonymous Coward
          >1引数関数定義
          >オブジェクトを基本単位とするσ計算とか

          全然知らんのですが、もしかして

          「メンバ変数が1つだけのオブジェクト」

          とかをたくさん使う方法論なんでしょうか??

          「複数のメンバ変数が有る1つのオブジェクトは、1つのメンバ変数だけを持つオブジェクトの複数の組み合わせに変形できる」

          といったところとか??

          #JSPの拡張タグライブラリって、拡張タグのHTML(XML)の「属性」がJavaクラスの「属性」にマッピングされるんだよね。初めて見たときショッキングだったよ。なんとなくメソッド呼び出しの引数にマッピングされるもんだと思い込んでいたので。まあ確かにJavaのメソッド引数は(コンパイル後に)名前情報が残らないからXML属性にマッピングするのは無理なんだけど。
    • 年寄り向けに,リモコンの使うボタンに目印をつけた。
      これがラムダだ。(リンゴとバナナだと、ほとんど食べれるからダメ)
      --
      the.ACount
      親コメント
    • by Anonymous Coward
      そういう具体的事物で表現しようとしても、ラムダ計算は抽象性がミソなんだかラ、ムダです。

      #いえ、本当は私も全然理解してません。ゴメン。
      • by Anonymous Coward on 2008年12月15日 15時40分 (#1473625)
        lambdaといえば、Lispを習った時が最初かなぁ。

        実に短絡的に「ランバダ」と読んで大爆笑されました。

        #ちゃーららららん、ちゃらららららららーん、な思い出なのでAC
        親コメント
      • by Anonymous Coward
        ζ┳┻┳°λ

        抽象化に失敗するとこうなるんですね

    • by Anonymous Coward
      オラオラオラオラ
       無駄無駄無駄無駄
        アッーーーー!!
    • by Anonymous Coward
      アルファがベータをカッパらったらイプシロンした。なぜだろう。
    • by Anonymous Coward
      あ、オレもforループがわからない、誰か教えて
      • by Anonymous Coward
        function GoldExperienceRequiem(){
          for (;;){
          }
          return truth;
        }
        • by Anonymous Coward
          ループはYコンビネータを使ってよ
          • by Deasuke (34806) on 2008年12月14日 13時01分 (#1473011) 日記
            ecmascriptならY-combinatorは書けるけど、書く必要もなくて、例えば5の階乗を再帰で書くのに無名関数を使って、

            function(n) { return n < 1? 1 : n*arguments.callee(n-1); }(5)

            で済みます。

            --
            Best regards, でぃーすけ
            親コメント
            • by Anonymous Coward
              >callee

              そうだよなあ。
              OOP言語に「今アクセスされてるレシーバ」を表すthisとかselfとかいう言葉が有るなら、
              関数型(純粋関数型かどうかは問わない)言語にも
              「今呼び出されてる関数」を表すcalleeのようなものが有ってしかるべきだ。

              というかC言語にだって凄く欲しいぞ。
              (まあCは無名関数やローカル関数を原則作れない言語だから、単にグローバルな関数名を呼べば済んでしまうんだけどね)

              #MSX-Cではmain()のローカル変数にマシン語を積んだりしたのでAC。
              #割り込み処理を置ける領域とスタックが置けるのとが同じ(バンク切り替えを食らわない0
  • by elderwand (34630) on 2008年12月14日 7時11分 (#1472938) 日記
    Esoteric Language というのは、こんなの [dalkescientific.com] とは違うんですね。
  • by Anonymous Coward on 2008年12月13日 14時20分 (#1472681)
    なんとなく256倍本 [ascii.co.jp]を思い出した。

    # 読んでないけど
    • by Anonymous Coward
      RaccはYaccとかと同じで、
      自作プログラム言語の内部機能のうちパーサーまでは自動生成してくれるけど、
      そっから先の処理はいわば手書きでしか無いため、
      「色々な見た目のプログラム言語」を作るときには便利だろうけど、
      「色々な論理的構造/背景の言語」を作るぶんにはあまり嬉しくないんじゃないかな。

      上の人がやってるバナナ言語みたいな奴だと、
      パーサーはわざわざRaccを使うまでもないのは見れば判ると思う。
      単に文字を1つづつ切れば済むわけだからね。
      一方で内部で何をやってるかは、
      深い理解があって始めて記述できる部分だし、Raccを使ってもそれがわかりやすくなるわけではない。

      特にバナナ言語やLisp系やForth系のように
      見た目は素朴すぎる一方で中身が異様に濃い言語だと、
      Racc的なツールの旨みは殆ど無いね。
  • by Anonymous Coward on 2008年12月14日 21時15分 (#1473181)
    というタイトルから、思わず↓を思い出してしまいました。
    http://jp.rubyist.net/magazine/?0014-Hotlinks [rubyist.net]
typodupeerror

開いた括弧は必ず閉じる -- あるプログラマー

読み込み中...