プログラミング Gauche 練習問題を解く[7.4]

本日は可変引数を取る手続きについて。ここでの練習問題はさほど悩まず解決出来ました。自分の解答は以下の通り。

;; listを自分で定義してみましょう
(define (my-list a . b) (cons a b))
回答例は

(define (list . args) args)
あれ、ちょっと違う。そうか、0個以上の引数を受け取るって事で良いのか。なるほど。自分のやり方じゃ空のリストが作れないわ。いや0安直だった。テストケースが足りんかった。反省。

プログラミング Gauche 練習問題を解く[7.2]

引き続き読み進めております。「手続きを取る手続き」というなかなか楽しい章に突入しました。しかし、頭の中を整理しつつ例題、練習問題と向き合っていると中々進みませんね。まだまだ頭が固い。本章での重要項目は「手続きは手続きを引数とする事が出来る」、「手続きは手続きを返す事ができる」の2点です。前者はC言語であれば、引数に関数ポインタを取る関数といったイメージですが、後者はLisp系独特では無いかと思います。しかし、lambdaはPythonなどにもあったのでお馴染みの方にはお馴染みです。

色々と苦戦しつつ練習問題を解きました。とりあえず以下が自分の解答。



1、数字とそれ以外のモノが混ざっているリストを受け取り、数値にだけについて手続きを適用するfor-each-numbersを書け

