トップ 最新 追記

Route 477



2007-06-15

[haskell] WindowsでHSDLを使う方法

参考:

セットアップ

  1. GHC 6.6.xをアンインストールする (ちょw)
  2. GHC 6.4をインストール
  3. HSDLを配布ページからダウンロードして解凍
  4. SDL-devel-1.2.11-VC6.zipをSDLのページからダウンロードして解凍
  5. HSDL.cabalを以下のような感じで編集
include-dirs:
	C:/research/HSDL/SDL-1.2.11/include
ld-options:
	-LC:/research/HSDL/SDL-1.2.11/lib

あとは

C:\research\HSDL\HSDL-0.2.0> runhaskell Setup.hs configure
C:\research\HSDL\HSDL-0.2.0> runhaskell Setup.hs build
C:\research\HSDL\HSDL-0.2.0> runhaskell Setup.hs install

でOK。

テスト

haSDLis(テトリス)をダウンロードして

C:\research\HSDL\haSDLis>ghci main.hs
   ___         ___ _
  / _ \ /\  /\/ __(_)
 / /_\// /_/ / /  | |      GHC Interactive, version 6.4, for Haskell 98.
/ /_\\/ __  / /___| |      http://www.haskell.org/ghc/
\____/\/ /_/\____/|_|      Type :? for help.

Loading package base-1.0 ... linking ... done.
Compiling Main             ( main.hs, interpreted )
Ok, modules loaded: Main.
*Main> main

とするとテトリスが遊べるはずです。

TTSYさんの方法だと、うちではキー入力を受け付けてくれなかったので、 諦めてGHC 6.4を入れてしまいました。


2007-06-13

[Ruby/SDL] 「初心者向け」について

ということで、「るびま」で

Ruby/SDLで始めるゲームプログラミング

を見たときには「これだ!」と思ったんですけど、「ウインドウを開く前に変数のなんたるかを知らなければならない」というのは初心者的にはどうなんでしょう(純粋に疑問)。

