忍者ブログ
萌え指向プログラミング言語「萌香」のBlog
[1] [2]
×

[PR]上記の広告は3ヶ月以上新規記事投稿のないブログに表示されています。新しい記事を書く事で広告が消えます。

ユメのチカラ Rubyで習作 に吉岡弘隆さんのRubyプログラムが掲載されていていろんな人が添削しています。

プログラムの内容は親(?)ファイルにLinuxディストリビューションのパッケージ情報が入っていて、 (複数の)子(?)ファイルにそれが入っている場合"include"と、入っていない場合"not-include"と表示するものです。 (各行がパッケージ名、各列が各ディストリビューションのテーブルとなる)

個人的には Tociyuki::Diary - 吉岡弘隆さんの「Rubyで習作」を添削 が非常に参考になりました。

特にArrayの最初の要素とそれ以外の要素を分けるために

asianux, *dists = ARGV.collect do |filename|
とやるとこなんかは自分のイディオムに入ってなかったので大変参考になりました。

自分は最初

mother   = ARGV[0]
children = ARGV[1..-1]
なんてのを考えていました。

自分でやるなら結果をCSV形式にしてこんなかんじにしますでしょうか。

#!/usr/local/bin/ruby

mother_name, *child_names = ARGV

children = child_names.map {|name|
                aHash = Hash.new("not-include")
                IO.foreach(name) {|package_name|
                    aHash[package_name] = "include"
                }
                aHash
            }

IO.foreach(mother) {|package_name|
    tArray = [package_name] \
           + children.map {|child|
                 child[package_name]
             }
    puts tArray.join(", ")
}
テストデータがないためデバッグができないのでぜんぜん動かなかったらすみません。

とりあえずHashのデフォルト値を使ったので条件分岐がなくなったのがちょっとした利点です。

PR

「萌香」のコードを整理しようと思ってコードを読んだんですが、「末尾再起の最適化に関するメモ」というコメントがなにを書いてるんだかさっぱりわからない。ポルナレフAAを貼りたくなるぐらい何がなんだかわからない。なんか悪い薬でもやってたんだろうか。

きっと末尾再帰っぽいことがようやくできて舞い上がっていたんだろう。黒歴史として早く葬りたい。

解読してみる。

--- begin 本文 ---
末尾再帰の最適化に関するメモ

本プログラムには変数のフレームのスタックと継続のスタックが存在します。
Lexical scopeのクロージャなので、クロージャの再帰呼出しではフレームの
スタックが積まれることはありません。
(その呼出しへの参照が残っていた場合、そこに保持されている。)

クロージャの呼出し時に
フレームの退避 --> クロージャの実行 --> フレームの復帰
と行うと、クロージャの実行時に末尾再帰呼出しがあった場合
フレームの退避 --> クロージャの実行 -->
フレームの退避 --> クロージャの実行 --> フレームの復帰 --> フレームの復帰
となります。
ここで、フレームの退避はlexical scopeクロージャの場合フレームの
新規作製であり、作製されたフレームはクロージャの実行の終了とともに
GCによって回収されるようになります。

結局クロージャの実行時にフレームの復帰の継続がどんどん増えていくことに
なります。
フレームの復帰は最後のものだけ行えばよく、
末尾再帰の場合、フレームの復帰の継続を作製する場合、次の継続に
フレームの復帰があった場合継続の作製は行う必要はありません。

以上のことから、フレーム復帰の継続の作製を抑制すれば末尾再帰の
最適化になることになります。
--- end 本文 ---

--- 本プログラムには変数のフレームのスタックと継続のスタックが存在します。
これは単なる事実。ここでいう継続のスタックで保持されているものには次の関数呼び出しで使われる引数の保持先(return valueの戻し先)等様々なものがある。(わかりにくくてすみません。あとで整理する。) なので厳密な「継続のスタック」ではないかも知れない。

--- Lexical scopeのクロージャなので、クロージャの再帰呼出しではフレームのスタックが積まれることはありません。
「クロージャの再帰呼び出し」ではなく「クロージャの呼び出し」。ちなみに現在の実装ではフレームを積んでおきながら、呼び出しと同時にクロージャ定義時のフレームの参照に変更している。あとでなおす。

--- (その呼出しへの参照が残っていた場合、そこに保持されている。)
「その」と「そこ」が何を指しているかわからない。

--- クロージャの呼出し時にフレームの退避 --> クロージャの実行 --> フレームの復帰と行うと、クロージャの実行時に末尾再帰呼出しがあった場合フレームの退避 --> クロージャの実行 -->フレームの退避 --> クロージャの実行 --> フレームの復帰 --> フレームの復帰となります。
ここで、フレームの退避はlexical scopeクロージャの場合フレームの新規作製であり、作製されたフレームはクロージャの実行の終了とともにGCによって回収されるようになります。
ここでいう「フレームの退避」はフレームチェインに新しいフレームを作成すること。(新しいフレームは既存のフレームチェインにつなげられる) なんで「退避」と言う言葉を使ったのかわからない。 今考えると「フレームの退避」「フレームの復帰」は必要ないっぽい。(現在見えている変数フレームは継続スタックに保持されているじゃん) あとでなおす。

--- 結局クロージャの実行時にフレームの復帰の継続がどんどん増えていくことになります。フレームの復帰は最後のものだけ行えばよく、末尾再帰の場合、フレームの復帰の継続を作製する場合、次の継続にフレームの復帰があった場合継続の作製は行う必要はありません。

--- 以上のことから、フレーム復帰の継続の作製を抑制すれば末尾再帰の最適化になることになります。
現在の実装ではフレームの復帰が連続する場合その継続の作成を抑制しているがフレームの復帰は必要ないっぽい。あとでなおす。

今まで簡略化されていた文字を元の文字?の表記に戻すらしい。d.hatena.ne.jp/NAOI/20070109/1168334642

ところでこれって字体 ?(グリフ ?)の変更というので正しいのでしょうか。変換は一対一で出来るのでしょうか。葛城市の問題は ? 高と髙はどうなるの ? 今回の変更はそこまでの問題は扱わず単純にグリフの変更で対応できるもののみ扱うの ? 文字コードは難しいです(> <;)

ところで初めてのトラックバックなんだけどこれでいいのかな ? 引用元に迷惑掛けてないかな ?

萌え指向プログラミング言語「萌香」を公開してから1年経ちました。

この一年何もしてないように見えていろいろやってたんですよ。エイトクィーンの記事を書こうと悪戦苦闘してたのですがなかなかうまく書けなくって。人にわかる文章書くのって難しいですね。

ほんとは一周年のときにエイトクィーンの記事くらいは書きたかったのですが、あきらめて中途半端ですが順列の作成プログラムをアップするだけにしました。(一応エイトクィーンのプログラムも出来てたはずなのですがどっかいっちゃった。)

今後ともよろしくお願いします。



忍者ブログ [PR]
カレンダー
10 2019/11 12
S M T W T F S
1 2
3 4 5 6 7 8 9
10 11 12 13 14 15 16
17 18 19 20 21 22 23
24 25 26 27 28 29 30
フリーエリア
最新CM
[11/30 Lehar9296 ]
[11/19 Bihler7840 ]
[04/09 pavelvolinkins]
最新TB
プロフィール
HN:
No Name Ninja
性別:
非公開
バーコード
ブログ内検索
アクセス解析