ひしだまの変更履歴

ひしだまHPの更新履歴。
主にTRPGリプレイの元ネタ集、プログラミング技術メモと自作ソフト、好きなゲームや音楽です。

関数リテラルとかトレイトとか

2010-12-25 23:59:47 | PG(Scala)

今日はScalaの関数リテラルとか関数の型とかトレイトについて勉強していましたよ。
ちょっと割り込みでfor式のメモとか追加したりもしましたね。
久しぶりに特に用事の無い休日だったので、Scalaの勉強がはかどりましたよ。
(12月25日近辺って、世間的には何かあったような気がしないでもないような気もするけど、きっと気のせいですねー)
これでコレクション(ListやMapトレイト、foreachやmapメソッド等)の勉強へ進める準備が出来てきた感じですかねー。

ちなみにこの口調は、plasticscafeさんの(LL脳がscalaの勉強を始めたよ)が移ったものですねー。
最近このブログを読み進めているもので。いやぁ、ほぼ毎日これだけの期間続けているのがすごい!

コメント
  • X
  • Facebookでシェアする
  • はてなブックマークに追加する
  • LINEでシェアする

Scalaのmap

2010-12-15 23:59:12 | PG(Scala)

0x82,0xA8,0x82,0xC8,0x82,0xA9,0x82,0xB7,0x82,0xA2,0x82,0xBD
という文字列を見かけたら、文字コードっぽいから、何の文章になっているか知りたくなるのが人情。

変換プログラムを何の言語で作るか(あるいはバイナリエディターで直接ファイルを作っちゃうとか)は人それぞれだと思うけど、Javaで作るとこんな感じ。
public class Convert {
 public static void main(String[] args) throws java.io.UnsupportedEncodingException {
  final int[] xs = { 0x82,0xA8,0x82,0xC8,0x82,0xA9,0x82,0xB7,0x82,0xA2,0x82,0xBD };
  final byte[] b = new byte[xs.length];
  for (int i = 0; i < xs.length; i++) b[i] = (byte)xs[i];
  System.out.println(new String(b, "MS932"));
 }
}

ちなみに直接バイト配列の初期値に設定しようと思ったけど、int→byteへの変換で「精度が落ちる」というコンパイルエラーが出るので、出来ない。

けど最近Scalaを勉強しているんだから、Scalaで書いてみよう(Javaだと毎回コンパイルがいるし)…と思って書いたのがこれ。
(直接バイト配列に入れようとするとエラーになるのはJavaと同じだった)
def f(xs:Int*) = {
 val b = new Array[Byte](xs.length)
 var i = 0
 for (x <- xs) { b(i) = x.toByte; i += 1 }
 new String(b, "MS932")
}
f(0x82,0xA8,0x82,0xC8,0x82,0xA9,0x82,0xB7,0x82,0xA2,0x82,0xBD)

でもこれ、Scalaプログラムとしては明らかに駄目駄目orz

で、Arrayの代わりにListBufferを使ってみた。
def f(xs:Int*) = {
 val b = new scala.collection.mutable.ListBuffer[Byte]
 for (x <- xs) b += x.toByte
 new String(b.toArray, "MS932")
}

もうちょっと何とかなりそうな気もするけど、どうすればいいか思い付かず、とりあえずTwitterに出してみた。
(ツイートする為に一行にしたら136文字。ツイートは140文字までだから、ぎりぎりw)

そうしたら、mapを使えば?というアドバイスをいただいた。
なるほど、Scalaの本とかを見ているとfilterやらmapというのが出てきていた気がする。で出来たのがこれ。
def f(xs:Int*) = new String(xs.map(_.toByte).toArray, "MS932")
おお、これは何となくScalaっぽい気がする!

→Togetter「文字コードのデータを文字列に変換するプログラム


まだScalaを勉強中なので、やはりfilterやmapといった関数は自力では思い付けないんだなぁ。
そういえば、自分が新しい言語を勉強するときは、(1)知っている言語の機能(構文)と比較する、(2)ライブラリーをざっと眺める(どんな関数・クラス・メソッドがあるかを知る)、をするんだけど、Scalaではまだそれが途中だった。

今のところ、Scalaの構文はtry~catchをメモしようと思って、形式がmatchに似てるからそちらを先にまとめていた。
ライブラリーの方は、PredefStringのメソッドをざっと見てみただけ。

コレクション(ListとかListBuffer)のメソッドを眺めてみれば、filterとかmapが出てくるはず。(もしかしたらStringにもあったかもしれないが、あったとすればCharの並びを処理するもののはずで、そういった使い方を自分がするとは思えなかったから、読み飛ばしたかも)

その前にコンストラクターや関数リテラルの定義方法とかもまとめたい。…色々先は長いなー^^;


ちなみに「マップ」と聞くと、まずはJavaのMap(HashMap)が思い浮かぶ。
最近ではHadoopのMapReduceのMap処理とこんがらがる事も…。
これにScalaのようなmap関数(マッピングする=対応付ける?)が加わると、余計ややこしくなりそう^^;
(さらに某業界ではマップと言えば地図のことで、マッピングと言えば地図を描くことだが、さすがにこれは区別がつくかw)

コメント (2)
  • X
  • Facebookでシェアする
  • はてなブックマークに追加する
  • LINEでシェアする