[http://d.hatena.ne.jp/kmaebashi/20070611より引用]

実を言うとあの記事はもうちょっと初心者向けに書きたかったんですけど、 僕の実力不足で多少Rubyの知識を前提にしています。すいません。*1

というのもありつつ。

「Ruby/SDLスターターキット」とMyGameは合体したほうがいいんじゃないかと思うわけですよ。

[http://dgames.jp/dan/?date=20070613#p02より引用]

僕もそうした方が良いような気がしてきましたですよ。

  • 初心者 → MyGame + スターターキット
  • 中級者 → Miyako
  • 上級者 → もちろん、フレームワークから自作 :-)

という感じ?

*1 ていうか、本当に初心者向けに書いてたら多分8回連載とかになってたと思われ(笑)

[prog] 初心者に特化した言語

あれなんだよな、HSPは初心者に特化した言語だと思うんですよね。 プログラミングに関する前提知識がない人に最適化されてるというか。 僕が触ってた頃(7年くらい前?)はたしか戻り値の概念すら無かったし。

もちろんそれは割り切りであって悪いことではないですが。

Rubyの文法でどこまでその域に迫れるか?ってのも面白いかもな。

[softs] タブブラウザfubで蒸発機能が検討されている模様

期待age。

fubはタブをメタタブでグループ化できるブラウザで、さらに終了時に開いてるタブを保存できるので、 使い方によっては開きっぱなしのタブがどんどん増えていく。 だから、これを閉じるなりブクマするなりお気に入りに入れるなりして自分で閉じないといけないんだけど、 自動でなんとかしてくれると嬉しいよね。という話(だと思うけど俺の勘違いかも知れない)。

最後にアクティブにしてから1時間経ったらタブだけ残して中身消しちゃう。

これ欲しい。メモリ消費が少なくなって良さそう。ついでにGMailだけは消さずに置いとくとかできると嬉しい。


2007-06-12

[Ruby/SDL][idea] 位置決め

ゲーム製作において、キャラクタや文字の位置を決めるのが結構めんどい。「ちょっと座標をいじって再実行」とかさ。

GUIビルダみたいな感じで位置を検討できると便利そうだ。

[Ruby/SDL][idea] デバッガ

スライドに書き忘れたんだけどHSPは実行時に変数の内容とか別ウィンドウに表示できて便利だった覚えがあります。

最近local_variablesというメソッドを知ったので、Rubyでも(黒魔術を駆使すれば)実装できそうな予感。

[ruby] あるURLからフィードを見つけてくれるライブラリ、FeedDiscover

例のOPMLを作るときにいちいちフィードのURLを探すのが面倒だったので、rubyforgeからそれっぽい (PerlのFeed::Findみたいな)ライブラリを探してみました。

FeedDiscoverを使うと、あるURLのHTMLを解析してフィードのURLを見つけてくれます。

ドキュメント
http://feed-discover.rubyforge.org/
プロジェクトページ
http://rubyforge.org/projects/feed-discover/

インストールは gem install feed_discover で。

長所

使い方が超簡単なところ。

require 'rubygems'
require 'feed_discover'

fd = FeedDiscover.new('http://bbc.co.uk/')

fd.feeds   #=> ["http://newsrss.bbc.co.uk/rss/newsonline_world_edition/front_page/rss.xml"]
fd.feed    #=> feeds[0]といっしょ
fd.feeds?  #=> !feeds.empty?といっしょ

短所

Hpricotベースになるといいなぁ。

[ruby][memo] eachで回してるときの次の要素がほしい

ary.each do |item|
  ...
end

みたいな定番のループで、itemの次の要素や前の要素が欲しくなることってないかい?

こういう時はだいたい下のようにインデックスを使うようにするんだけど、もっと簡単な方法はないかな。

(0..ary.size).each do |i|
  prev = item[i-1]
  succ = item[i+1]
end

隣り合う要素を2つずつ…ってことは隙あらばinjectか?

ary.inject([]){|sum, item|
  ...
}

いやいや、injectは「ある要素」と「そこまでの結果」を扱うメソッドだからあんまり向いてないよな。

prevやsuccが暗黙的に束縛されるようなメソッドを(Rubyレベルで)実装できないだろうか。

ary.each_with_prevsucc do |item|
  p [prev, item, succ]
end

(追記:いろいろな解決案が寄せられています。

ありがとうございます。あとでまとめるかも。)

[ruby] SimpleOPML

RubyでOPMLファイルを生成するクラスを作ってみました。

OPMLはもともと文書のアウトラインを記述するフォーマットとして作られた そうなのですが、今ではなぜかRSSのリストを記述するのに使われているようです。

OPMLファイルの仕様に関しては以下のサイトが参考になります。

require 'cgi'
require 'time'
require 'kconv'

require 'rubygems'
require 'hpricot'
require 'open-uri'

class SimpleOPML

  Site = Struct.new(:url, :rss, :title)

  def initialize(title)
    @title = title
    @sites = []
  end

  def add(url, rss, title=nil)
    title = get_title(url) if title.nil?
    @sites << Site.new(url, rss, title)
  end

  def get_title(url)
    doc = Hpricot(open(url).read)
    if (title = doc % :title)
      title.inner_html
    else
      ""
    end
  end

  def to_s
    <<EOD
<?xml version="1.0" encoding="utf-8"?>
<opml version="1.0">
<head>
<title>#{CGI.escapeHTML @title}</title>
<dateCreated>#{Time.now.rfc822}</dateCreated>
<ownerName />
</head>
<body>
<outline text="Subscriptions">
#{@sites.map{|s| site_to_outline(s)}}
</outline>
</body>
</opml>
EOD
  end

  def site_to_outline(site)
    %!<outline title="#{CGI.escapeHTML site.title.toutf8}" htmlUrl="#{CGI.escapeHTML site.url}" text="#{CGI.escapeHTML site.title.toutf8}" type="rss" xmlUrl="#{CGI.escapeHTML site.rss}" />\n!
  end

end

#---- example

opml = SimpleOPML.new("RubyKaigi2007 Speakers & Staffs")
File.read("sites.txt").each do |line|
  url, feed = line.split /\t/ 
  opml.add(url, feed)
end

puts opml
本日のツッコミ(全3件) [ツッコミを入れる]

ohai [そういうときは zip かな]

nov [そこで Enumerable::Enumerator#{each|enum}_cons ですよ! >> (0..9)..]

takkanm [なんとなく誰も言ってないのは、理由があるのかわかりませんが、each_with_indexで十分じゃないかと思ってお..]


2007-06-11

[ruby][event] RubyKaigi2007発表者のブログ一覧

日本 Ruby 会議 2007の発表者の方々のブログをまとめてみました。

  • (6/13追記:OPMLを作りました。livedoor ReaderなどのRSSリーダに食わすとまとめて登録できます。)
  • (6/15追記:version 2になりました。)

一日目

Lightning Talks

  • LT1. 数値データ管理・解析・可視化アプリケーション "Gfdnavi" (西澤 誠也*2
  • LT2. Software is Made of Design and Communication (平鍋 健児
  • LT3. 「Ruby+Miyako」でおもろいプレゼン (サイロス誠
  • LT4. Rubyでファミコンプログラミング (takkaw
  • LT5. Ruby on Railsでデータマイニング (山形 頼之 id:yoriyuki)
  • LT6. Rubyのパーサーを拡張して "end" の対応付けをチェックする (山野 ゆき菜*3
  • LT7. マルチコアプロセッサでのRubyプログラムの高速実行方式 (米澤 直記*4
  • LT8. 「地域資源」Rubyと島根県の産業振興の取り組み (野田 哲夫*5
  • LT9. 5分で作るCometチャット (瀧内 元気
  • LT10. データで予想する Ruby のリリース (田中 哲 akr)*6
  • LT11. 第2日本Rubyの会について (高橋 征義

二日目

  • もっと仕事で使うRuby (後藤 謙太郎 gotoken)
  • JRuby on Rails でエンタープライズ Ruby (高井 直人
  • OpenWFEru, a Ruby workflow engine (John Mettraux
  • AP4R : Ruby のための非同期メッセージングライブラリ (篠原 俊一 id:ita-wasa / 加藤 究 id:kiwamu)
  • Inside Ruby/Tk (永井 秀利) *7
  • Hello Ruby-GNOME2 World (武藤 昌夫 むとう まさお)
  • VisualuRuby計画(仮称)によるWindowsでのGUI開発 (nyasu
  • RubyCocoa - RubyによるMac OS Xソフトウェア開発 (藤本 尚邦 hisa)
  • モテる Ruby!Ruby で画像編集のあの手この手 (舘野 祐一 id:secondlife)
  • Ruby/SDLとその周辺 (大林 一平 ohai / 原 悠 yhara)
  • rcairo (須藤 功平*8
  • 私はいかにRubyでメディア・アート作品をつくり、しかも一円も損をしなかったか (えと こういちろう eto)
  • Island Ruby, or How To Survive Invasions, Immigrants, and Cultural Attacks(Dave Thomas

RejectKaigi

実行委員会

当日スタッフ、ロガー、司会

  • たけうち(東京外国語大学)
  • 設樂洋爾(dara)
  • 島田浩二(snoozer.05)
  • 磯辺和彦(株式会社ビジネス・アーキテクツ)
  • 柳沢 恵
  • 木下史彦((株)永和システムマネジメント)
  • だん(日本Rubyの会)
  • kitaj(tDiary)
  • 斎藤ただし(筑波大学)
  • zunda(るびま編集)
  • よう(るびま編集)
  • すずき みほ (株式会社ツインスパーク)

コメントでいくつかブログを教えていただきました。ありがとうございます。

*1 日記なし?

*2 日記なし?

*3 ただただしさんは代理でPCを設置しただけで、中の人なわけではない模様

*4 日記なし?

*5 日記なし?

*6 IEでは見えないので注意

*7 ページ不明

*8 日記なし?

本日のツッコミ(全13件) [ツッコミを入れる]

Before...

yhara [かくたにさん: アップデートしました。ありがとうございます。]

dan5 [司会がない!]

yhara [鈴木さんファンの方: 追加しておきました(笑)。ありがとうございます。]


2007-06-10

[ruby] どうもyharaです

趣味は睡眠です。

よろしくお願いします。

[ruby][event] RubyKaigi2007\(^o^)/オワタ

良いイベントでした。

本日のツッコミ(全2件) [ツッコミを入れる]

なかもと [お疲れさまです。RubyKaigiには行けなかったけれど、速報ログを見て思ったこと。 →スタータキットで、ゲームだけ..]

yhara [提案ありがとう。考えてみます。 Gem Box本にそういうネタがあったと思うので、できるはずだよなぁ。]


2007-06-08

[junk] @カプセルホテル

みょーん

[ruby] caller_binding

Kernel#local_variables というメソッドがあるだなんて知らなかったよ!(それっぽいのがあるとしたら Binding のメソッドかなあと踏んでそっち探してたよ

[http://yowaken.dip.jp/tdiary/20070608.html#p01より引用]

俺も俺も!

あと呼び出し元のbindingを取るのは callcc + set_trace_func でできます(Rails方面ではBinding.of_callerという名前で提供されているらしい)。

[web] Re: 「追加して確認」ボタンがなくなった

個人的には「追加して閉じる」ボタンが欲しいです。[あとで読む]でブクマしたあと、手動でウィンドウを閉じるのがめんどい。

[web] Google Analyticsの登録フォームがアレな件

国名を全部日本語に翻訳してくれてるのは有難いんだが、アルファベット順ソートのままじゃ探しにくくて仕方ないよ^^; (ジャマイカ→日本→ヨルダンって何だ。)

てーか、日本語で表示するならデフォルトで日本を選択してくれといたら良いのに。

[junk] 登録フィードが500を超えた件について

そんなに登録して全部読めるの?と聞かれそうだが

未読が0になるとむしろ不安になります。


2007-06-05

[scheme] FizzBuzz一般化 (2)

動くまでに28分、リファクタリングに10分くらい。

「=」が数値の比較であることを忘れててだいぶはまった。(どの関数のエラーメッセージなのかも出してくれると嬉しいなぁ。)

[D:\proj]d:\prog\Gauche\bin\gosh ./fizzbuzzx.scm 1 100 3 Fizz 5 Buzz
*** ERROR: real number required: #f
Stack Trace:
_______________________________________

回答はこんな感じで。

(use util.list) ;slices
(use srfi-1)    ;iota

(define (fizzbuzz from to mapping) ;mapping -> '((3 . "Fizz") (5 . "Buzz") ..)
  (define (integer->fizzbuzz i)
    (let1 mapped (map (lambda (pair) 
                        (let ((n   (car pair))
                              (str (cdr pair)))
                          (if (= (modulo i n) 0) str "")))
                      mapping)
          (if (every (cut string=? <> "") mapped)
            (number->string i)
            (apply string-append mapped))))

  (map integer->fizzbuzz (iota to from)))

(define (main args)
  (cond 
    ((< (length args) 2) 
     (print "usage: fizzbuzz.scm 1 100 3 Fizz 5 Buzz ..."))
    (else
      (let ((from    (string->number (cadr args)))
            (to      (string->number (caddr args)))
            (mapping (map (lambda (ls)
                            (cons (string->number (car ls)) (cadr ls)))
                          (slices (cdddr args) 2))))
        (for-each print (fizzbuzz from to mapping))))))

[ruby] Re:もんだい

immutableなはずのFixnumを無理やり変更せよ (or 変更されたように見せかけろ)、という問題。

変数名をiに限定すれば1行で書けますね(笑)。ってのでは駄目だろうな。うーん、どうやるんだろ。Bindingをどうにかするのかな。

pppを思い出したんだけど、pppはシンボルが引数なんで参考にならず。


2007-06-04

[erlang] もしも「ふつうのErlang」が出版されたら

第1章は「エラーメッセージ」で。

[event][erlang] Erlang勉強会#1

というわけで(どういうわけだ) Erlang勉強会#1 に行ってきた。「参加者はfizzbuzzを書いてくること」という 告知にもかかわらず12人も集まってすげー!と思ったんだけど、 やっぱり半分くらいの人がまだ書けてなかった(笑)。僕ですか?電車の中で頑張って書きましたよ。ええ。

-module(fizzbuzz).
-compile(export_all).  %これは便利

fizzbuzz(N) when N rem 3  == 0 -> "fizz";
fizzbuzz(N) when N rem 5  == 0 -> "buzz";
fizzbuzz(N) when N rem 15 == 0 -> "fizzbuzz";
fizzbuzz(N) -> integer_to_list(N).

run() -> lists:map(fun fizzbuzz/1 , lists:seq(1, 100)).
%run2() -> [fizzbuzz(X) || X <- lists:seq(1,100)].

数値を"fizz"とか"buzz"とかに変換する関数を書いて、それを1から100までのリストにmapする方向で実装してみた。

  • 定義済みの関数を関数に渡すには fun fizzbuzz/1 のように書く(1は引数の個数)。
    • 関数は関数名とarityで区別されるらしい。

最初はlists:seqを知らなくて、iotaという関数を実装してた。

iota(Start, Start) -> [Start];
iota(N,     Start) -> iota(N-1, Start) ++ [N].   

逆順に作ってreverseするほうが速そうだな。

本編では、練習としてold roman (ローマ数字の簡略版、4をIVじゃなくてIIIIのように書く) を整数に変換する関数を書いた。

-module(roman).
-compile(export_all).

chr2int($M) -> 1000;  % 1文字を整数に変換する。「$M」はC言語の「'M'」、Rubyの「?M」。
chr2int($D) -> 500;
chr2int($C) -> 100;
chr2int($L) -> 50;
chr2int($X) -> 10;
chr2int($V) -> 5;
chr2int($I) -> 1;
chr2int(X)  -> erlang:error("invalid char in old roman: " ++ [X]). % ++はリストの連結(format使う方がいいかも)。

old2int(Str) -> 
  Mapped = lists:map(fun chr2int/1, Str),        % まず整数のリストに変換して、
  Soted  = lists:reverse(lists:sort(Mapped)),    % ソートしたものを作る
  if 
    Soted == Mapped -> lists:sum(Mapped);        
    true            -> erlang:error("invalid order in old roman: " ++ Str)
  end.

old romanの仕様から考えると、"VII"はいいけど"IVI"とかはエラーにしたい。ここではまず整数のリストを作って、 それが降順かどうかでエラーチェックするようにしてみた。ソートして同じかを比較するというのはなんきさんの案。 本当は「(apply < ls)」みたいなことがしたかったんだけど(scheme脳)、多引数の「<」みたいな便利なもんはあるのかな。

  • erlang:errorでエラーを通知できる。(ここはthrowで例外を投げるほうがいいかも?)
    • エラーメッセージは親切にしておかないと、処理系のエラーなのか自前のエラーなのか見分けがつきません(笑) 気をつけよう。
  • ifの見た目が変態すぎるw
    • ifっていうかcondだよね
    • 条件に副作用を持つものは書けない(?)らしい。

その他:

  • =:= っていう演算子がある
    • ==は、整数と少数を区別しないが、=:= は区別する(1.0 =:= 1は偽)。
  • 文字列がなく、数値のリストを作ると文字列と見なされる
1> [104, 111, 103, 101].
"hoge"
  • 副作用についてはわりと緩めらしい。HaskellじゃなくてSchemeやOCamlのような。
test() ->
  io:put_chars("hoge"),
  io:put_chars("moge"). % 普通にOK
  • Emacsのerlang-modeが凄い
    • 「;」を打つと、自動的に次の行に関数名を補完してくれたりとか
    • 「;」と「.」と「,」を使い分ける→実はエディタ指向言語なのかも
    • 例えばC#の仕様はVisual Studioでの補完がやりやすいように考えられてる(という噂)
  • HIGHER ORDER PERLという本が熱いらしい
    • 目次を見てるだけですでにヤバい(笑)

1558607013

[erlang] ESDLが以下略(2)

test\ 以下で

erlc -W -bbeam -I..\.. -I..\include -pa ..\ebin testsprite.erl

とやると、testsprite.beamにコンパイルできる。ってとこまでは分かった。

だがしかし、これを実行しようとすると…

C:\research\Erlang\esdl-0.96.0626\test>erl -pa ..\ebin testsprite.beam
Eshell V5.5.4  (abort with ^G)
1> testsprite:go().
Driver Failed {error,driver_incorrect_version}

=ERROR REPORT==== 2-Jun-2007::20:23:09 ===
Error in process <0.29.0> with exit value: {einval,[{erlang,open_port,[{spawn,"s
dl_driver"},[binary]]},{sdl,init,1},{testsprite,go,1},{erl_eval,do_apply,5},{she
ll,exprs,6},{shell,eval_loop,3}]}

** exited: {einval,[{erlang,open_port,[{spawn,"sdl_driver"},[binary]]},
                    {sdl,init,1},
                    {testsprite,go,1},
                    {erl_eval,do_apply,5},
                    {shell,exprs,6},
                    {shell,eval_loop,3}]} **

driver_incorrect_versionって何だよー。

って、driver_incorrect_versionで検索したら自分の日記がでてきた。進歩してねえじゃん。

もうちょっと調べてみる。

[ruby][prog] 英語なまりのRuby

Enumerableを操作するのに

@stooges.select {|s| s.name == 'Mo'}

と書く代わりに

@stooges.that.have.name == 'Mo'

と書くためのライブラリ、ho_enumerable.rbについて。

[http://www.rubyist.net/~matz/20070530.html#p04より引用]

一瞬「かっこえー!」と言いそうになったんだけど、プログラミング言語として考えるとこれはセンスないよな。 なんつーか、thatとかhaveが何を返すのかが全然わからんところが嫌だ。せめて

@stooges.that_have.name == 'Mo'

と分けてほしい。

どちらにせよ、自然言語に近くてもプログラミング言語的に不自然だったら駄目だと思う。*1

余談

Lispだと「.」が要らないので、より英語に近くできるらしい。

(例) Loopマクロより:

(loop for x being the hash-keys in ht collect x)

*1 チャレンジとしては面白いけど

[ruby] FizzBuzz一般化

14分。

仕様を読み間違えた(optparse使おうとした)のとto_i忘れでちょっとはまった("1".."100" が普通に通るんだよな…)。

require 'enumerator'

class FizzBuzz

  def initialize(argv)
    raise ArgumentError if argv.size < 2

    @start = argv[0].to_i
    @end   = argv[1].to_i

    @str_mod = []
    if argv.size > 2
      argv[2..-1].each_slice(2) do |n, str|
        @str_mod << [n.to_i, str]
      end
    end
  end

  def run
    puts (@start..@end).map{|i|
      s = ""
      @str_mod.each do |n, str|
        if i % n == 0
          s << str
        end
      end
      s += i.to_s if s.empty?
      s
    }
  end

end

FizzBuzz.new(ARGV).run

2007-05-30

[idea] 動作コンビネータ

関数型らしいゲームプログラミングってないかなぁという話について。

パーサコンビネータみたいに「動作」をつなげて記述するというアプローチはどうだろうか。

move_square = move_right 10 <+> move_down 10 <+> move_left 10 <+> move_top

[prog] コーディングって呼ばないで

コーディングってプログラミングのかっこいい言い方だと思ってました。

[prog] おまいらは「scanf=セキュリティホール」で思考停止していないか

scanf("%s", &buf); が危険なのは分かるんですけど、scanf("%d", &a); って危険なんですかね?

(追記:aをchar型で宣言してたりすると危険ですね。)


2007-05-29

[softs] Firefoxの許せないところ

  • about="_blank" が新規ウィンドウで開く。お前はそれでもタブブラウザか。
  • C-hで履歴が開く。いやWindows版は仕方ないとしても、せめてLinux版はBackspaceとして振舞ってくれよ。

いやまあTab Mix Plusを入れればいいんですけど、 「新規ウィンドウを開かない」くらいデフォルトでできてほしい。

[ruby] それany?で

link_exist = (doc/:a).any?{|a| a[:href] == 'http://example.com:3000'}

最初「それfindで」というタイトルにしてて、書いてる途中でany?のことを思い出したのは秘密。

あとEnumerable any?で検索するるりまが一番上に 来ますね。リプレースはすでに始まっているのだ。

[Ruby/SDL] 等幅フォントじゃないと点数表示がぐらぐらして鬱陶しいんじゃね?という指摘

http://blawat2015.no-ip.com/~mieki256/diary/200705274.html#200705274S1

その発想はなかった!確かにそうだなぁ。

「"」の分割問題については、ご指摘の通り「ひとつ多かったら " が分かれているものと見なす」という方針にしました。 というか、頑張ってアルゴリズムを考えるよりも、簡単に確認を行えるようにしておいて人間に判断してもらうというアプローチの方が良さそうです。

1文字ずつ画像を作るのは面倒だから駄目です(笑)。いや、そういう仕様にしても 人によっては使ってくれると思うんだけど、それはその人の時間を無駄に消費させている気がしてやだ。

とか書いてる暇があったらリリースしないと…。[たぶん明日やる]

[ruby] いまさらFizzBuzz

puts (1..99).map{|i|
  fizzbuzz = (i%3==0 ? "Fizz" : "") + (i%5==0 ? "Buzz" : "")
  fizzbuzz.empty? ? i.to_s : fizzbuzz
}

面接で「学生時代に力を入れたことは何ですか」だの聞かれるより、FizzBuzzのコードを書かされる方が100万倍いい。

[prog] 関数型プログラマはプログラムを木だと思ってるらしい

gauche.nightで出た話題だけど、関数型プログラマはプログラムを木だと思ってるらしい。

(car (string-split
       (string-reverse (string-upcase str))
       "\n"))

うん、これは木だ。

head $ lines $ reverse $ upcase str

Haskellだと $ があるから見た目はネストしてないけど、実際には関数に関数の返り値を渡している。

そう、関数型プログラマは関数呼び出しの中に関数を書くことに抵抗がない。でもC言語とかだとさ、 関数呼び出しの中に関数って書かないじゃん、普通。すごく短いやつを除けば、だいたい一旦変数に代入するでしょ。

そのへんの違いが関数型言語を学ぶときの抵抗になってるのかなぁと思った。

そういう目で見れば、Rubyのメソッドチェーンは 「木構造を使わずに関数的な処理を書くための発明」っていう風に見えてきませんか?

str.upcase.reverse.to_a.first

[befunge] befunge-wiki

これはやべぇwwwwwwwwwwwwwww思わずbefungeカテゴリを新設した。

ていうかBefungeで書かれた実用的なアプリケーションという意味では世界初だったりしないすかね?

[net] 自宅サーバの台数

えーと、その母集合だと明らかに平均は1未満かと(笑)。

ていうか、自宅サーバを2台以上持つっていう発想が無かったよ。 KMCでも何人かサーバ立ててるけど、みんな1台だと思う。

ちなみにうちのサーバはMac miniですけどまだ何も動かしてないし外から見えません(それを人はサーバと呼ばない)。

[net] LDR

登録フィード数: 497件

あと3つで500。っていうかさっき4件ほど追加したからもう500超えたか。

僕はPCかMP3プレーヤーでしか音楽を聴かないので、聴きたかったCDがCCCDだと非常にがっかりする。 CCCDで発売するっていうのは、僕にとっては発売しないのと同じだ。

…っていうのと同じで、SubscribeしようとしたブログがRSSを出力してないとがっかりするようになりつつある(はいはいそれPlaそれPla)

[scheme] 熟練したScheme使いは再帰を書かない

いや書かないは嘘だけど、リストを扱う関数が充実してるので自分で再帰してどうこう…っていうのは あまりしなくていいことが最近分かってきた。例えばfoldとか。

あとGaucheには何をするにも低水準(高パフォーマンス)と高水準(使いやすい)のAPIが用意してあって、 「LispはもうひとつのC」を連想した。

[ruby] 継続についての記事を書こうと思って早3ヶ月

人はこれを[あとで書かない]と呼ぶ。

じゃなくて、えーと、YARVに継続が入った記念に概略だけ書くと

  • 継続は「プログラムの残りの部分」のこと。
    • すごく直感的に言うと、RPGにおけるセーブポイントみたいなのを想像するといい。宿屋の主人に話しかけると「現在の状態」をセーブできる。ダンジョンを探索中に「ロード」すると、セーブした瞬間からゲームをやり直せる。
  • 継続ってSchemeとかRubyでしか使えないんでしょ?
    • →これは誤解。「プログラムの残りの部分」なんだから、「プログラムあるところに継続あり」。

バトー、忘れないで。あなたがプログラムを書くとき、継続は必ずあなたの側にいる。

[http://tsukimi.agusa.i.is.nagoya-u.ac.jp/~sydney/ocaml/index.php?%B7%D1%C2%B3より引用]

  • じゃあSchemeやRubyは何が違うのよ?
    • →call/ccがあるのが違う。これはcall-with-current-continuationの略で、RPGで例えると どこでもセーブできる みたいなもん。宿屋でもダンジョンでも戦闘中でも。
    • call/ccを呼ぶと、「call/ccを呼んだ瞬間」をセーブした継続オブジェクトがもらえる。この継続オブジェクトを実行すると、セーブしたところからプログラムが再開される。
  • call/ccがあると何ができるんでしょうか
    • 関数的setjmpというか、λ計算的gotoというかなんというか
    • 実行順序を好きなように蹂躙できる。メソッドを超えてジャンプできる点でgotoより遙かに凶悪。諸刃の剣。
    • 代表的な使い方としては、「プログラムをちょっとだけ止めてあとで再開する」ってのがある。
      • ザ・ワールド
    • Rubyのyieldが自前で実装できる。とか。
  • 「継続渡し」っていうのはcall/ccと関係ある?
    • ありません。別物です
    • 任意の再帰関数は「プログラムの残りの計算」を引数にとるように書き換えることで末尾再帰にできる。という定理があって、この書き換えがCPS変換と呼ばれています*1。CPSは「Continuation Passing Style(継続渡し形式)」の略ね。
  • 継続のRubyでの利用例
    • 時を止めるやつ
      • コルーチン (ゲームのイベント部分の記述に使ったことあり。効果大。)
      • Webアプリ
    • 実行順序を操作するやつ

継続の弱点はやっぱり慣れないと非常に読みにくいっていう点だと思う。変数名を工夫するとかメソッドにラップするとかしないとな。

あと継続を理解するにはjsSchemeのソースを追っかけるのが良かった。内部構造を見れば、「ああこれが継続か」って思うよ。たぶん。

*1 合ってます?