C++ 1xについて
C++ Advent Calendar jp 2010の24日目の記事です.世の中ではC++ 0xが旬のようですが,そんな古いのは置いておいてC++ 1xの話をしましょう.C++ 1xはついに破壊的変更が来ます.
include to import
includeは単なる置換でコンパイルが遅い原因にもなっていました.C++ 1xからはシンボルをインポートするだけのimportが追加され,またコンパイル処理の明確な分離によって,爆速コンパイルになっています.
struct / classの最後の;の削除
struct S { // ... } // ;がいらない!
これに苦しめられた人は結構いるのではないでしょうか!
Angel Bracketの削除
C++ 0xで>>が出来るようになったとはいえ,やっぱりこの辺はコンパイラに優しくないわけです.なので,C++ 1xでは!()を使ってテンプレートパラメータを指定するようにします.
vector!(string) v;
auto
C++ 0xでautoが入ったものの,constとかと合わせるときはconst autoとかになって冗長でした.C++ 1xでは
const v = 10; // v is int
とより書きやすくなってます.
配列,連想配列,foreach
この辺ってよく使われるんだから,組み込んだ方がいいよね,ということで組み込まれてます.後Range-based for文はRangeサポートも考慮にいれてforeachに名前が変わりました.
foreach (v : [1, 2, 3]) { // do something }
型推論も効いて使いやすいですね.
alias
typedefがあまり使い勝手がよくないので,template周りでより柔軟に使えるaliasが入りました.template parameterでも使うことができて,parameterに様々なシンボルを受け取れるようになります.
Dvorak初心者なので…
Dvorak Advent Calendarの12/28の記事です.
QWERTYと打ちやすい配列からDvorakに移行してもうすぐ1ヶ月になるtamaです.しかしまだ慣れない自分は,記号とか打つときふとキーボードでキーを探してしまうんですが,愛するMacBook AirのキーボードがDvorak表示ではないという悲しい状況です.
しかし,痒い所に手が届くMacでは標準でキーボードビューアがついていて,今はこれを使って複合キーで迷った時はチェックしています.MacのメニューバーにあるIMEメニューから"キーボードビューアを表示"を押すと
というのが表示されるので,すぐチェック出来て便利です.
早くこれからも卒業して「え?今(Dvorak配列)打ってた?完全に無意識だったわ」と言えるようになりたいです.ということで,他の方とは違いかなり初心者向けの記事になりましたとさ…
D Programming Advent Calender 2010 - 24日目: 使ってはいけない標準モジュール
D Programming Advent Calender 2010の24日目の記事です.ついにここまで来ました.今回の内容はPerlの方であったこの記事のD言語版です.
D言語は言語仕様が固定されることはありますが「標準ライブラリはそうではない」とAndreiが述べています.これはつまりあるメジャーバージョンの言語仕様が固まっても標準ライブラリに破壊的変更が発生する可能性があるということです(D2は今もろにそんな感じです).
ということで,今現在D2のPhobosに関して削除されるモジュールと,使わない方がいいモジュール,破壊的変更がくるであろうモジュールについてまとめて置きたいと思います.D言語にはdeprecatedという便利な属性があるので,使う時にはコンパイラオプションをつけないとコンパイル出来ない関数などもあります.また,削除される予定のモジュールにはpragmaを使ってコンパイル時にメッセージが表示されます.
モジュールのリストは以下から見れます(std.outofmemoryとかはもう消えてるはずなんだけど,なぜリストにあるのか…).
http://www.digitalmars.com/d/2.0/phobos/phobos.html
いずれ削除されるモジュール
- std.atomics
druntimeのcore.atomicを使って下さい.std.atomicsはCASがintにしか対応してなかったりとかなり機能不足です.
- std.bind
レキシカルクロージャが言語としてサポートされたので,使い道がありません.後多分バグっているので,そもそも使えません:(
- std.boxer
std.variantに取って代わられました.
- std.contracts
std.exceptionを使って下さい.std.contractsは名前がおかしい,という議論の後std.exceptionにリネームされたので,中身は一緒です.
- std.date / std.gregorian / std.perf
次のリリースで入る予定のstd.datetimeに全て統合されます.
- std.demangle
druntimeにあるcore.demangleを使って下さい(というか今日core.demangleに委譲するコミットがありました).
- std.intrinsic
消すという話は出てないんですが,core.bitopに取って代わられると思います(なんでまだメンテされているのか…).
- std.iterator
Donが消したはずなのになんでまだリストにいるのかわかりませんが,元々D言語の配列とかはiterableであり,PhobosはRangeコンセプトなので使う事はありません.
- std.openrj
はるか昔とりあえず入れとけ的なノリでReviewもなく入ったモジュールで,使ってる人見た事ありません.
-
- changeset 2240で削除されたので,2.052からは存在しません.
- std.stdint
druntimeのcore.stdc.stdintを使って下さい.ですが元々変数のサイズが決まっているD言語で使っている人見た事ありません.
- std.c.*
druntimeのcore.stdcを使って下さい.環境依存のはcore.sys以下を使って下さい.
使わない方がいいモジュール
- std.metastrings
今はもう必要ないんじゃないかと思います.
- std.regexp
charしか対応してません.std.regexはRange対応でchar, wchar, dcharにも対応しているのでなるべくこっちを使いましょう.
破壊的変更が来るモジュール
- std.json
そもそもバグありです.Robertがstd.variantのパッチ付きでまともな実装を出しているので,レビューが終わればリプレースされます.
- std.md5
デザインがCの移植でダサダサです.OutputRangeを使ったstd.cryptみたいなモジュールで置き換えられると思います(今考えているところですが).
- std.process
StevenとLarsの二人が新しいstd.processを書いています.いずれリプレースされます.
- std.cstream and std.stream
Andreiの一言でstd.streamが消える予定でしたが,さすがに標準ライブラリのIOのほとんどの機能が消えるのはやばいということで,代替案を皆が考えているところです.
- std.socket and std.socketstream
俺担当です.IPv4しか使えなくてかつデザインが微妙なのでリプレース予定です.こんなに遅れてすいません.
- std.typetuple
なんか名前があれ,的な感じでモジュール名とかTypeTupleの名前が変わる可能性があります.この辺はrsinfu先生とか任せ.
- std.xml
遅い?ということでリプレース予定です.2, 3個代替実装があるのですが,個人的にはMichelのXOMベースの実装が気になってたりします(他のはよくも悪くも普通のXMLモジュールなので).
結構なモジュールに変更が来ますね.昔の人が少ない時の影響か,実装やデザインがあれなのに入ってしまったモジュールがあったりして,この辺のブラッシュアップもPhobosの課題の一つだったりします.ということで,俺がリプレースしてやるぜ!って人はモジュールを書いてMLで提案とかしてみたらコミッタになれるかもしれませんよ!!
Dvorak-erへの道
Shibboleth must go!
http://www.publickey1.jp/blog/10/restsoapwebws-i.html
まぁOASISが引き継ぐらしい.SAMLとかの策定もしてるんだし,こっちの方がいいかも?RESTのインターフェイスで面倒な部分とかは結局SOAPとかのような仕様が使われることになると思うので,なんだかんだでしつこく残りそう.
Goのinterface
Goのinterfaceはコンパイルタイムとランタイムで処理が分かれてるんだけど,その境目がよくわかってなくて,全部コンパイルタイムに移るせるんじゃないのかなぁと昨日Twitterで呟いたら,自分の勘違いとかが発覚したので,ここでinterfaceの処理を忘れないうちにまとめておく.Thanks to hajimehoshi and seagetch!
注意点として俺はGoのソースコードを走らせたこともないユーザなので,中身が本当に気になる方はソースや資料("Google Go! A look behind the scenes")を読んだ方がいいです!
interfaceの使い方
interfaceはGoでポリモーフィズム?を実現するための機能.Javaとかのinterfaceと決定的に違うのは,後付けで構造体に好きに実装できるところ.Goは継承を持ってないけど,これでポリモーフィズムが出来るようになる.
type Stringer interface { String() string; } type Binary uint64 func (i Binary) Get() uint64 { return uint64(i) } // Stringerを実装したことになる func (i Binary) String() string { return strconv.Uitob64(i.Get(), 2) } // 後は以下のように使える b := Binary(200) s := Stringer(b) // Stringerを満たしているオブジェクトは何でもOK // code from "Listing 2.2: Using interfaces in Go!"
interfaceの実装
GoはC++でのvtblみたいなものをオブジェクトが持ってない.でも
var foo Stringer if cond { foo = &Binary } else { foo = &Hex } a.String()
とかやろうとするためにはそれ相応の機能が必要で,それがinterface table(以降itable).これはInterfaceの変数が持っていて,実態は以下.
struct Iface { Itab* tab; void* data; };
そのまんま,tabがある型(Stringer with Binary)のitableを指していて,dataがランタイム時の実際の値を指している.
コンパイルタイムにやること
- ある型がinterfaceを満たすかどうかのチェックで,満たしてなければコンパイルエラー
- Stringerのランタイム型生成
- Binaryのランタイム型生成
- コードの置換(s.String() → s.tab->fun[0](s.data)みたいな)
ランタイムにやること
- Ifaceのtabとdataを代入時に動的付け替え
- tabで使うitableを生成し,Binaryのメソッドリストでitableのメソッドリストを埋める
- 結果をキャッシュ(StringerとBineryのハッシュ計算と思われる)
- "static Itab* hash[1009];"
なので最初はitableの生成で時間が掛かるけど,それ以降はキャッシュがあるので,呼び出しコストは一定になる.Itabはlinkを持っているので,ハッシュ値で被ってもitableが上書きされず当該バケットにつながれる.
まとめ
それなりに頑張ってました.コンパイルタイムとか最初に全部itableを計算しないのは,処理によっては通らないパスがあるので,無駄にitableを生成しないためっぽい.
Go使わないのに何やってんだろ…
TinySegmenter in D.
分かち書きとかする時はMecabとかが有名なんだけど,手軽にやりたい時には色々と面倒だしバインディングとか用意するのもあれ,ということでTinySegmenterとかいうのを工藤さんが書かれていた.で,なんかいくつかの言語に移植されてたんだけど,D言語にないのが悔しかったので移植した(というかMecabのバインディングとかってD言語あるのかな?).
http://bitbucket.org/repeatedly/scrap/src/tip/tinysegmenter.d
scoreForとかに関しては静的配列を使えば無駄なアロケーション防げそうなので,問題になるようであれば後々書き換える(今のD言語の一番のネックはこの辺のGCの性能だし).Range対応はどうするかねぇ…
追記
無駄なアロケーション減らしてパフォーマンス改善した.この記事書いた時より2倍くらい速くなってるはずです.