(define (for-each-numbers proc ls)
; リストが空でないかどうか
(if (null? ls)
#f
;filter で数値のみのリストを返してもらう
(filter (lambda (a) (if (number? a) (proc a) #f)) ls)
)
)
数値だけに手続きを適用し、結果をリストにするmap-numbersを書け

(define (map-numbers proc ls)
; リストが空でないかどうか
(if (null? ls)
ls
;filter で数値のみのリストを返してもらう
(proc (filter (lambda (a) (if (number? a) a #f)) ls))
)
)
数値だけに手続きを適用し、その結果をリストにするmap-numbersを書け

(define (numbers-only walker)
; 手続きを返す
(lambda (proc ls)
(if (null? ls)
; リストが空であれば何もしない
#f
; 数値である要素に手続きを適用する
(walker proc (filter (lambda (a) (if (number? a) a #f)) ls))
)))
とりあえずそれっぽい結果が返ってきます。で、回答例を見てみますと。

;; 数値とそれ以外のものが混ざっているリストを受け取り、その中の数値だけについて
;; 手続きを適用する手続きfor-each-numbersを書いてみてください。

(define (for-each-numbers proc lis)
(for-each proc (filter number? lis)))

;; 数値だけに手続きを適用してその結果をリストにするmap-numbersも
;; 書いてみましょう。

(define (map-numbers proc lis)
(map proc (filter number? lis)))

;; for-eachやmap等の手続きを受け取り、それを数値だけに適用する手続きへと
;; 変換するnumbers-onlyを書いてみましょう。

(define (numbers-only walker)
(lambda (proc lis)
(walker proc (filter number? lis))))

となにやら最初の2問を難しく考えすぎたというか、意味をはき違えて解答してしまいました…。というより、lambdaを使う事を意識しすぎて変なコードになっている気があります。いかんです。思い込みは。さて、最後にもう一問あるんですが、じつはまだ取り込み中です。まだまだ頭の中がLisp脳になっておらず1問1問に手こずっていまして。この試行錯誤している過程が楽しい!プログラムは止められんw

心が砕けたデモンズソウルへのリベンジ

発売当時完全に心が粉砕したゲーム、デモンズソウル。最近ベスト版が出たようなので、何となく流れに乗って再開。最初に作った盗賊キャラを止めて、神殿騎士で再スタート。まあ相変わらず死ぬ死ぬ。でも、盾の使い方を覚えたらグッと難易度が下がりました。盗賊は難易度が高い選択だった事を今更思い知らされた…。

1年遅れで盾の有効性を知り、楽しさが分かってきました。なんとか全てのステージをエリア2まで攻略し、ようやくフロム伝統のムーンライトソード(ゲーム中の名前は「月明りの大剣」)を手に入れた所です。ちょっと感動。悪寒の走る巨大ナメクジの山を掻き分けたかいがありました。まあ、ステータス足らなくて使い物にならないんですが…。良いんです。この達成感があれば。なんとかエンディングまで行きたいと思います。

プログラミング Gauche 練習問題を解く[6.6]

本日も練習問題に取り組んでみましたが…解答に至りませんでした。ん0完全に頭が凝り固まっている、柔軟性に欠ける頭脳です。以下が回答例。この発想ができるまで止めんぞ!



■reverseを末尾再帰で書いてみましょう。



(define (reverse lis)
(define (reverse-rec lis r)
(if (null? lis)
r
(reverse-rec (cdr lis) (cons (car lis) r))))
(reverse-rec lis '()))

プログラミング Gauche 練習問題を解く[6.5]

とりあえず解答を晒してみます。

不慣れながらなんとか解いていきます。

今回は6章の5の練習問題です。



■リストの長さを計算するlengthを直接(foldを使わずに)定義してみる



(define (length lis)
(if (null? lis)
0
(+ 1 (length (cdr lis)))))


■リストの中から、条件を満たす要素だけを抜き出したリストを返すfilterを定義してみる

これの「条件を満たす」部分をどうすれば良いのかわからず手詰まり。条件式のリスト、例えば'(< a b)を引数にするのか、それとも比較を行う関数を引数にするのか。 ん0また明日。

消えるビット

今回も組み込みのちょっとしたお話。ま、ビットシフトを行う上での注意は組み込みに限ったことではないですが…。とりあえず以下のコードをご覧アレ。

#define FOO_VALUE (1 << 16)
なんの変哲もないマクロ。1が左に16ビットシフトされます。しかし、このコードには罠が!まあ、コンパイラ依存ではありますが、組み込みで使用するコンパイラはdefineやenumが32bitで確保されるとは限りません。コンパイラによっては値の格納できる最小のサイズが割り当てられます。この場合も1がbyteサイズのメモリに割り当てられ、それを16ビットシフト。結果、シフトした段階でビットは溢れている場合があります。こういったマクロを利用してレジスタやら、メモリマップドIOにアクセスすると、意図した制御ができないことがよくあります。こういったマクロを書く場合、例えばarmccでは以下の様にします。

#define FOO_VALUE (1ul << 16)
こうすることで意図しないビットあふれは発生しなくなります。原因不明の動作不良が案外こんなオチだったりします。要はコンパイラの仕様書はよく読めってことです。

Gauche本買いました

なんだかんだで興味が薄れなかったので買ってしまいました。ちょっと新しい事に触れるとワクワクしますね。今回も組み込みの仕事では使わない技術ですが、そんな事は気にしない!興味の赴くままよ!

フルスクリーンに対応したCocoa Emacsをインストールしてみました

ココを参考にインストール。Carbon Emacsをフルスクリーンで使用していたのでCocoa Emacsでフルスクリーンにならなくて残念に思っていた所、世の中には偉大な方が居ます。ありがとうございます。

本日施した変更

とりあえずCmdキーにMETAを割当。

(setq ns-command-modifier (quote meta))
(setq ns-alternate-modifier (quote super))


ウィンドウ最大化

(when (>= emacs-major-version 23)
(ns-toggle-fullscreen-internal))


フォントをどうにかしたかったけど、イマイチうまくいかなかったのでとりあえず…

(set-default-font "M+2VM+IPAG circle 12")


あとはエラーとなった箇所を(when (= emacs-major-version 22)みたいな感じで処理を振り分けました。ひとまず自分の環境での命となるanything.elyasnippet.elなんかは動作している模様。Flymakeとかも動きそうな予感です。動作確認は今後もおいおいやっていきます。これでEmacs23が満喫できそうです!

Macを使い始めた理由

Macに移行して一年。ここでMacを使い始めた理由を振り返ってみます。大して中身はありません。

  1. Windowsは会社で死ぬ程触れる。

    これは読んだ通り。基本的に会社の個人用マシンはWindowsしかない。

  2. Linuxもなんだかんだで会社で触れる機会が多い。

    開発環境がCygwin必須だったりLinuxサーバ上で軽作業をやる事が多々ある。
  3. なんとなくMacに興味がある。

    なぜデザイナに人気なのか。なぜWeb業界の人に人気なのか。なぜあんなにWinに挑戦的なのかw
と、以上の理由により自宅ではMacを触ろうということでMacへ移行。まあ8割興味本位です。で、幸い元々NTEmacsを使用していたので、開発環境はそのままCarbon Emacsへ移行。でそんなこんなで何も不便無く使い続けております。そして去年末に新型MacBookをUSキーボードで購入し早くもMacBookも2台目(買い替えが早すぎたと若干後悔…)。今後も長い付き合いになるでしょう。興味が続く限り。

ARMのスタートアップルーチンをハック その2

ARMCCでのスタートアップが8割くらい完成しました。情報が少なく、正確な手法かは保障できませんがメモしておきます。一応行うことの概要はここに書いてある処理を自前で実装することです。

まず、最初にやることは、ベクタ、スタックの設定後に最初に呼び出す関数を__main()以外のものにすることです。これは単純な話で、アセンブリコードで

LDR     r0, =__main
MOV lr, pc
BX r0
といった感じになっているところを

LDR     r0, =BootMain    ; 自前のスタートアップルーチン(今回はC言語で作成)
MOV lr, pc
BX r0
という風にするだけ。



次に、リンカの出力する情報をCのソースコードから参照する必要があります。必要なのはROM領域とRAM領域のマッピング情報です。まずリンカの使用方法の要点から話しますと、armlinkにもGCCで使われているようなリンカスクリプトのようなものがあります。スキャッターローディングと呼ばれるモノで、まあ詳しくはリンク先を読んでください。リファレンスでは分散ロード等と記載されており、いまいち用語の統一がされておらず、なかなか混乱させられました。上記のスクリプトを使用しないでも単純なマッピングはリンカオプションでも可能です。このあたりに書いてあります。そしてリンカオプションでもうひとつ重要なものが!今回の作業でもっともハマったところです。armlinkは勝手にRAM領域の圧縮を行います。まあ、容量の節約という観点からは素晴らしい機能なんですが、しかし勝手に、しかもデフォルトでやられると困ります。圧縮されるとRAM領域内のアドレスが詰まるため、上手くROMからRAMへ初期値つき変数の初期値がコピーできませんでした。なのでarmlinkに"--datacompressor off"を指定してRAM領域の圧縮を無効にします。ここまででひとまずリンカの準備は終了とします。



さて、実際のCで実装されたコードに入っていきます。まず、リンカの出力したそれぞれの領域を表すシンボルにアクセスするには以下のようにします。リファレンスではこのあたりこのあたりに載っています。



extern int Load$$領域名$$Base;  // 読み出し領域のXXの開始アドレス
extern int Image$$領域名$$Base; // 実行領域のXXの開始アドレス
extern int Image$$領域名$$Limit; // 実行領域のXXの終端アドレス
extern int Image$$領域名$$Length; // 実行領域のXXの終端アドレス


領域名には分散ロードファイルで命名した領域名を指定します。リファレンスによるとリンカは分散ロードを使用しない場合はデフォルトで以下の命名を行うとの事。





  • ER_RO、読み出し専用の実行領域の場合
  • ER_RW、読み出し-書き込み実行領域の場合
  • ER_ZI、ゼロで初期化された実行領域の場合




しかし、ZI領域に関してはER_ZIではなく、単にZIと出力される…。RVDS3.1なのに…。まあ、いいか。なお、分散ロードファイルを使用する場合は__user_initial_stackheap()という関数を再実装する必要があるとの事です。リファレンスによると「__user_initial_stackheap() の標準実装では、Image$$ZI$$Limit の値が使用されます。」との事ですので、ZI領域の名前を"Image$$ZI$$Limit"になるように合わせておけば、再実装は必要ないのかもしれません。今回は分散ロードは使用していませんので詳細は書けませんが、分散ロードする場合は忘れずに再実装を行ってください。で、実際のコードは以下のとおり。

//armlinkの出力したシンボルのインポート
extern int Load$$ER_RW$$Base; // 読み出し領域のRWの開始アドレス
extern int Image$$ER_RW$$Base; // 実行領域のRWの開始アドレス
extern int Image$$ER_RW$$Limit; // 実行領域のRWの終端アドレス
extern int Image$$ZI$$Base; // 実行領域のZIの開始アドレス
extern int Image$$ZI$$Limit; // 実行領域のZIの終端アドレス

/**
* @brief RW、ZI領域を初期化する
*/
void InitRAM(void)
{
unsigned char* imgRW = (unsigned char*)&Image$$ER_RW$$Base;
unsigned char* imgRWLim = (unsigned char*)&Image$$ER_RW$$Limit;
unsigned char* ldRW = (unsigned char*)&(Load$$ER_RW$$Base);

// 初期値つき変数の初期化
while(imgRW < imgRWLim)
{
*imgRW = *ldRW;
imgRW++;
ldRW++;
}

imgRW = (unsigned char*)&Image$$ZI$$Base;
// ZI領域の0クリア
while(imgRW < (unsigned char*)&Image$$ZI$$Limit)
{
*imgRW = 0;
imgRW++;
}
}

とりあえず素直に書きました。一応ICE上で初期値がコピーされているのも確認できたので問題ないと思います。さて、あとは__rt_lib_init( )をどう実装するかだが…。こいつの実装に関する情報はいまいち得られず、ヘッダーを除いてみても

extern __value_in_regs struct __argc_argv
__rt_lib_init(unsigned /*heapbase*/, unsigned /*heaptop*/);
と定義されているだけ。コメントにも「スタック、ヒープの初期化の後に呼んでね」といったことが書いてあるが…。__user_initial_stackheap()とあわせてもう少し調査が必要そうです。ちなみに私の環境ではこの状態でも一応ソフトは動きました。

ARMのスタートアップルーチンをハック

、組み込みの仕事をしておりまして。いま新しいプロジェクトが立ち上がり、動き始めたところなんです。が、早速一つ問題が発生。やれやれ。さて、まずは今回の開発環境を軽く説明。とはいえハードの仕様は機密事項なので公開できません。なので、コンパイル環境を記載します。



さて、プロジェクト開始当初はもちろんスタートアップルーチンから作成するわけです。例外ベクタハンドラ、各種スタック、ヒープの設定をアセンブリコードで記述した後、armccでは_main()呼び出すことでarmlib内のスタートアップルーチンが走り、ROM、RAMの配置、初期値付き変数の初期化、ZI領域のゼロクリア、その後ユーザーのmain()をコールするところまでやってくれるようになっています。しかし、このarmlib内のスタートアップルーチンというのが社内の規定にひっかかりまして。会社での規約として





ブラックボックスになっているモジュールは使用しない”





というものがあります。まあ、ライブラリだろうがなんだろうがソースコードの無いモジュールは使用するなという事でして。「ARMが提供しているものだから…使っちゃだめ?」とダメ元で聞いてみたら案の定だめでした。仕方ありません。



日はとりあえず_main()ではなく、自前のメイン関数をコールするように変更し、間違いなくその関数に飛んでくることを確認するところまで作りました。とりあえず明日はリンカの仕様書とにらめっこしてRAMクリア処理を実装していくとします。うまく動いたらまた書きます。

XMind

ちょっとマインドマップツールで面白そうなものを見つけたのでこれから試してみます。その名もXMind

http://www.xmind.net/

WindowsMacLinuxと各プラットフォームに揃っています。さてさて、使用感はどんなものか。

アジャイルとはなんぞや?

色々とマネージャ的な業務も増えつつあるお年頃。そういった業務は嫌いじゃないのでそっち方面の勉強も進めています。今回はこんな本を買いました。

アジャイルな見積りと計画づくり ~価値あるソフトウェアを育てる概念と技法~

現状はアジャイルという単語の意味が分かっていない状態ですが、しっかり読んでいきたいと思います。

tracを構築するの巻

仕事で今回tracを試験的に導入する事になりまして。Trac導入を待ち望んでいたワタクシとしては、ココは導入作業を買って出て、猛アピールするしかない!サーバーマシンはLinuxしかないと言われ、ひとまずtrac0.11.5.jaをインストール。Trac Lightningで楽しようという道は断たれましたが、しかし一つずつセットアップしていくのは個人的には楽しいので問題ないです。



Trac自体のセットアップやApacheSVNは滞り無く終了。その過程は他の数多くサイトで紹介されているので割愛。で、問題が発生したのはプラグインの導入の際です。プラグインは海外の物が多いのですが、インストールしてみると結構文字コード関連のエラーが…。更に最新のTracに追従していない場合もあり結構難航しました。そこでふと思いついた事がひとつ。

Trac Lightningのプラグインを利用すればいいのではないか

と。早速Trac Lightningのリポジトリからめぼしいものをひとしきり落として、セットアップ。これが意外に上手くいき、殆ど手を加える事無く動作しました。ただ、ExcelReportPluginに関してはパッチあて作業が必要です。しかし、patchコマンドでのパッチでは上手くパッチがあたってくれなかったのでpatchファイルを見ながら該当箇所を手動でマージ。手間があったのがその点くらいですかね。cronでバックアップなんかを仕込んで現状は安定動作中です。うんうん、これならコードを書かない方達の第一印象も悪くは無いだろう。

Left 4 Dead 2 発売!!

ご無沙汰しております。転職の兼ね合いで更新が滞ってしまいました…。

ぼちぼち落ち着いたので更新をしていきたいと思っております。



さて、いよいよ(ゾンビ)狩猟解禁ッ!体験版を繰り返しプレイし、待ちかねた Left 4 Dead 2 発売!!更新再開で最初のネタはゲームです。まずは前作と比較してみての雑感を。遊び始めたのが深夜だったのでシングルキャンペーンを難易度はノーマルでプレイしました。



■明るいので見通しがいい。バイオ5みたいな雰囲気。

■グロ表現に手加減なし。オプションで抑え目にできます。

■コンバットショットガンが強力。

■スナイパーライフル系のレティクルの収縮が早くなった気がする。

■マグナムピストルにロマンを感じるw

■近接武器にHalf-lifeでおなじみの「バールのようなもの」がッ!

■特殊感染者の出現インターバルが短い…気がする。

■フィナーレが感染者の波を凌ぐだけではなくなったのがアツイ。

■エリス喋りすぎw



読むに値しない雑感だらけです。とりあえずゴア表現ですが、海外版そのままのようです。パッケージの手だけはNGだったようで5本全ての指が揃っているものに差し替えられています。これは前作と一緒ですね。クレッシェンドイベント時にナタや刀を使っていると凄まじい光景が目に映ります。



次に武器ですが、大幅に種類が増えてそれぞれの扱いやすさ等にも調整が入った模様。個人的にはショットガンとスナイパーライフルの使い勝手が向上したように感じました。それでも私はアサルトライフルを使うのが安定しますがw



新武器のコンバットショットガンの破壊力は爽快です。2,3匹まとめて葬る感覚、病み付きです。とりあえず出てきたら使ってます。ちょっとショットガンに目覚めたかもw



グレネードランチャーは使いどころが難しいですね。屋内移動中は自分の腕のせいもありますが誤爆が多くなるので要注意です。強力なのでうまいこと活用する方法を研究したいところです。実績もあるし積極的に使っていこうと思います。



スナイパーライフルは「移動→停止」時のレティクルの収縮が前作よりも高速になった気がします。ん〜気のせいですかねぇ。こちらも前作ではあまり使っていなかったので、もう少し使い込んでみます。



完全新規の近接武器ですが、これがまたアツイ!フライパンとギターの効果音は一聴の価値ありw

ピストルとトレードオフなので4人で相談して所持するほうがいいとは思いますが、感染者の群れを裁く際には一人は持っておいたほうがよさそうな印象です。なにせ弾薬を使用することなく1撃でゾンビを葬れますからね。「突進中のチャージャーを近接武器で倒す」っていう実績もありますしガンガン使っていきたいと思います。Valveファンならばバール一択で!



今回武器だけでなく特殊感染者も追加された訳ですが、そのせいか特殊感染者の出現スパンが短い気がします。ボヤボヤしていると新旧織り交ぜてフルボッコにされることもありました。特にハンター2体同時出現は予想外でしたね。チームメイトの一人がハンターに飛び掛られ、救助に向かおうとしたそのときに自分もハンターの餌食に…。正直一瞬何が起きたのかと。後はスモーカーに締め上げられている最中にスピッターの酸を食らうと目も当てられない状況になりました…。酸痛い…。



そんな愉快な感染者と戯れ迎えるフィナーレですが、今回は基本的にキャンプができないようです。必ず移動を強要されます。たとえば脱出地点まで走れとか、ガソリンを探してきて車を発車しろといったちょっとしたミッションが課せられます。これがまたアツイ!難い!ショッピングモールのフィナーレは10回くらいリトライしましたw そのキャンペーンはトータル1時間40分かかるという不甲斐ない腕です。とりあえず2つしかまだ遊べていませんが、他のフィナーレも同様になっていると思います。前作の群れを凌ぐ感じも好きですが、今回のフィナーレもこれはこれで楽しいです。



とまあ、プレイ初日なのであまり深いところは見えていません。これから精進します。

読書の夏

トニー・ブザンの「ザ・マインドマップ」購入しました。

マインドマップの本質をしっかり学ぶために。



ついでにHCPチャートの本も購入。

こちらは単に興味本位で。



そしてAndroidの本も購入。

これで色々遊んでみる予定…

だが、夏期の休暇が取れるか否かで

触れないかもw

スマートフォンに替えたので、
i-mode.netっちゅうサービスを経由して
i-modeメールを確認しているんですが…

凄まじく使い辛い!
実用に耐えません。
しかもPCからだと
IEしか対応していないらしく、
firefoxでは何も表示されず…
i-modeメールの転送もできないし、
使い手の事を全く考えていない
やっつけ仕事ですな。

この先バージョンアップがあるんでしょうか?

emacs新生

つい最近になって愛用のemacs
auto-complete.elとanything.elを導入しました。

…ゾクっときましたね、これは。
別物に生まれ変わったと行っても過言でないくらいに
emacsが変貌しました。

いかんです。
何事も現状に満足していると
こういった素晴らしい発見を見逃してしまうんですね…。
もっとアンテナを張らねばッ!

SICPを読み解く1

少しずつ地道に進めていっています。

練習問題を必ず着手するようにし、

解答は有志の方々がまとめて下さっている

こちらを参考にしています。



http://oss.timedia.co.jp/show/SICP/Answer%20Book



慣れていない言語とはいえ

とりあえず「我ながらセンス無いなぁ」

とかボヤくばかりです。



最初の練習問題で



(define (a-plus-abs-b a b)
((if (> b 0) + -) a b))




というコードを見たときに

自分の思考が一瞬固まりました…。

よく見れば理解はできるんですが

今までの自分の経験では

思考の死角を突かれるコードでした。

よし、次からは自分の要点メモと

練習問題の自己解答も載せるようにします。

成長のためにも色々と恥をかくしか無い。