No Such Blog or Diary

«Prev || 1 | 2 | 3 | 4 | 5 | 6 |...| 57 | 58 | 59 || Next»

「一番嫌いなプログラミング言語は何?」

結構悩んだ.そもそも嫌いな物を思いつくとか難しい気がするのだけど,悩んだ結果 perl が一番嫌いなんじゃないかと.「使いたくない=嫌い」という解釈で.任意の目的に対して積極的に使用を回避したくなるのは perl しか思いつかん.

以下,答えを探している最中の思考.

sed:ロマン.頭の体操.やればなんでもできる便利な子.ワンライナーに必須.

C++:速い.演算子オーバーロードは素晴らしい.template で頑張るととても楽しい.

Haskell:遅延評価バンザイ.型推論バンザイ.高階関数バンザイ.参照透明バンザイ.

Java:どこでも動く.GCは素晴らしい.遅くない.リフレクションで頑張るととても楽しい.

awk:数値を使うワンライナーに便利.

bash:言語かこれ? バッチ処理には十分.

Python:キレイなスクリプト言語.

アセンブリ言語:速度のために必須.インラインで使うけど.

Lisp:なんでもありの素晴らしき自由.mix.eval/apply.

FORTRAN:良くも悪くも数値計算に必要十分.

C言語:真のC言語は安全.union は素晴らしい.#define で頑張ると楽しい.

OCaml:高階関数とか型推論とか欲しいけと遅延評価とか要らないし汚いことしたい時用.

php:web に関連するものならこれで.HTML との親和性が一番良いんじゃないかなと.

JavaScript:ブラウザで動くLispだよね.

閑話休題.

これを次の自己紹介の項目に入れよう.

多次元配列とポインタのポインタと

時々「配列とポインタは同一視出来る」という説明を聞くのだけど,これって良い説明なのか悪い説明なのかよく分からない.特に,多次元の配列の解説と同時にこの説明があるのはどうなのかなぁとか疑問に思う.1次元の配列を扱う範囲に置いては特に文句はないのだけど.

多次元配列の解説においては,「多次元配列=ポインタのポインタ」という説明になる.仮に float c[10][20] という配列と float **d というポインタがあった場合,この説明では c = d とした以降は c と d がプログラム中で同一に扱えることになる.が,実際には c と d はインクリメントとかデリファレンスの挙動とかが違い,同一視すると痛い目を見る.正しくは,c は 20要素の float 配列のポインタ(float (*)[20]と書くのか?)と同一視出来る程度であって float ** とは別物と.

ということで,下のプログラムを動かすと c と d が別物だとよく分かる.c と e は同じ挙動.

main(){
  float c[10][20], **d, (*e)[20];
  d = c;
  e = c;
  printf("%p %p %p\n", c, d, e);
  printf("%p %p %p\n", c+1, d+1, e+1);
  printf("%d %d %d\n", c == *c, d==*d, e==*e);
}

結果は以下の通り.

0x7fff7bca9320 0x7fff7bca9320 0x7fff7bca9320
0x7fff7bca9370 0x7fff7bca9328 0x7fff7bca9370
1 0 1

久々にHaskellでフィボナッチ数列の計算を書いてみた

とりあえず普通のHaskellプログラマが書くであろうフィボナッチ数列の計算:

fib = 1:1:[a + b | (a, b) <- zip fib (tail fib)]

Parallel List Comprehensions を使ってみた書き方:

fib = 1:1:[a + b | a <- fib | b <- tail fib]

Generalised (SQL-Like) List Comprehensionsを(無駄に)使った書き方:

fib = 1:1:[sum a | a <- fib, then group using (\b -> zipWith (\c d->[c,d]) b (tail b))]

こいつは -XTransformListComp で機能を有効する必要あり? とりあえず束縛時と使用時で変数 a の型が変わるのがまぎらわしい.ついでに using の後の関数の型が forall a. [a] -> [[a]] でないといけないのを時々忘れて怒られる.ついでに by をつけたときには forall a. (a -> t) -> [a] -> [[a]] でないと怒られる.第一引数の (a -> t) という型の部分には by の後に指定する式から作られる関数が渡されるので,そこでリストの要素を見て適当な型 t の要素に射影して,その結果を使ってリストの要素をリアレンジしても良いよと.でも,その関数以外ではリストの要素に触れてはいけないよと(forall がついてるから).むずい.

