3
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

Nemerle入門Ⅰ ~インストール,言語説明,C#に近い機能の説明~

Last updated at Posted at 2016-02-21

筆者の動作環境は,Nemerle入門の目次をご覧ください.

ダウンロードとインストール

このページからダウンロードできます.
残念ながら,最近のVisual Studioには拡張機能が対応していません.

Nemerleとは

C#,Lisp,Ruby,Python等,沢山の言語機能を詰め合わせた.NET Frameworkで動く言語です.

Macro(メタプログラミング)

Nemerleの注目機能の一つ,Macroによって,柔軟なメタプログラミングができます.
今後紹介する,if文,foreach文などの文はほとんどMacroによって実装されています.色々工夫すれば,Nemerleを様々な言語の書き方で書けるようになります.この機能によって,アスペクト指向プログラミング,部分評価,ドメイン固有言語の組み込みとかできるらしいです.(Wikipediaより)

関数型プログラミングがC#よりもやりやすく,F#よりC#風に書ける

Nemerleはそれぞれの言語の良さを取り入れている(主観)ので,イケてます.

イケてる型推論

型推論
def li = List(); //コンストラクタで初期化
//liはジェネリック型List[T]と宣言される
def n = 1;
//int型のnを宣言,1を代入
li.Add(n);
//liはList[int]と型推論される.
li.Add("Nemerle");
//デキナイヨ

もちろん,C#はできません.

型推論
var li = new List<>(); //Compile Error!
//デキナイヨ
var n = 1;
//int型のnを宣言,1を代入
li.Add(n);
//だからliってナンゾヤ
li.Add("Nemerle");
//だから,デキナイヨ

プロジェクトの作成,どこにコード書く?

Visual Studioから新しいNemerleConosleProjectを作ってください.
こんな感じのソースコードが出てくるはずです.

Main.n
using Nemerle.Collections;
using Nemerle.Text;
using Nemerle.Utility;

using System;
using System.Collections.Generic;
using System.Console;
using System.Linq;

module Program
{
  Main() : void
  {
    WriteLine("Hi!");
    _ = ReadLine();
  }
}

実行してみて,"Hi!"が表示されて,なんか入力して,Enter押すと黒画面が閉じるはずです.
これから,"WriteLine("Hi!")"の部分を書き換えていきます.

変数・定数,初期化,代入(束縛)

宣言

mutable name : type = value
def name : type = value

または

mutable name = value
def name = value

nameには変数名,typeには型名,valueは値を入れます.
変数はmutable,定数はdefを用います.
上は,型を指定して宣言,下は,型推論をしています.型推論の場合,宣言時に型がわかるような代入・初期化をしなくても結構です.

型推論
mutable x = null; //xってどうなるの?
x = Console.ReadLine(); //ReadLineの戻り値はstring.すなわち,xはstring型なのか!!

初期化(コンストラクタの呼び出し)

intなど,プリミティブ型などは,def hoge = 1で結構ですが,その他は,コンストラクタを呼ぶ必要があります.ここでは,一般的な型のコンストラクタの呼び出しを説明します.

コンストラクタ
def name = type_name(arguments) //非ジェネリック型
//例
    def string_builder = StringBuilder();

def name = type_name.[T](arguments) //ジェネリック型
//例
    def lazy_object = Lazy.[string]();

クラス変数を指定しながら初期化

文法がC#と少し違います.

コンストラクタとクラス変数の指定
class some {
  public n : int;
  public m : int;
  public this() {
    WriteLine("Constractor is called.");
  }
}

def s : some = some() <- {
  n = 0;
  m = 0;
}

代入(束縛)

C#などと同じ "=" イコールで代入します.

プリミティブ型

C#と全く同じです.

条件分岐

条件分岐に関す売る演算子(比較演算子,条件演算子)

C#と同じです.

条件がTrueの場合,Falseの場合で分岐させる(if文)

if
if(condition) {
  A
} else {
  B
}

両方共,conditionがTrueの時は,Aのコードを,Falseの時は,Bのコードを実行します.
C#のようにカッコを省略することができます.しかし,elseは省略できません.

条件がTrueの場合のみ実行する(when文)

when
when(condition) {
  Code
}

conditionがTrueの時,Codeが実行されます.

条件がFalseの場合のみ実行する(unless文)

unless
unless(condition) {
  Code
}

conditionがFalseの時,Codeが実行されます.
(when文で,論理否定演算子使って済ませることが自分は多いので,影が薄い文です.)

コメント

C#,C++と同じです.

comments
//一行コメント
/*
   複数行コメント
*/

