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);
}
{
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$();
}
}
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$();
}
}