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

新言語Noopのおもしろそうなところまとめ

今朝起きたらGoogleがNoopなんて新しい言語を作っててびっくりしました。ついに言語まで作るようになったか、Google

http://code.google.com/p/noop/

ちゃんとしたまとめはだれかが作ってくれると思うので、ここから面白そうな部分だけ取り上げてみる。


まず、Noopの特徴なんですが、このようにうたわれています。(英語わかんないところは省略)

Yes

  • テストしやすい
  • イミュータブル
  • 読みやすい文法
  • 実行可能で古くならないドキュメント(rdocとかjavadocみたいなやつ?)
  • 強い型づけ
  • 整理された標準ライブラリ

No

  • subclassing
  • プリミティブ
  • 紋切り型のコード

……それなんて関数型言語

実際のコード

コメント
  • //* *// とか {* *} とか /*! !*/ でくくればコメントになります。
  • @なんちゃら とか書くとjavadocと連携したリンクを生成
class Foo(Bar bar) {
  /*!
    A brief description which ends at the first dot followed by a space or new line. 
    Details follow here.
    @param bar Bar description
    @since 1.1
  !*/

  public Foo foo(Bar bar, Bar bar) {
    /*!
      A brief description which ends at the first dot followed by a space or new line. 
      Details follow here.
      @param bar Bar description
      @return Foo for bar 

      @code
      Foo foo = obj.foo(bar1, bar2);
      @endcode
     !*/
  }
}
  • Hashはこんなかんじで使います。
bind(Key.get(Service.class, Transactional.class)).to(TransactionalService.class)
bindConstant().annotatedWith(Port.class).to(9876);
  • 型は定義できる
class Flags() {
  alias Int Port;
}

こんな風に定義すると、

Port => 9876;

こんなかんじや、

import Flags.Port;
class Server(Port portNumber) {}

こんなふうにかける。この例だけみるとCのtypedefがちょっと面倒担っただけに見えますね。きっとFlagsでいろいろ拡張したりできるんでしょう。

委譲
  • delegateってキーワードがあってスマートに行えるそうです
class FakeBankService(delegate BankService b) {
  override Int balance() { return 0; }
}
BankService mock = new FakeBankService(BankService.noop());
  • というかNoopには継承がなくてすべて委譲でやるみたいです
class Dog(Animal delegate) composes delegate {
  Int numberOfLegs() {
    return 4;
  }
}
Animal dog = new Dog(); // works!
Nullオブジェクト
  • Nullオブジェクトがあります。
interface FooInput {
  void increment();
}

interface FooResult { ... }

interface Foo {
  void doFoo(FooInput input);
  FooResult getFoo();
}

null Foo {
  void doFoo(FooInput input) {
    input.increment();
  }

  FooResult getFoo() {
    return new FooResult(5);
  }
}

こんな風にFooを定義しておくと、

Foo foo = null;
foo.doFoo();  // Does not throw NullPointerException, performs a no-op by default
assertTrue(null == foo.getFoo()); // Does not throw NPE, performs a no-op and returns null by default

インスタンスを生成してなくてもNullPointerExceptionを吐かなくなります。

多値
class Foo() {
  String, String getThings() {
    return "a", "b"; 
    // or maybe just return a List<String>, but need to guarantee a matching size
  }
}

(String x, String y) = getThings();

返す値の数は毎回変化してもOK

String head;
List<String> tail;
(head, tail) = returnsManyStrings();
例外
  • エラーをError型の変数に突っ込んでおいて後で処理できます。
class Int() {
  Int, Error parse(String s) {...}
}

Int a, Error e = new Int().parse("13a");
if (e.isError()) {
  // handle error
} else {
  // a must be a good int
}
  • 省略して_を使って書くこともできます。
Int a, _ = new Int().parse("100");