Hare Lang Tutorial1からの続き...

関数とパラメーター(Functions & parameters)

functions_and_parameter.ha

use bufio;
use fmt;
use os;
use strings;

export fn main() void = {
	const user = askname();
	greet(user);
};

// Ask the user to provide their name.
fn askname() str = {
	fmt::println("Hello! Please enter your name:")!;
	const name = bufio::read_line(os::stdin)! as []u8;
	return strings::fromutf8(name)!;
};

// Greets a user by name.
fn greet (user: str) void = {
	fmt::printfln("Hello, {}!", user)!;
};

このプログラムを実行すると,Hello! Please enter your name:のあとにプロンプトで入力を待ち受け,入力された文字を"Hellor! XXX"のように出力する. 関数はプログラムの処理を実行する基本単位で複数のタスクをひとかたまりにして呼べるようにしたもの. 関数は,引数(parameters)のリストを受けとることができ,関数名につづく()にリストが記述される. greetstr(文字列)型の引数をuserという名前で受けとる. 関数は処理の結果を呼び出し元に_返す(return)askname関数は返す値(返り値)としてstr型を宣言する. main関数は,askname関数の返り値をuser(変数)に保存して,greet関数に_渡す

よりくわしく(A closer look at bufio::read_line)

asknameのように標準ライブラリ関数bufio::read_lineも返り値を返す. heredoc bufio::read_lineコマンドでドキュメントをみてみる.

fn read_line(h: iohandle) ([]u8 | io::EOF | io::error)

関数のシグニチャ(パラメーターと返り値の組み合わせ)は少し複雑で,タグ付き共有体(tagged union) とよばれる,値のいくつかの種類(または )のうちひとつを返す.[]u8 - 読み出したいバイト列を格納した"slice"か,io::EOF- “end of file"に到達したことを示すか,io::error - I/Oエラーを示す,のいずれかを返す.

haredoc io::errorコマンドを実行してみる.

// Any error which may be returned from an I/O function.
type error = !(...errors::error | underread); 

すると,シグニチャの前に!(error_flag)が付いている.これはio::errorerror type であることを意味する. 次にharedoc io::EOFコマンドを実行する.

// Indicates an end-of-file condition.
type EOF = done;

// Reads up to len(buf) bytes from a [[handle]] into the given buffer, returning
// the number of bytes read.
fn read(h: handle, buf: []u8) (size | EOF | error);

// Reads an entire buffer, perhaps issuing several [[read]] calls to do so. If
// EOF is immediately encountered, it is returned; if [[EOF]] is encountered
// partway through reading the buffer, [[underread]] is returned.
fn readall(in: handle, buf: []u8) (size | EOF | error);

// Performs a vectored read on the given file. A read is performed on each of
// the vectors, prepared with [[mkvector]], in order, and the total number of
// bytes read is returned.
fn readv(fd: file, vectors: vector...) (size | EOF | error);

!が付いていないことを見る.ファイルの終端への到達はエラーとみなさない.前述のとおり,!は_error_assertion operator_ (エラーアサーション演算子)でエラーケースとして扱われる. []u8io::EOFはその対象ではない.

これに対応するために,as演算子を使って,値を[]u8とみなすように処理する - これは,型アサーションと呼ばれる.他のアサーションと同じく,コンパイラは,処理内容をチェックし,間違っていることが分ればプログラムをクラッシュさせる.プログラムを実行し,名前を入力する代わりにCtrl+Dを押すことで,これのケースを再現させることができる.

ここでの収穫はharedocツールである. hare言語で処理する時には自由につかえる. このサンプルで使っているstrigns::fromutf8のような,他の標準ライブラリの関数を学ぶためにも,使ってみてほしい.モジュールそのものについて確認することもできる - haredoc fmtharedoc stringsを試してみよう.