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

1,481 views
1,404 views

Published on

Published in: Technology
0 Comments
0 Likes
Statistics
Notes
  • Be the first to comment

  • Be the first to like this

No Downloads
Views
Total views
1,481
On SlideShare
0
From Embeds
0
Number of Embeds
29
Actions
Shares
0
Downloads
4
Comments
0
Likes
0
Embeds 0
No embeds

No notes for slide

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. おわりに ありがとうございました

×