2008.03.31

言語占い

プログラミングGauche」を読んで、再びSchemeの魅力に取り憑かれる。PythonもC++も勉強したいし、勉強したいことが多すぎて困る。

SystemCやるならC++だし、変態を自重するならPythonだし、メタプロするならSchemeが良いよね。でも、メタプロなら、C++のテンプレートも最高だよね。って、あれだ。一緒に遊園地行くならゆうゆだけど、奥さんにするならまみまみだよね、くらいのノリなんだと思う。もちろん、僕は両方ゆうゆですが。分からない人は、冒険に行くならビアンカだけど、結婚するならフローラだよね、でもよい。僕は両方フローラですが。

いい加減男らしくばしっと決めたいので、言語占いで決める事にした。

言語占いってのは、雑誌で良くある奴ね。

問1:最先端の技術を使いたい。YES→問2へ NO→じゃあ、COBOLで
問2:英語は苦手 YES→変数をローマ字で書いてもOKなCOBOLをおすすめ NO→問3へ
問3:Webアプリを作りたい YES→そんなナンパな気持ちは捨てて、COBOLを勉強しろ。NO→圧倒的な実績のあるCOBOLをおすすめ

こんな感じで、YES、NOを答えていくだけですぐに、あなたにおすすめの言語を選んでくれる。こりゃ楽だ。
雑誌の弱点として、いまいち僕を対象にしていないというか、不特定多数を対象にしすぎている。なければ作ってしまえば良くて、自分で占いを作る事にした。前からSICPのAMBが仕事で使えないかな~と思っていたので、題材にしてみる。やる夫は五階に住んでいません、ってやつね。

問1:AMBをPythonで書いてみる。納得いく物ができたか?
   YES→問2へ
   NO→言語レベルで継続をサポートしているGaucheおすすめ。

問2:AMBをC++で書いて見る。納得いく物ができたか?
   YES→C++おすすめ
   NO→君にはC++は10年早い。Pythonがおすすめ。

ちょっと占ってみよう。

# 一応書いておくけど、ネタだからね><

| | Comments (0) | TrackBack (0)

2007.11.04

今日のシンコーシン

・C++信仰
ときどきの雑記帖 リターンズ さんから

> んとですね、わたしが「信仰」という単語を持ち出したのは、 確たる理由もなく相手の状況を一顧だにせずC/C++を押し付ける(曰く「必要だ」 「ポインタが理解できれば云々」)その態度が、宗教(特に新興宗教といわれるそれ) の押し付けに近いものを感じたからです。 ですのでなつたんさんがご自分の姿勢と態度を称して信仰といわれるのは にんともかんとも。
あっ、他人に対してなのか。誤読失礼しました。
自分自身、何でC++勉強してるのかさっぱり分からなくなって、C++信仰じゃね、って言われたときに図星を指された気がして反応してしまった。

# 図星は、突くのか指すのかわからない。
明鏡:指す
国語大辞典:突く
大辞泉、広辞苑:両方


・最強伝説
神様なんて信じない僕らのためにさんから
[c/c++]C++が最強に決まってるだろ!

> だいたい、
> 何かのコスト(お金や学習時間、調査時間など)を払わずに、
> プログラムをしようだなんてことが間違っているんだよ!!!!!!
かっこえー。

退職金でBDS狙っているんだけど、BCB5 Personalからアップグレードできないみたい。できても高そうだけど。素直に、Visual Studio買うか。

> C++はいいものだ……。
早くここまで行こう。
目標「それ、Boostで出来るの知っているけど、(前向きな理由)であえて使わない」とさらっと言えるところまで頑張る。
使えないと使わないの違い。

・Higher-Order Perl
3.11 EVANGELISM (伝道師)
If you're trying to explain to a C programmer why Perl is good, automatic memoization makes a wonderful example.
CプログラマにPerlの良いところを説明しようとしているなら、自動的なメモ化の話は見事な例になるよ。

何というタイムリー、Perlの良さを説明するのにわざわざ1節とってある。みるみる信仰心がゆらいでいく~。一応、If you are a C programmer, じゃないのが救い。

そういえばCode Completeにもプログラミングに宗教を持ち込むなで1章取ってあった気がする。こっちは真面目に書いてあったけど、新しい版にも残っているのだろうか。

・神の比較
noboshemonさんの所から
「仏教も、キリスト教も、イスラム教も、それで飯食えるくらいまでいったけど、状況による使い分けが大事だよ。」
「宗教初心者は日本に行って神道から始めると良いんじゃないかな。断食とかお布施とか無いから初心者向け」
とかいう人はいない。宗教ってそういうシステムになっているんだな。

