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
}

型推論も効いて使いやすいですね.

static *

static ifやstatic assert(C++ 0xではstatic_assert)などコンパイルタイムに色々やる人が増えたので,組み込みで使いやすくなりました.

alias

typedefがあまり使い勝手がよくないので,template周りでより柔軟に使えるaliasが入りました.template parameterでも使うことができて,parameterに様々なシンボルを受け取れるようになります.

constexpr

C++ 1xでは,コンパイル時に値が決まるものを利用した関数はそもそもコンパイル時に評価されるため,これは廃止されました.

thread_local

C++ 1xではデフォルトで変数はTLSに保存されます.なので,thread_localの変わりにsharedという共有変数を表すキーワードが追加されました.

まとめ

その他にもここにあるような機能はちゃんとサポートされています.で,肝心の処理系はこのページからダウンロードできます.あ,言い忘れましたがC++ 1xは別名D言語と呼ばれているので,C++ 1xが面倒な人はD言語と読んだ方が呼びやすいかもしれません.

Enjoy C++ 1x!

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に取って代わられると思います(なんでまだメンテされているのか…).

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

今はもう必要ないんじゃないかと思います.

charしか対応してません.std.regexはRange対応でchar, wchar, dcharにも対応しているのでなるべくこっちを使いましょう.

破壊的変更が来るモジュール

そもそもバグありです.Robertがstd.variantのパッチ付きでまともな実装を出しているので,レビューが終わればリプレースされます.

デザインが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先生とか任せ.

遅い?ということでリプレース予定です.2, 3個代替実装があるのですが,個人的にはMichelのXOMベースの実装が気になってたりします(他のはよくも悪くも普通のXMLモジュールなので).

結構なモジュールに変更が来ますね.昔の人が少ない時の影響か,実装やデザインがあれなのに入ってしまったモジュールがあったりして,この辺のブラッシュアップもPhobosの課題の一つだったりします.ということで,俺がリプレースしてやるぜ!って人はモジュールを書いてMLで提案とかしてみたらコミッタになれるかもしれませんよ!!

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倍くらい速くなってるはずです.