nim tutorial part2 (1) memo [objects]

つづき

nim チュートリアル part2 のメモ

objects

nimは最小限のOOP(オブジェクト指向)をサポートしている。

type
    Person = ref object of RootObj # 
        name*: string # *がつくと public
        age: int # * ないと private? 
    Student = ref object of Person
        id: int # with and id field

var
    student: Student
    person: Person
    sample: int

student = Student(name: "Anton" , age: 5,id: 2)
person = Person(name: "sample" , age: 10)

echo student[]
# echo student    -> これはエラーになる
echo person[]

classはないが、object型をrefすることで同じようなことはできる。
*のありなしで、public/privateをわけている。継承もできるが、多重継承はサポートしていない。ここらへんはPythonと異なる。
typeっていうのがあるので、お気づきかもだが、いくつか型を指定できる。enumとかobject とか ref objectとか…
それは次回。

nim lang チュートリアル(4) (distinct,modules)

つづき

distinct

これは他の言語でもあるのかな。理解するまで時間がかかったものだが、どうやらある型をベースに
異なる型を生成するもよう。

下記の例だとエラーになる

type  Dollar = distinct int

var  d: Dollar

echo d + 1   // Error: type mismatch: got (Dollar, int literal(12))

int型をベースにDollar型を生成している。
だが、演算子までは使えない

modules

nimはmodule機構がある

import

おなじみimport

import strutils

モジュール内の関数を読み込まないこともできる

import strutils expect isDigit

var a: string = "1"
echo isDigit(a)  // Error: undeclared identifier: 'isDigit'

コンパイルエラーになる

from statement

moduleの中からなにを使えるようにするか選択できる

from mymodule import x ,y ,z 
x()  # OK
from mymodule import nil
x()  # error
mymodule.x()  # OK

aliasも指定できる

from mymodule as m import nil
m.x()  # OK

include statement

モジュールのファイル分割時に使用するみたい

include fileA  , fileB , fileC

nim lang チュートリアル(readLine,if,case,let,const)

こちらの写経 -> https://nim-lang.org/docs/tut1.html

echo "What's your $name ?"
var name = readline(stdin)
echo "Hi, " , name , " !"

標準入力

readline(stdin) で標準入力を受け付けるもよう
JavaのSystem.inみたいなものかな

コンパイルは下記コマンドで

$ nim c Hello.nim
$ ./Hello

変数宣言はTypescriptっぽい感じ

var 変数名: 型

// 代入の場合
var 変数名: 型  =  値

// まとめて指定もできる
var x , y : int

// 改行で指定もできる
var
  x , y: int
    a,b,c: string

// まとめて代入もできる
var
  x , y: int = 1
    a,b,c: string = "abcdefg"

const と let

constが使える。Javaでいうstatic final な感じかな

const x = "abc"
x = "def"  // <- エラーになる

letも使える。Javaでいfinalな感じかな。

let x = "abc"
x = "def"

上の2つの例をみるとconstとletの違いが無いように思えるが、constはコンパイル時に値が決定している。
letは使用時に1度だけ値を入れることが可能になる

let x = readLine(stdin)     // OK

const x = readLine(stdin)  // NG

このような感じである

if statement

if文では、Pythonと同じようにインデントで制御されるので、インデントがないとちゃんと動かない

let name = readLine(stdin)
if name == "":
  echo "empty value"
elif name == "name":
  echo "name is name"
else:
  echo "Hi , ", name , "!"

こんな感じ

下記はPythonだが、まったく同じ

if a == 1:
    print(1)
elif a == 2:
    print(2)
else:
    print("else")

case statement

case文はレンジ指定とかで使うっぽい

from strutils import parseInt

let n = parseInt(readLine(stdin))
case n
of 0..2, 4..7: echo "The number is in the set: ", n
of 3, 8: echo "The number is 3 or 8 ", n
else: discard

三点リーダの両端を含めた間の値が選択される

一旦ここまで

MacでNimの事始め

世間的にはGoな感じなんだが、Nimの方がいいなーわかりやすいなーとおもったので、メモ。

Macではbrewでインストールできるので、brewで。

$ brew install nim

$ nim
Nim Compiler Version 0.18.0 [MacOSX: amd64]
Copyright (c) 2006-2018 by Andreas Rumpf

nimで簡単にコード書いてみる

# Hello.nim

echo('Hello Nim!')

これでコンパイルかけて実行する

$ nim c Hello.nim 

出来上がったファイルで実行する

$ ./Hello
Hello Nim!

めちゃ簡単

ちなみに、jsにもコンパイルできる

$ nim js Hello.nim

jsは、コンパイルするとnimcacheというディレクトリ配下にjsファイルが作られる

中身をみると…

/* Generated by the Nim Compiler v0.18.0 */
/*   (c) 2018 Andreas Rumpf */

var framePtr = null;
var excHandler = 0;
var lastJSError = null;
if (typeof Int8Array === 'undefined') Int8Array = Array;
if (typeof Int16Array === 'undefined') Int16Array = Array;
if (typeof Int32Array === 'undefined') Int32Array = Array;
if (typeof Uint8Array === 'undefined') Uint8Array = Array;
if (typeof Uint16Array === 'undefined') Uint16Array = Array;
if (typeof Uint32Array === 'undefined') Uint32Array = Array;
if (typeof Float32Array === 'undefined') Float32Array = Array;
if (typeof Float64Array === 'undefined') Float64Array = Array;

function toJSStr(s_15403) {
            var len = s_15403.length-1;
    var asciiPart = new Array(len);
    var fcc = String.fromCharCode;
    var nonAsciiPart = null;
    var nonAsciiOffset = 0;
    for (var i = 0; i < len; ++i) {
      if (nonAsciiPart !== null) {
        var offset = (i - nonAsciiOffset) * 2;
        var code = s_15403[i].toString(16);
        if (code.length == 1) {
          code = "0"+code;
        }
        nonAsciiPart[offset] = "%";
        nonAsciiPart[offset + 1] = code;
      }
      else if (s_15403[i] < 128)
        asciiPart[i] = fcc(s_15403[i]);
      else {
        asciiPart.length = i;
        nonAsciiOffset = i;
        nonAsciiPart = new Array((len - i) * 2);
        --i;
      }
    }
    asciiPart = asciiPart.join("");
    return (nonAsciiPart === null) ?
        asciiPart : asciiPart + decodeURIComponent(nonAsciiPart.join(""));



}

function rawEcho() {
              var buf = "";
      for (var i = 0; i < arguments.length; ++i) {
        buf += toJSStr(arguments[i]);
      }
      console.log(buf);
}

function makeNimstrLit(c_15003) {
            var ln = c_15003.length;
    var result = new Array(ln + 1);
    var i = 0;
    for (; i < ln; ++i) {
      result[i] = c_15003.charCodeAt(i);
    }
    result[i] = 0; // terminating zero
    return result;



}
var nimvm_6539 = false;
var nim_program_result = 0;
var globalRaiseHook_12005 = [null];
var localRaiseHook_12010 = [null];
var outOfMemHook_12013 = [null];
rawEcho(makeNimstrLit("Hello Nim!"));

いやー。これ、人の手でメンテできるのかな?