さらに -XViewPatterns を有効にして無駄に分かりにくい書き方をしてみる.機能の無駄遣い.

fib = 1:1:[sum a | a <- fib, then group using (\c@(tail->b)-> zipWith (\((:[])->c) d -> d:c) c b)]

とりあえず,変なプログラムを書いたおかげで Generalised (SQL-Like) List Comprehensions の使い方が分かった(元論文はだいぶ前に読んであったのだけど).

久々にHaskellでフィボナッチ数を計算する関数を書いてみた

fib((-1+)->n@((-1+)->m))|m<0=1|((,,fib n)m->(fib->x,_,y))<-()=x+y

ViewPatterns, PatternGuards, TupleSections の拡張機能を使ってみたかっただけともいう.

View patterns はパターン部分に計算を書けるしそれを連ねることもできるので(関数結合と逆向きだけど),なんとなくモナド(のbind演算子)でプログラムを書いている気分を味わえる気がする.Pattern guards はまあ面白い使い方がまだ思いつかない.Tuple sections は場合により便利だけど変なプログラムを書くのには使いにくいかも? λ式にも view patterns 書けるので,かっこを使いまくりな id 関数とか:

i=(\((,)() -> ((),x)) -> x)

ついでなので階乗を求める関数も.

fact n|1>n=1|((-1+)->fact->x)<-n=n*x

Hadoop でまた大いに嵌る

今度の症状は datanode が namenode に接続できないというもの.ログをみると

INFO org.apache.hadoop.ipc.Client: Retrying connect to server: namenode/:8020. Already tried 9 time(s).
INFO org.apache.hadoop.ipc.RPC: Server at namenode/:8020 not available yet, Zzzzz...

とかいうのが延々と……

で,結局のところ conf/core-site.xml で namenode の名前を FQN で書かずにホスト名だけで書いていたので namenode の RPC 受付けポートが 127.0.1.1:8020 とかになっていたというオチ(/etc/hosts に 127.0.1.1 namenode という記述がデフォルトで入ってたから).これじゃあ外から繋がらない.

これに気づくまでに半日かかった.アホだ……

閑話休題.

とりあえず動くようになったので動かしたら並列化の効果ばっちり.数の暴力バンザイ.

Hadoop で大いに嵌った

ほとんど同じパターンで Hadoop を使いまくるので,面倒だから Hoge というクラスに Hadoop を動かす部分を全部書いておいて,それを jar に固めて $HADOOP_HOME/lib に入れておいた.使うときには,下みたいに Hoge にパラメータとなるクラス(例えば Fuga)を引数で渡すという形にする.

bin/hadoop jar Fuga.jar Hoge Fuga

で,Hoge の Hadoop 呼び出し部分を何も考えずに

  public static void main(String[] args) throws Exception  {
    //...
    job.setJarByClass(Hoge.class);
    //...
  }

とか書いて動かそうとしたら,Fuga のクラスが見つからねぇと Mapper の初期化時辺りに怒られまくった.しばらく理由も分からず…… 3時間ほど独り Hadoop 読み会をした.

結局のところ,job.setJarByClass の引数に Fuga.class のほうを指定しておかないとそれを含む Fuga.jar をワーカに転送してくれない,というオチ.こんなことそこら辺のドキュメントにちゃんと書いてあるような気もするけど,頭の中ではただのおまじないになっていたので全然気づかなかった.アホ.

でもまあ,ぶっちゃけコマンドラインに指定した jar を job.jar として転送してくれる設計でよいと思うのだけど,なぜにわざわざクラスをひとつ指定してそれを含む jar を job.jar として転送するとかいう仕様になっているのだろう?

とりあえず -libjars, -files, -archives で問答無用に必要なファイルを指定しておくのがよいのかもしれない.

閑話休題.

コードを読んでみての感想:org.apache.hadoop.mapred と org.apache.hadoop.mapreduce を行ったり来たりしているのでとても汚い.キレイな Hadoop が欲しい.

«Prev || 1 | 2 | 3 | 4 | 5 | 6 |...| 57 | 58 | 59 || Next»
Search
Feeds

Page Top