Nemerle for OOP Programmers Week 1 (4)

カスタム属性

たぶんC#のそれと一緒なんでしょう.
Nemerleでは,カスタム属性はtop-levelマクロで再利用されると書かれていて,とりあえずtop-levelマクロってなに?ってところが気になりますね.まぁ楽しみは先にとっておきましょう.

メソッド

メソッドはコードをグルーピングするために使われますよと.グルーピングしたものを再利用したいときにはメソッド名を利用して……,はい,なんか拍子抜けするくらいにあっさり書かれてます.関数型言語というからにはもっといろいろありそうなのに.

フィールド

これもC#とほとんど変わりがないみたいです.唯一immutabilityだけが異なる……というか,ここがすべてですね.
Nemerleでは,mutableキーワードを付けないと,フィールドはstaticコンストラクタまたはインスタンスコンストラクタ(通常のコンストラクタ)でしか値を設定できません.
ただし以下の書き方は出来ます.

class Test {
  static public x : int = 1;
  static public y : int = 2;
}

フィールドの定義と同時に書くやり方ですね.この書き方をしない場合フィールドは0とか0.0とか参照型であればnullで一旦初期化されることになります.

インスタンスコンストラク

C#だとコンストラクタ名はクラス名と一緒ですが,Nemerleだとthisになります.
例えばこんな感じ

class Point {
  public x : float;
  public y : float;
  public this (ini_x : float, ini_y : float)
  {
    x = ini_x;
    y = ini_y;
  }
}

この例ではインスタンスコンストラクタの引数名とフィールド名がかぶらないようにしてますが,同名にすることも出来ます.

class Point {
  public x : float;
  public y : float;
  public this (x : float, y : float)
  {
    this.x = x;
    this.y = y;
  }
}

インスタンスコンストラクタの使い方の例

def the_point = Point (3.14f, -3.14f);

利用する側はthisではなくクラス名を使います.またnewキーワードがないですね.
左辺に型がないのは型推論が働くから.たしかに

def the_point : Point = Point (3.14f, -3.14f);

って書き方はくどいですよね(もちろんコンパイルはできますけど).
ところで脱線しますが,フィールドの型は省略できないのかな?
実験してみました.

using System;

class Point {
  public x : float; 
  public y;         // インスタンスコンストラクタで型推論される?
  public this (x : float, y : float)
  {
    this.x = x;
    this.y = y;
  }
}

def the_point : Point = Point (3.14f, -3.14f);
Console.WriteLine("Point(x={0},y={1})", the_point.x, the_point.y);

--(実験結果)
[ncc] Compiling 1 files to 'C:\work\0630\Point.exe'.
[ncc] C:\work\0630\Point.n:5:10:5:11: error: type inference for fields is available only when assigning literal value to them
[ncc] C:\work\0630\Point.n:5:10:5:11: error: type inference not allowed here

BUILD FAILED

まぁ,そうですよね(^^;;

Recordマクロ

Pointクラスですが,こんなふうにも書けます.

using System;

[Record]
class Point {
  public x : float; 
  public y : float;
//  public this (x : float, y : float)
//  {
//    this.x = x;
//    this.y = y;
//  }
}

def the_point : Point = Point (3.14f, -3.14f);
Console.WriteLine("Point(x={0},y={1})", the_point.x, the_point.y);

インスタンスコンストラクタがフィールドに値を設定しているだけなら,Recordマクロを使うとコーディングを行なわなくて済むと.なるほどね.

デフォルトコンストラク

コンストラクタを1個も用意していない場合は,引数なしのデフォルトのコンストラクタが用意されます.
これもC#と同じ.OKです.


今日はここまで.