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

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

on

  • 1,212 views

 

Statistics

Views

Total Views
1,212
Views on SlideShare
1,206
Embed Views
6

Actions

Likes
0
Downloads
2
Comments
0

1 Embed 6

http://a0.twimg.com 6

Accessibility

Categories

Upload Details

Uploaded via as Adobe PDF

Usage Rights

© All Rights Reserved

Report content

Flagged as inappropriate Flag as inappropriate
Flag as inappropriate

Select your reason for flagging this presentation as inappropriate.

Cancel
  • Full Name Full Name Comment goes here.
    Are you sure you want to
    Your message goes here
    Processing…
Post Comment
Edit your comment

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

  • 2011 関数型都市忘年会 最近書いた 関数型言語と関連する? C++プログラムの紹介 H.Hiro (Maraigue) Web: http://hhiro.net/about/ Twitter: @h_hiro_
  • 自己紹介H.Hiro
  • 自己紹介札幌C++から 来ました
  • 自己紹介H.Hiro• 大学院生(情報系)• アルゴリズムを考案し、それを実装して 効果を確かめたりしています(主にC++利用)• 最近、C++11の機能をいろいろと使いたいが ために、研究室のマシンをUbuntuを11に アップしました (gcc4.5標準搭載のため)
  • 自己紹介H.Hiro• 好んで使うもの:C++、Ruby、JavaScript• 用途次第では使うもの:C#、Python、PHP• 一応書けるもの:Perl、Java、etc...
  • 自己紹介H.Hiro• 好んで使うもの:C++、Ruby、JavaScript• 用途次第では使うもの:C#、Python、PHP• 一応書けるもの:Perl、Java、etc...• まだ使えてないもの:Scala、F#、etc...
  • 自己紹介• Twitter: @h_hiro_• Facebook: 諸事情により非公開• github: maraigue(まれーぐ)• ブログ: LivedoorブログのID "maraigue"• ニコ動: 探せば見つかります
  • 自己紹介(宣伝) 数学勉強会@札幌• 大学数学の内容を取り扱ってます (現在は「群論」をやっています)• 毎週土曜日の10:00~12:00に 開催 ※今週については 日曜10:00~12:00• 公式サイト:ぐぐって!
  • 自己紹介(宣伝) 交通勉強会(trafficonf)• 主に首都圏のメンバーがやっている 勉強会ですが、私も乗っかってます (10/8 札幌でust観覧会を実施)• 不定期開催(2~3ヶ月に1回)• 次の開催は1/7• 次の札幌開催は3/17?• 公式サイト: 「交通勉強会準備会」でぐぐって!
  • 最近書いた関数型言語と関連する?C++プログラムの紹介 H.Hiro (Maraigue) Web: http://hhiro.net/about/ Twitter: @h_hiro_
  • おことわり別に、直接 "関数型言語" 的なことをするわけではないです
  • おことわり 別に、直接 "関数型言語" 的な ことをするわけではないです※C++で、「直接 "関数型言語" 的なことを する」例:Boost.勉強会 #6 札幌のuskz氏の発表http://sites.google.com/site/boostjp/study_meeting/study6
  • 最近書いた関数型言語と関連する?C++プログラムの紹介 H.Hiro (Maraigue) Web: http://hhiro.net/about/ Twitter: @h_hiro_
  • 例題与えられた文字列に対し、「どの単語が何番目にあるか」を示す連想配列を生成したい。例えばconst std::string text = "I love C++";という文字列があったとき、連想配列dataをdata["I"] == 0;data["love"] == 1;data["C++"] == 2;となるようにしたい。
  • 回答例(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++; }}
  • 回答例(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++; }}
  • 回答例(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++; }}
  • 回答例(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++; }}
  • 回答例(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++; }}
  • 回答例(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++; }}
  • ポイント関数型言語では、メモリや速度よりも処理の実現方法を気にする傾向がある。
  • ポイント関数型言語では、メモリや速度よりも処理の実現方法を気にする傾向がある。(個人的な印象)
  • ポイント関数型言語では、メモリや速度よりも処理の実現方法を気にする傾向がある。(個人的な印象)(例:変数への再代入を避ける)
  • ポイント関数型言語では、メモリや速度よりも処理の実現方法を気にする傾向がある。(個人的な印象)でも、メモリを重視しなければC++の美学に反する。(個人的な印象)
  • ポイント関数型言語では、メモリや速度よりも処理の実現方法を気にする傾向がある。(個人的な印象)でも、メモリを重視しなければC++の美学に反する。(個人的な印象)メモリを節約しつつ、関数型言語くらいのレベルで記法を簡略化したい
  • 回答例(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; }}
  • 回答例(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; でも文字列インスタンスを }} 別途生成してるだろ!
  • つまりは• すでに存在する文字列(constであることを 仮定してよい)の部分文字列を 1つの文字列として扱いたい ("I love C++" から "love" や "C++" を得たい)• ただし、その「部分文字列」インスタンスを 作る際、文字列をコピーしてはならない• でも楽に書きたい (substrが使えれば楽に書けるんだけど…)…という状況が私の手元で発生したのでライブラリを書いたのです。
  • そのライブラリの名は
  • そのライブラリの名はhttp://www.flickr.com/photos/m-louis/3391434507/ Creative Commons 2.0 Attribution-ShareAlike
  • そのライブラリの名は fundoshihttp://www.flickr.com/photos/m-louis/3391434507/ Creative Commons 2.0 Attribution-ShareAlike
  • そのライブラリの名は fundoshi (「他人のふんどしで相撲を取る」 より)http://www.flickr.com/photos/m-louis/3391434507/ Creative Commons 2.0 Attribution-ShareAlike
  • fundoshiについてgist.githubにありますhttps://gist.github.com/1372506(「fundoshi C++」でぐぐっても出ます)以下のコマンドで入手可能ですgit clone git://gist.github.com/1372506.git
  • 回答例(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++; }}
  • 回答例(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++; }}
  • 実行例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;}
  • 実行例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
  • 簡単なリファレンス(1)• クラス名 – template <class CharType> fundoshi::basic_string<CharType>; – typedef basic_string<char> string; – typedef basic_string<wchar_t> wstring;※std::stringとかに名前を合わせてます メソッド名も基本的には合わせてます
  • 簡単なリファレンス(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などを含む) を使う場合
  • 簡単なリファレンス(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;
  • おことわり APIは(今のところ)これで 全部です!
  • おわりに• 私はよくRubyも使ってるのだが Rubyに慣れてしまうと C++って記法がエレガントじゃないよね• だから記法にこだわっている• boostとかその点頑張ってるっぽいので タイミングを見て勉強してみたいです
  • おわりに (再掲) 関数型言語あまり関係なかった。 本当申し訳ない。
  • おわりに (もし時間が余ったら)もう一つ「記法にこだわる」 ネタをします
  • おわりに ありがとうございました