『Scalaで学ぶ関数脳入門』

2010-12-12 01:51:09 | PG(Scala)

『オブジェクト指向プログラマが次に読む本 Scalaで学ぶ関数脳入門』読了。

「オブジェクト指向プログラマが次に読む本」ってけっこう露骨に煽り文句っぽいと思ったけど^^;、でもホントJavaプログラマーが読むにはいいかも。
関数型プログラミングの基礎として「副作用」についての説明とかちゃんとあるし、「funarg問題」なんて知らなかったなー。他にも高階関数とかクロージャとか共変アノテーションとか、色々な用語も説明されている。

実際、Javaでもなるべく副作用の無いメソッドを作る方がいい(JUnitでテストしやすいし)と思っているが、新人に「副作用の無いようにプログラムを書け」と言っても“副作用”の説明からしなきゃいけないので大変なんだよね。
「C++で関数宣言の後ろに付いているconstはどういう意味?」っていうのを調べたことがあれば副作用という言葉が出てこないはずが無いんだけど、新人にそんなの望むべくもないし(爆)
(そういう意味ではDBアクセスを行うと必ず副作用が発生するんだが、そこを解説したScalaの本ってあるのかなぁ?)

他には再帰やパターンマッチの説明でそれぞれ章が立てられている。
再帰呼び出し自体は知ってるけど、Javaでは使ったことないなぁ。そこら辺がすんなり頭に入ると関数脳になるんだろうな(笑)
Scala以外の関数型言語を勉強したことが無いので、パターンマッチがそんなに関数型言語にとって重要だとは知らなかったけど、実際これすごく強力・便利そう。
別の章に言語処理の例(yaccとlexのような構文解析をScalaのパーサコンビネーターライブラリーを用いて作ってみる)が出てくるんだけど、パターンマッチのせいで無茶苦茶すっきりしてるし!
(パーサコンビネーターがあれば、自分がJavaで作った解釈クラスなんて全く不要^^;)

あと、並行プログラミングとして通常のスレッドの使い方・ロックの方法から始まってアクターの説明に進んでいるのも良かった。
アクターのサンプルとして、MapReduceのアルゴリズムを独自実装する例が出てきたのには驚いたけど(笑) (もっとも、HadoopのMapReduceとは引数の渡し方が違う(ような気がした)のとアクターの使い方に慣れていないのとがあって、あまり理解できなかったのだけれど。アクターは重要そうなだけに、まだまだ精進が必要だ…)

まれに誤字を見つけたけど、まぁよくある範囲か。(ピリオドをコロンと書いてある(p.91)のはさすがにどうかと思うが^^;)

さて、次はコップ本に挑戦してみたい。が、原著(英語)で第2版が出たらしいので、その日本語訳が出るまで待ちかなー。

コメント
  • X
  • Facebookでシェアする
  • はてなブックマークに追加する
  • LINEでシェアする

マンガ『空の軌跡』

2010-12-09 23:59:16 | マンガ

なにげなく本屋に行ったら、マンガの『空の軌跡』が売っていてびっくり!(なかなかやるな、近所の本屋その1!)
そんなものが出るとは(どこかで連載されていたとは)全然知らなかった!

懐かしいねぇ、確かにゲームはこういう話から始まってたよ(笑)
ジョゼットとかレンの登場の仕方はちょっと違うけど、まぁ全部原作と同じくやってたら全然話が進まないしな^^;
(こういったマンガではよくある事だけど)絵柄が原作と違うんでちょっと違和感あるが、特徴ある台詞はそのまんまw さすがだw ちょっと前にイースvs.空の軌跡をやってた事もあって、脳内に音声が再生される(爆)

いいねぇ、またやりたいなぁ。(ガガーブ三部作も時系列に沿ってやってみたりしたい。)
しかし他にもやりたい事が立て込んでて、しばらくはとても無理なんだよなぁ。零の軌跡も我慢中だし><

P.S.
歴代ファルコムの隠しキャラ、言われても分からんくらいだよ^^;

コメント
  • X
  • Facebookでシェアする
  • はてなブックマークに追加する
  • LINEでシェアする

#line・#error

2010-12-09 06:24:17 | PG(C言語)

C言語を使っていてプリプロセッサ命令の#defineを知らない人はいないだろうし、#if・#ifdef辺りも知られていると思う。
でも#lineとか#errorはあまり知られていない気がする。

#lineは、元となったソースのファイル名と行番号を示すもの。
(コンパイラーによっては、)コンパイルエラーになった時に、その元となったファイル名を表示してくれる(かもしれない)。
逆に言うと、本当にエラーが出た場所が分からなくなる可能性もあるけど^^;

#errorは、コンパイルエラーを発生させるもの。
ヘッダーファイルがちゃんと読み込まれているかどうか・あるいは記述されている定義が#if等によって無効になっていないかどうかを確認する為に、#errorを埋め込んで、そのエラーが出るかどうかで判定する…なんて使い方が出来るかも。

C言語で「(定義されているはずの)構造体が見つからなくてコンパイルエラーになる」というような場合、その定義近辺で何か間違っている可能性が高い。
定義がきちんと読み込まれているかどうかの確認に#errorが使えるんじゃないかなーと思う。

コメント
  • X
  • Facebookでシェアする
  • はてなブックマークに追加する
  • LINEでシェアする