mike-neckのブログ

Java or Groovy or Swift or Golang

KotlinとTypeScriptで同じことをしてみる

表記には偉そうなことを書いていますが、僕は

  • TypeScript - 1日だけ
  • Kotlin - この記事で初めて書いた

レベルです。

したがって、チュートリアルレベルのことしか書いていません。次のブログを読んで、興味本位でやってみただけです。特に結論があるわけでもありません。

yyyank.blogspot.jp

KotlinがAltJSとしても使えるということは知っていのたですが、今現在はTypeScriptのエコシステムがかなり優秀そうなのでTypeScriptを学習(ほとんどしてないけど)しているわけですが、同じようなコードを書いたらどれくらい違うか試してみました。

ネタはTypeScriptのHandBookのOur First Interfaceです。

まずはTypeScriptのコード(Handbookそのまま)

interface Labeled {
  label: string;
}
 
function printLabel(labelledObj: Labeled) {
  console.log(labelledObj.label);
}
 
var myLabel = {size: 10, label: "Size 10 Object"};
printLabel(myLabel);

次はKotlinのコード

trait Labeled {
  val label: String
}
 
fun printLabel(label: Labeled) {
  println("here is label[" + label.label + "]")
}
 
class MyLabel(override val label: String, val size: Int): Labeled {}
 
fun main(args: Array<String>) {
  val myLabel = MyLabel("Size 10 Object", 10)
  printLabel(myLabel)
}

Kotlinの方がコード量が多いと思わせていますが、これはTypeScriptがJavaScriptの延長で記述することができるために、オブジェクトを作るのに簡単に記述できるというだけの差です。同じような記述も可能です。

interface Labeled {
  label: string;
}
 
function printLabel(labelj: Labeled) {
  console.log(label.label);
}
 
 class MyLabel implements Labeled {
     label: string
     constructor(l: string, size: number) {
         this.label = l
     }
 }
 
var myLabel = {size: 10, label: "Size 10 Object"};
printLabel(myLabel);

どちらのコードを実行してもSize 10 Objectと表示されます。

なお、これらのコンパイル結果はかなり違います。

以下はKotlinからコンパイルされたJavaScriptのコードです。

Kotlin.out.flush();
(function (Kotlin) {
  'use strict';
  var _ = Kotlin.defineRootPackage(null, /** @lends _ */ {
    Labeled: Kotlin.createTrait(null),
    printLabel: function (label) {
      Kotlin.println('here is label[' + label.label + ']');
    },
    MyLabel: Kotlin.createClass(function () {
      return [_.Labeled];
    }, function (label, size) {
      this.$label_xbtvxu$ = label;
      this.size = size;
    }, /** @lends _.MyLabel.prototype */ {
      label: {
        get: function () {
          return this.$label_xbtvxu$;
        }
      }
    }),
    main: function (args) {
      var myLabel = new _.MyLabel('my label', 10);
      _.printLabel(myLabel);
    }
  });
  Kotlin.defineModule('moduleId', _);
  _.main([]);
}(Kotlin));

Kotlin.out.buffer;

結構長い…

一方TypeScriptからコンパイルされたコードは結構単純です。

function printLabel(labelledObj) {
    console.log(labelledObj.label);
}
var MyLabel = (function () {
    function MyLabel(l, size) {
        this.label = l;
    }
    return MyLabel;
})();
var myObj = { size: 10, label: "Size 10 Object" };
printLabel(myObj);

個人的にはKotlinのAltJSとしての機能も、その他のライブラリーとのエコシステムの構築にかかっているかなと思っています(同じような印象はScalaJSに対しても思っている)。