Successfully reported this slideshow.
We use your LinkedIn profile and activity data to personalize ads and to show you more relevant ads. You can change your ad preferences anytime.

2011.12.10 関数型都市忘年会 発表資料「最近書いた、関数型言語と関連する?C++プログラムの紹介」

1,900 views

Published on

Published in: Technology
  • Login to see the comments

  • Be the first to like this

2011.12.10 関数型都市忘年会 発表資料「最近書いた、関数型言語と関連する?C++プログラムの紹介」

  1. 1. 2011 関数型都市忘年会 最近書いた 関数型言語と関連する? C++プログラムの紹介 H.Hiro (Maraigue) Web: http://hhiro.net/about/ Twitter: @h_hiro_
  2. 2. 自己紹介H.Hiro
  3. 3. 自己紹介札幌C++から 来ました
  4. 4. 自己紹介H.Hiro• 大学院生(情報系)• アルゴリズムを考案し、それを実装して 効果を確かめたりしています(主にC++利用)• 最近、C++11の機能をいろいろと使いたいが ために、研究室のマシンをUbuntuを11に アップしました (gcc4.5標準搭載のため)
  5. 5. 自己紹介H.Hiro• 好んで使うもの:C++、Ruby、JavaScript• 用途次第では使うもの:C#、Python、PHP• 一応書けるもの:Perl、Java、etc...
  6. 6. 自己紹介H.Hiro• 好んで使うもの:C++、Ruby、JavaScript• 用途次第では使うもの:C#、Python、PHP• 一応書けるもの:Perl、Java、etc...• まだ使えてないもの:Scala、F#、etc...
  7. 7. 自己紹介• Twitter: @h_hiro_• Facebook: 諸事情により非公開• github: maraigue(まれーぐ)• ブログ: LivedoorブログのID "maraigue"• ニコ動: 探せば見つかります
  8. 8. 自己紹介(宣伝) 数学勉強会@札幌• 大学数学の内容を取り扱ってます (現在は「群論」をやっています)• 毎週土曜日の10:00~12:00に 開催 ※今週については 日曜10:00~12:00• 公式サイト:ぐぐって!
  9. 9. 自己紹介(宣伝) 交通勉強会(trafficonf)• 主に首都圏のメンバーがやっている 勉強会ですが、私も乗っかってます (10/8 札幌でust観覧会を実施)• 不定期開催(2~3ヶ月に1回)• 次の開催は1/7• 次の札幌開催は3/17?• 公式サイト: 「交通勉強会準備会」でぐぐって!
  10. 10. 最近書いた関数型言語と関連する?C++プログラムの紹介 H.Hiro (Maraigue) Web: http://hhiro.net/about/ Twitter: @h_hiro_
  11. 11. おことわり別に、直接 "関数型言語" 的なことをするわけではないです
  12. 12. おことわり 別に、直接 "関数型言語" 的な ことをするわけではないです※C++で、「直接 "関数型言語" 的なことを する」例:Boost.勉強会 #6 札幌のuskz氏の発表http://sites.google.com/site/boostjp/study_meeting/study6
  13. 13. 最近書いた関数型言語と関連する?C++プログラムの紹介 H.Hiro (Maraigue) Web: http://hhiro.net/about/ Twitter: @h_hiro_
  14. 14. 例題与えられた文字列に対し、「どの単語が何番目にあるか」を示す連想配列を生成したい。例えばconst std::string text = "I love C++";という文字列があったとき、連想配列dataをdata["I"] == 0;data["love"] == 1;data["C++"] == 2;となるようにしたい。
  15. 15. 回答例(1)void position(const std::string & str, std::map<std::string, size_t> & result){ size_t number = 0, begin_pos = 0, end_pos; result.clear(); for(;;){ end_pos = str.find( , begin_pos); if(end_pos == std::string::npos){ result[str.substr(begin_pos)] = number; break; }else{ result[str.substr(begin_pos, end_pos - begin_pos)] = number; } begin_pos = end_pos + 1; number++; }}
  16. 16. 回答例(1)void position(const std::string & str, std::map<std::string, size_t> & result){ size_t number = 0, begin_pos = 0, end_pos; result.clear(); for(;;){ end_pos = str.find( , begin_pos); // スペースの位置を発見して if(end_pos == std::string::npos){ result[str.substr(begin_pos)] = number; break; }else{ result[str.substr(begin_pos, end_pos - begin_pos)] = number; } begin_pos = end_pos + 1; number++; }}
  17. 17. 回答例(1)void position(const std::string & str, std::map<std::string, size_t> & result){ size_t number = 0, begin_pos = 0, end_pos; result.clear(); for(;;){ end_pos = str.find( , begin_pos); // スペースの位置を発見して if(end_pos == std::string::npos){ result[str.substr(begin_pos)] = number; break; }else{ result[str.substr(begin_pos, end_pos - begin_pos)] = number; } // ↑その部分までの部分文字列をキーとし連想配列に渡す begin_pos = end_pos + 1; number++; }}
  18. 18. 回答例(1)void position(const std::string & str, std::map<std::string, size_t> & result){ size_t number = 0, begin_pos = 0, end_pos; result.clear(); for(;;){ end_pos = str.find( , begin_pos); // スペースの位置を発見して if(end_pos == std::string::npos){ result[str.substr(begin_pos)] = number; break; !!!??? }else{ result[str.substr(begin_pos, end_pos - begin_pos)] = number; } // ↑その部分までの部分文字列をキーとし連想配列に渡す begin_pos = end_pos + 1; number++; }}
  19. 19. 回答例(1)void position(const std::string & str, std::map<std::string, size_t> & result){ size_t number = 0, begin_pos = 0, end_pos; result.clear(); 関数型な方にとっては 普通なことなのかも for(;;){ end_pos = str.find( , begin_pos); // スペースの位置を発見して if(end_pos == std::string::npos){ しれないけど result[str.substr(begin_pos)] = number; break; }else{ result[str.substr(begin_pos, end_pos - begin_pos)] = number; } // ↑その部分までの部分文字列をキーとし連想配列に渡す begin_pos = end_pos + 1; number++; }}
  20. 20. 回答例(1)void position(const std::string & str, std::map<std::string, size_t> & result){ size_t number = 0, begin_pos = 0, end_pos; result.clear(); 文字列インスタンスを 別途生成するとか for(;;){ end_pos = str.find( , begin_pos); // スペースの位置を発見して if(end_pos == std::string::npos){ (C++的には)言語道断! result[str.substr(begin_pos)] = number; break; }else{ result[str.substr(begin_pos, end_pos - begin_pos)] = number; } // ↑その部分までの部分文字列をキーとし連想配列に渡す begin_pos = end_pos + 1; number++; }}
  21. 21. ポイント関数型言語では、メモリや速度よりも処理の実現方法を気にする傾向がある。
  22. 22. ポイント関数型言語では、メモリや速度よりも処理の実現方法を気にする傾向がある。(個人的な印象)
  23. 23. ポイント関数型言語では、メモリや速度よりも処理の実現方法を気にする傾向がある。(個人的な印象)(例:変数への再代入を避ける)
  24. 24. ポイント関数型言語では、メモリや速度よりも処理の実現方法を気にする傾向がある。(個人的な印象)でも、メモリを重視しなければC++の美学に反する。(個人的な印象)
  25. 25. ポイント関数型言語では、メモリや速度よりも処理の実現方法を気にする傾向がある。(個人的な印象)でも、メモリを重視しなければC++の美学に反する。(個人的な印象)メモリを節約しつつ、関数型言語くらいのレベルで記法を簡略化したい
  26. 26. 回答例(2)Boost::splitを使う(参考URL http://www.gesource.jp/weblog/?p=4531)void position(const std::string & str, std::map<std::string, size_t> & result){ std::list<std::string> splited; boost::split(splited, str, boost::is_space()); size_t number = 1; BOOST_FOREACH(std::string tmp, splited){ result[tmp] = number; }}
  27. 27. 回答例(2)Boost::splitを使う(参考URL http://www.gesource.jp/weblog/?p=4531)void position(const std::string & str, std::map<std::string, size_t> & result){ std::list<std::string> splited; boost::split(splited, str, boost::is_space()); size_t number = 1; 記述は分かりやすいけど BOOST_FOREACH(std::string tmp, splited){ result[tmp] = number; でも文字列インスタンスを }} 別途生成してるだろ!
  28. 28. つまりは• すでに存在する文字列(constであることを 仮定してよい)の部分文字列を 1つの文字列として扱いたい ("I love C++" から "love" や "C++" を得たい)• ただし、その「部分文字列」インスタンスを 作る際、文字列をコピーしてはならない• でも楽に書きたい (substrが使えれば楽に書けるんだけど…)…という状況が私の手元で発生したのでライブラリを書いたのです。
  29. 29. そのライブラリの名は
  30. 30. そのライブラリの名はhttp://www.flickr.com/photos/m-louis/3391434507/ Creative Commons 2.0 Attribution-ShareAlike
  31. 31. そのライブラリの名は fundoshihttp://www.flickr.com/photos/m-louis/3391434507/ Creative Commons 2.0 Attribution-ShareAlike
  32. 32. そのライブラリの名は fundoshi (「他人のふんどしで相撲を取る」 より)http://www.flickr.com/photos/m-louis/3391434507/ Creative Commons 2.0 Attribution-ShareAlike
  33. 33. fundoshiについてgist.githubにありますhttps://gist.github.com/1372506(「fundoshi C++」でぐぐっても出ます)以下のコマンドで入手可能ですgit clone git://gist.github.com/1372506.git
  34. 34. 回答例(1)void position(const std::string & str, std::map<std::string, size_t> & result){ size_t number = 0, begin_pos = 0, end_pos; result.clear(); for(;;){ end_pos = str.find( , begin_pos); if(end_pos == std::string::npos){ result[str.substr(begin_pos)] = number; break; }else{ result[str.substr(begin_pos, end_pos - begin_pos)] = number; } begin_pos = end_pos + 1; number++; }}
  35. 35. 回答例(3)void position(const std::string & str, std::map<fundoshi::string, size_t> & result){ size_t number = 0, begin_pos = 0, end_pos; result.clear(); for(;;){ end_pos = str.find( , begin_pos); if(end_pos == std::string::npos){ result[fundoshi::string(&(str[begin_pos]))] = number; break; }else{ result[fundoshi::string(&(str[begin_pos]), end_pos - begin_pos)] = number; } begin_pos = end_pos + 1; number++; }}
  36. 36. 実行例int main(void){ std::map<fundoshi::string, size_t> result; position("I love C++", result); std::cout << result["I"] << std::endl; std::cout << result["C++"] << std::endl; std::cout << result["love"] << std::endl;}
  37. 37. 実行例int main(void){ std::map<fundoshi::string, size_t> result; position("I love C++", result); std::cout << result["I"] << std::endl; std::cout << result["C++"] << std::endl; std::cout << result["love"] << std::endl;}↓02 きたこれ!1
  38. 38. 簡単なリファレンス(1)• クラス名 – template <class CharType> fundoshi::basic_string<CharType>; – typedef basic_string<char> string; – typedef basic_string<wchar_t> wstring;※std::stringとかに名前を合わせてます メソッド名も基本的には合わせてます
  39. 39. 簡単なリファレンス(2)• コンストラクタ – basic_string(); // 空文字列 – basic_string(const CharType * newstr, size_t length); // 文字列の一部を切り出す場合 – basic_string(const CharType * newstr); // ¥0終端の文字列を使う場合 – basic_string( const std::basic_string<CharType> & newstr); // std::basic_string (std::stringなどを含む) を使う場合
  40. 40. 簡単なリファレンス(3)• ポインタを貰う const CharType * c_str(void) const;• 長さを取得 size_t length(void) const;• 文字を取り出す CharType operator [](size_t pos) const;• 文字列比較 bool operator ==(const basic_string<CharType> & other) const; bool operator < (const basic_string<CharType> & other) const; bool operator <=(const basic_string<CharType> & other) const; bool operator > (const basic_string<CharType> & other) const; bool operator >=(const basic_string<CharType> & other) const;
  41. 41. おことわり APIは(今のところ)これで 全部です!
  42. 42. おわりに• 私はよくRubyも使ってるのだが Rubyに慣れてしまうと C++って記法がエレガントじゃないよね• だから記法にこだわっている• boostとかその点頑張ってるっぽいので タイミングを見て勉強してみたいです
  43. 43. おわりに (再掲) 関数型言語あまり関係なかった。 本当申し訳ない。
  44. 44. おわりに (もし時間が余ったら)もう一つ「記法にこだわる」 ネタをします
  45. 45. おわりに ありがとうございました

×