| | Comments (0) | TrackBack (0)

2007.11.02

電卓

Higher-Order Perl、から。

Perlで逆ポーランドの電卓を作ろうという話題

#!/bin/perl
use strict;

my @stack;
my $actions = {
    '+' => sub { push @stack, pop(@stack) + pop(@stack) },
    '*' => sub { push @stack, pop(@stack) * pop(@stack) },
    '-' => sub { my $s = pop(@stack); push @stack, pop(@stack) - $s },
    '/' => sub { my $s = pop(@stack); push @stack, pop(@stack) / $s },
    'NUMBER' => sub {push @stack, $_[0] },
    '_DEFAULT_' => sub { die "Unrecognized token '$_[0]'; aborting" }
};

my $result = evaluate($ARGV[0], $actions);
print "Result: $result\n";

sub evaluate {
    my ($expr, $actions) = @_;
    my @tokens = split /\s+/, $expr;
    
    for my $token (@tokens) {
        my $type;
        if ($token =~ /^\d+$/) {
            $type = 'NUMBER';
        }

        my $action = $actions->{$type} || $actions->{$token} || $actions->{_DEFAULT_};

        $action->($token, $type, $actions);
    }
    return pop(@stack);
}

ざっとこんな感じ。
my $action = $actions->{$type} || $actions->{$token} || $actions->{_DEFAULT_};
この辺りがLLぽい。一つめのハッシュが駄目なら、次のハッシュ。

class calclator {
public:
  int calc(std::vector tokens) {
    std::vector::iterator it;
    for(it=tokens.begin();it!=tokens.end();it++) {
      if(it->type() == NUMBER) {
        st.push(*it);
      } else if(it->type() == OPERATOR) {
        token op2 = st.top(); st.pop();
        token op1 = st.top(); st.pop();
        st.push((*it)(op1, op2));
      } else {
        std::cout << "error" << std::endl;
      }
    }
    token result = st.top();
    st.pop();
    return result.value();
  }
  
private:
  std::stack st;
};

一応C++でもそれっぽくできて動いたけど、なんかダサイ。
スタックに、文字列でも数字でも入れられるようにしようとしたのが失敗。逆ポーランド記法ではスタックに入るのは数字のみと気がついたのは、完成間近。それに気がついたとたんやる気がなくなった。なんでもほいほいpushできるLLすげー。普通の会社でC++で開発していて、やべー設計間違ってるって時、どうしてるんだろうな。

'+'のアクションで、std::plusが使えそうだったけど上手く行かなかった。今日はstd::stackが使えるようになったので良しとしよう。一日一歩。

Perl、入出力込みで数時間。(丸写しだけどね)
C++、3日がかりで、入力はソースに直書き。

むう、そろそろC++挫折しそうになってきた。

| | Comments (0) | TrackBack (0)

2007.10.30

C++でdirectory walking

Higher-Order-Perlから

ディレクトリを再帰的に降りていき、コールバック関数を呼び出す。
Boost::filesystemとboost::functionの合わせ技でOK。

#include <iostream>
#include <functional>
#include <algorithm>

#include <boost/function.hpp>
#include <boost/filesystem/operations.hpp>

using namespace boost;
using namespace boost::filesystem;

void dir_walk(const path& top, function<void (const path& )> f) {
 directory_iterator end;
 
for(directory_iterator it(top);it != end;++it) {
  path p = *it;
  f(p);  
//call back functionの呼び出し(表示)
  if(is_directory (p)) {  //dirctoryなら再帰呼び出し
   dir_walk(p, f);
  }
 }
}

void print_dir(const path& p) {
 std::cout << p.string() << std::endl;
}

void print_size(const path& p) {
 
if(!is_directory(p)) {
  std::cout << file_size(p) << 
"  ";
 } 
 std::cout << p.string() << std::endl;
}

int main(void)
{

 function<void (const path& path)> f;
 
// f = &print_dir;  
 f = &print_size;

 path dir(".");
 dir_walk(dir, f);

 return 0;
}

rambdaとかbindとかも挑戦したけど駄目だった。for文は、for_eachにしたいんだけどなぁ。出来る人はできるんだろう。

とりあえず、Perlでも、Pythonでも出来た。ていうか、一冊の本を3つの言語でやっていくのは効率が悪い気がした。

| | Comments (0) | TrackBack (0)

C++でcallback

Higher-Order Perlにでてきたハノイの塔をC++で書いてみた。

#include <iostream>
#include <string>
#include <functional>
#include <boost/bind.hpp>
#include <boost/function.hpp>

using namespace boost;

class peg {
public:
  
explicit peg(const std::string& name) : name(name){  }
  
const std::string name;
};