スプリクト言語風書き方

プロジェクト作成時のMain.nは,(usingの部分は省いてます.)

Main.n
module Program {
  Main() : void {
    WriteLine("Hi!");
    _ = ReadLine();
  }
}

こうなっていたと思います.これらをコメントアウトしてください.(Ctrl + K,C)
そして以下のソースコードをコピペして,実行してみてください.

Main.n
WriteLine("Hi!");
_ = ReadLine();


実行できましたね?このように,スクリプト言語のように書くこともできます.
(C# 10にも同様の機能が実装されました.)

アクセス修飾子

publicやprivate等,C#と同じです
現在,

static,volatile,partial

これらもC#と同じです.

メソッド

Method
Method_Name(Parm1 : type, Param2 : type...) : Return_Type {
  Code
}

書式はこんな感じ.F#っぽいかな?これだけ見てもわからないので,具体例を示しましょう.

Method
void HogeHogeMethod(int start, int count) {
  //DoSomething
} //C#
Method
let hogeHogeMethod (start : int, count : int) =
  //DoSomething
  ()
Method
HogeHogeMethod(start : int, count : int) : void {
  //DoSomething
} //Nemerle

上の3つはほぼ同じです.
書き方はC#をF#みたく書いた感じでしょうか.
属性の付け方はC#と同じです.

関数

C#ならば,

return
int Add(int x, int y) {
  return x + y;
}

ですが,Nemerleでは,returnは要りません.最後の式の戻り値が返されます.

return
Add(x : int, y : int) : int {
  x + y;
}

namespace

C#/VB.netのnamespaceと同じです.

namespace
namespace hoge {
  class hoge {
    ...
  }

  module hogeUtil {
    ...
  }
}

class

C#/Vb.netのclassと同じです.
クラスを定義することができます.
クラスの定義の仕方は後で詳しく説明します.

class
class hoge {
  mutable a : int;
}

Main() : void {
  def h = hoge();
  h.a = 0;
  WriteLine(h.a);  // 0
}

module

VisualBasic .Netのmoduleと同じです.C#で言う,static classのようなものです.
moduleの中に書いた物は自動的にStaticになります.
インスタンス化はできないので,通常のクラスのコンストラクタなどは作れません.

module
module Num {
  Add(x : int, y : int) : void {
    x + y
  }
}

Main() : void {
  Console.WriteLine(Num.Add(3, 5)); // 8
  def n : Num = Num(); // Error!!
}

クラスの定義

Nemerleでも,もちろん.Netのクラスを定義することができます.他の言語と同じで,プロパティなども定義することができます.そこまで,C#/VB .netと差異は無いので軽く流します.

class
class IntPair {
  mutable a : int; //メンバ変数(アクセス修飾子がないので,自動的にprivateになる)
  public mutable b : int; //アクセス修飾子がつけられる
  private c : int; //局所定数(変更はできない)
  static class_name : string = "IntPair";
    //staticをつければ静的に,”=”で代入もできる

  public A : int { //プロパティ,C#と同じなので,そこまで気にしなくていい
    get{
      WriteLine("A is called!");
      a;
    } set{
      a = value;
    }
  }

  public D : int { get; } //getオンリーなプロパティもこの一行でおk

  public this() { //コンストラクタ
    a = 0;
    b = 0:
    c = 0;
  }

  public static this() { //静的なコンストラクタ
    WriteLine("IntPair!");
  }
}

残念ながら,C# 9のinitには対応していません.

構造体: struct

classではなく,structにすることで構造体を生成できます.

struct
struct StructBox {
  public mutable x : double = 0;
  public mutable y : double = 0;
}

レコード: Record

classもしくはstruct[Record]マクロをつけると,C# 10のレコードのようになります.

record
[Record]
class Point {
  public mutable x : double = 0;
  public mutable y : double = 0;
}

キャスト

Nemerleにキャストは2種類あります.

厳密な型変換(:)

コンパイル時にチェックされ,型変換できるかわからない時は,コンパイルエラーを吐きます.

type_enforcement
def s : short = 72;
WriteLine(200000000 / (s : long)); // short → longは元がどんな状態でも変換できるので,おk

def obj : object = 18;
WriteLine(200000000 / (obj : long)); // Compile Error!

普通の型変換(:>)

実行時にチェックされ,失敗した場合,InvalidCastExceptionを投げます.

type_cast
def a : object = "abc";
WriteLine(20000000 / (a :> long)); // コンパイルエラーはないけど,例外投げる

おわりに

入門Ⅱへ

3
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
3
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?