読者です 読者をやめる 読者になる 読者になる

プログラムdeタマゴ

nodamushiの著作物は、文章、画像、プログラムにかかわらず全てUnlicenseです

scala弄ってみた

scalaはJAVAで実装されたJAVAVM上で動く関数型言語です。
こちらのサイトからダウンロードして適当なフォルダに展開、そこにパスを通せばOKです。
(JAVAがあれば)インストール不要なので手軽に弄れるのも魅力。


簡単な使い方はここでも参照して下さいな。


さて、関数型言語と名乗る以上は末尾再帰関数については当然調べたくなるのは人の性。

object A{	
	def func(x:Int,sum:Int):Int = {
		if(x==0) sum
		else func(x-1,sum+1)
	}
	def main(args :Array[String]){
		println(func(100000,0))
	}
}


まったく知らなくても何となく分かると思われます。

funcは単純に与えられた第一因数を一つずつ数えて返すだけの頭の悪い関数です。

これをJAVAに書き直して実行するとエラーになります。

さて、実行してみましょう。

100000

おおおぉお!感動物です。

さっそく、どう実装されているのか中身を見てみましょう。
scalaは所詮JAVAVM上で動くプログラムなので、コンパイルすると普通にclassファイルが生成されます。
フォルダを覗いてみればA.classとA$.classの二つのクラスが生成されていました。


はやる気持ちを抑えて、逆コンパイル!


A.java


import java.rmi.RemoteException;



public final class A

{



    public static final void main(String args)

    {

        A$.MODULE$.main(args);

    }



    public static final int func(int i, int j)

    {

        return A$.MODULE$.func(i, j);

    }



    public static final int $tag()

        throws RemoteException

    {

        return A$.MODULE$.$tag();

    }

}


A.javaの方には定義の様なものだけ書かれていて重要なことは書かれていませんね。
ということはA$.javaが怪しい。

func部分抜き出し↓

    public int func(int x, int sum)

    {

        do

        {

            if(x == 0)

                return sum;

            sum++;

            x = x - 1;

        } while(true);

    }





分かってはいたけど、普通だなぁ(何を求めていたwww)


A$.java

import java.rmi.RemoteException;

import scala.Predef$;

import scala.ScalaObject;

import scala.runtime.BoxesRunTime;



public final class A$

    implements ScalaObject

{



    public A$()

    {

    }



    public void main(String args)

    {

        Predef$.MODULE$.println(BoxesRunTime.boxToInteger(func(0x186a0, 0)));

    }



    public int func(int x, int sum)

    {

        do

        {

            if(x == 0)

                return sum;

            sum++;

            x = x - 1;

        } while(true);

    }



    public int $tag()

        throws RemoteException

    {

        return scala.ScalaObject.class.$tag(this);

    }



    public static final A$ MODULE$ = this;



    static 

    {

        new A$();

    }

}