void print_move(int disk, const peg& start, const peg& end);
void hanoi(int n, const peg& start, const peg& end, const peg& extra, function<void (intconst peg&, const peg&)> f);

int main(void)
{
  
//call back function
  function<void (intconst peg&, const peg&)> f;
  f = &print_move;

  hanoi(3, peg("A"), peg("C"), peg("B"), f);

  return 0;
}

void print_move(int disk, const peg& start, const peg& end){
  std::cout << 
"Move disk #" << disk << " from " << start.name << " to " << end.name << std::endl;
}

void hanoi(int n, const peg& start, const peg& end, const peg& extra, function<void (intconst peg&, const peg&)> f)
{
  
if(n==1) {
    f(n , start, end);
  } 
else {
    hanoi(n-1, start, extra, end, f);
    f(n, start, end);
    hanoi(n-1, extra, end, start, f);
  }
}

動かしてみる。

YUKI.N>./kati.pl
g++ -c -I/usr/include/boost-1_33_1 -g -W -Wall -ansi -pedantic hanoi.cpp
g++ -o hanoi hanoi.o -I/usr/include/boost-1_33_1 -g -W -Wall -ansi -pedantic
YUKI.N>./hanoi.exe
Move disk #1 from A to C
Move disk #2 from A to B
Move disk #1 from C to B
Move disk #3 from A to C
Move disk #1 from B to A
Move disk #2 from B to C
Move disk #1 from A to C


C++でcallbackは出来るようになった。

| | Comments (0) | TrackBack (0)

2007.10.29

自分に教わる

gcc使っていて、multiple types in one declaration のエラーが出てはまる。
こんな時こそ、googleだと思って検索したトップ。

全然、成長していない。orz

| | Comments (2) | TrackBack (0)

2007.10.06

C言語の必要性

Cというのは、ハードウェアのエンジニアとコミュニケーション取るために必要なんですよ。彼らが分かるのはCだけなんだから。

| | Comments (0) | TrackBack (0)

2007.09.12

C言語ラブ

shinhさんの所からいろいろ回る。

http://blog.livedoor.jp/dankogai/archives/50910559.html

のコメントから
> shi3zさんはverilogやVHDLを出さずに「論理回路」なんて表現を使っている点からして知識が浅い。
> それで大言壮語してるんだから、反論されてもしかたない。

HDL厨キターー。もっと煽れ。2chにマシン語厨とHDL厨が煽り合うスレが立つまで煽れ。スレが立ったら僕はそのスレで毎日煽り、煽られするよ。

もとはここか。こことは違うらしい。
マシン語を知らない子ども達

> 最低でも、論理回路だけで桁上がりをサポートした加算機を作れる程度の理解はしておいて欲しいと思います。
これは、マシン語とかそういうレベルでなくても簡単に理解できるし、それで理解できれば十分じゃないかと。
sum = a ^ b ^ cin;
cout = (a & b) | (a & cin) | (b & cin);
これの&とか| を絵で描いただけ。たんなる論理演算です。

むしろフリップフロップを使って4bitでいいからカウンター作って欲しい。
教科書的に言うと順序回路の方。これを作れば、CPUの動作周波数の概念も分かるし、パイプラインが必要な理由も分かる。
CPUのオーバークロックで何が起こるかもよく分かると思う。それ以上は興味持ったらどうぞ、の世界。
教科書はいうまでもなくCPUの創りかたが最適。

> マシン語はプログラミングの深淵であり、母であり、基礎です。すぐに理解できなくても、それを理
> しているのとしていないのとでは大きな差があると思います。
マシン語をLispに置き換えても違和感がないのがいい。結局心のよりどころか。

僕はCとPerlがラブです。(いきなり告白!)
Cはアセンブラとの合わせ技で小さいマイコンなら俺様デバッガくらいまで作れますが、Perlはサブルーチンを作った事がありません。変数に$が必要なC言語の方言だと思っています。
ラブな理由は一つで、仕事をしていてこのままでやばいって時にCとPerlはいつも僕を助けてくれました。CとPerlが無ければ、「やばい」から「駄目だ」になっていたことは間違いありません。RTOSの仕事をしていて通信物のライブラリを2種類使うことがあり、どちらも「この処理をしているときは割り込みは禁止にしてください」という混ぜたら危険状態を上手く乗り越えたのはCのおかげです。1万行近いOrCADネットリストから必要な情報だけをきっちり抜き出して、並び替え、なんとか出図が間に合ったのはPerlのおかげです。これはやばいって時に、VHDLやVerilogは何もしてくれませんでした。

組み込みの仕事をしていたときは、CPUをブートさせ、ICEをつなぎ、割り込みを入れ、メモリのテストを行い、コンパイラ、リンカの設定を終え、環境を構築するまでが仕事だと思っていました。各初期化が終わり、いわゆるmainへ処理が飛んでデバッガが普通に動けば、そこから先はC言語の世界だからなんとでもなるという信頼感がありました。ShiroさんやPaul Grahamは、それがLispなんだろうな。ShiroさんのLispラブは、Lisp:よくある正解にいっぱい、Perlラブは、僕やはてながPerlを選ぶ理由とか、どっちの文章も好きで何回もよんでます。Shinhさんは、コードが短くなるからバイナリ好きなんだ。なんという偏愛。

結局shi3zさんは、マシン語ラブなわけですよ。困ったときに386マシン語の知識が助けてくれた。それだけだと思う。R3000とかSH4が出てくるから、もともと組み込みに近いところで活躍していたのではないかと。組み込みエンジニアならマシン語うんぬんは100%正しい。「××が分からないと駄目」というのは、リアルで言われたら引くかもしれないけど、Web上ではどんどん言って欲しい。ある人が、どんなに言語ラブか、その言語で熱くなれるかってのはいっぱい知りたい。煽り、煽られでいいじゃない。ハッカーと画家なんかLispラブ以外の何物でもないし、そのLispへのラブでSICP読み始めた人間がここにいる。Lisp面白いよ、Lisp。

神様なんて信じない僕らのために
> だから、
> 好きな事を好きなだけやれば良いんじゃない?
結局これかな。

最後にこんなの見つけた!
オシロスコープを知らない子供たち
マルツでふいた。

トラ技はともかく、もう一回くらいファインマン読みたいな。

| | Comments (0) | TrackBack (0)

2007.08.27

main関数のプロトタイプ宣言

http://www.kt.rim.or.jp/~kbk/zakkicho/07/zakkicho0708c.html
http://d.hatena.ne.jp/RiSK/20070825

気になるので調べてみました。C99の規格書はここからダウンロード。
http://www.open-std.org/jtc1/sc22/wg14/www/standards

ISO/IEC 9899:TC2から
大前提の話。

5.1.2.1 Freestanding environment
In a freestanding environment (in which C program execution may take place without any
benefit of an operating system), the name and type of the function called at program
startup are implementation-defined. Any library facilities available to a freestanding
program, other than the minimal set required by clause 4, are implementation-defined.

A hosted environment need not be provided, but shall conform to the following
specifications if present.


freestanding environment(例えば組み込みの世界)なら、最初に呼ばれる関数は実装依存。この場合、main()は普通の関数だからプロトタイプ宣言してもOK。次に、ここから先は、hosted environmentについてルールですよと。freestanding environmentは、Googleによると自立環境って訳が付いていた。昔はスタンドアローン環境って呼んでいたような気もするが、僕の記憶違いかな。

そして、main関数の説明の箇所。

5.1.2.2.1 Program startup
The function called at program startup is named main. The implementation declares no
prototype for this function. It shall be defined with a return type of int and with no
parameters:

実装環境(でいいのかな?)はmainのプロトタイプを宣言しませんとは書いてあるけど、明確に禁止はしていなそう。

ときどきの雑記帖 リターンズさんに教えていただいた、FAQでは、「 main は、 int 型の関数であり、プロトタイプ宣言しない約束になっています。」と書いてある。問題は宣言の主語だけど、上の規格書が根拠なら「The implementationはmainをプロトタイプ宣言しない」という意味かな。規格書見る限り、特に禁止はしていなそうなんだけど、複数の方から「mainはプロトタイプ宣言しちゃ駄目じゃないの?」って意見が出るって事は、実装上の問題 or 歴史的な何かがありそうな気がします。

ついでに、C++はルールが違うらしい。http://gusmachine.blog49.fc2.com/blog-entry-213.html


以下、僕的結論
・組み込み以外ではmain関数のプロトタイプ宣言は止めとこう

# C言語ならこうやって規格書見ようって気になるのに、Verilogは全然見ようともしないのはなんでだろう・・・

| | Comments (0) | TrackBack (0)

2007.08.24

C言語のプロトタイプ宣言

shinhさんの所から思いだしたこと。

いろいろと関数があって、最後にmain()があるのが嫌じゃないですか?あと、ヘッダーを公開用とそれ以外で2種類用意するのが面倒な時は、普通に.cにプロトタイプ宣言します。


誰も同意してくれない僕の書き方

#include < stdio.h >

int main(void);

int main(void)
{
printf("Hello, world\n");
return 0;
}

main関数もプロトタイプ宣言してあげてください。

| | Comments (0) | TrackBack (0)