hidekatsu-izuno 日々の記録

プログラミング、経済政策など伊津野英克が興味あることについて適当に語ります(旧サイト:A.R.N [日記])

Cooking as code

ただのネタなんだけど、cookpadあたりやってくれないかな、という期待を込めて書いてみる。

Twitter を眺めていたら、

という話が出ていた。

おぉ、これはわかりやすい。正直なところ現実のプログラムは複雑過ぎてフローチャートにするとむしろわかりにくくなるのだけど、料理のテキストに比べれば遥かにわかりやすい。さすが情報工学と言われるだけのことはある。

ただ、このフローチャートを見て思ったのは、むしろビジュアル・プログラミング 言語に親和性が高いのじゃなかろうか、と思ったのだ。いや、むしろビジュアルプログラムすらいらない。昨今、Infrastructure as code という概念が流行っているが、その延長線状に cooking as code という世界があってもいいではないか。

1年ほど前、自炊を始めたのだが、最初の一週間は何をやってもしょうゆの味しかしない。いろいろ調味料を増やして多少はマシになったのだけれども、どうにも飽きやすい私という人間には耐えられなかったと見え、結局ほとんどやらなくなってしまった。

もし、料理がプログラミング言語で実現できれば、私にもできるかもしれない。cookpad 上の recipehub からレシピをダウンロードしてビルドすれば料理の出来上がり。自分ごのみの味付けにしたければ、Recipefile を自分用に書き換えればいいみたいな。

もちろん、料理とシステムインフラには大きな違いがある。システムインフラと違って、料理の材料は多様だ。Recipefile をビルドするには自動発注システムや万能料理装置が必要になってしまう……あるいは人力ビルドを行うか。

とはいえ、まずは料理記述を定型化することは、非常に重要なことのように思える。料理記述言語とそのHub化の運用が軌道に乗れば、最適化アルゴリズムを使って、料理手順を効率化したり、よくある手順を共通化(=メソッド化)し提供する企業が生まれるかもしれない(アク抜きメソッド実行済みみたいな)。そこまで実現できれば、昨今の大手飲食チェーンが行っている、最終調理工程以外はすでに料理済みみたいな世界が実現できるかもしれない。

まぁ、本当に意味があるのかはともかく、主婦たちが日々の食事を提供するために必死にプログラムを書き続けるという光景はなかなかにシュールではある。

性別、国籍、年齢の多様性は組織にマイナス

世界の経営学者はいま何を考えているのか」の著者、入山章栄氏の新著「ビジネススクールでは学べない 世界最先端の経営学」に面白い話が載っていた。

ビジネススクールでは学べない 世界最先端の経営学

ビジネススクールでは学べない 世界最先端の経営学

 

 大昔は、学者の書く本と言えば、一般受けのしないお硬いタイトルの本が多かったけれども、スティグリッツの邦訳はじめ、昨今はキャッチーなタイトルも多くなった。一見、トが付く類の煽り書名だが、中身はたいへん面白かった。

特に13章の「日本企業にダイバーシティー経営は本当に必要か」は、センシティブな話題も含み大変興味深い。正直、ビジネスの業界用語に疎い当方としては、ダイバーシティと言われても、お台場のあれしか思い浮かばないのだけれども「人の多様性」を意味する言葉だそうだ。たしかに、女性比率を上げようとか、人員登用の国際化とか、しばしば耳にする話題ではある。

著者(の語る最先端の経営学での知見)によると、まず人の多様性と言っても、

  • タスク型の人材多様性:実際の業務に必要な「能力・経験」、例えば、多様な教育バックグラウンド、多様な職歴、多様な経験など
  • デモグラフィー型の人材多様性:性別、国籍、年齢など、その人の目に見える属性の多様性

の2種類があるそうだ。

そして、それぞれのパフォーマンスについて検証した結果、前者については組織のパフォーマンスにプラスの影響を与えるものの、後者については、組織のパフォーマンスに影響を及ぼさないか、むしろマイナスの影響を与える、との結論が得られた。

経験のバックグラウンドの多様性が組織に良い影響を与えるという結論は、知識の多様化により不確実性の高い出来事への対応や新たなビジネスの展開が容易になるという点でたしかにそうだろうと思える。

一方で性別、国籍、年齢の多様性がむしろマイナスに働くという結論は一見不可思議だ。サンデルNHK DVD ハーバード白熱教室で、多様な国籍や性別を迎えることが大学にとって良いことであるという観点から、アファーマティブ・アクションを擁護したのとは対照的に思える。

後者の原因として挙げられているのは、目に見える属性によって人間関係のクラスタが出来やすいという単純な理由だ。たしかに、世界どこにいっても、○○人街のように国籍でコミュニティができていることが多い。人間関係を見ても、同年齢での繋がりに比して、異なる年齢層が混在したグループというのはそうそうはできないように思える。人類みな兄弟という言葉とは裏腹に、人種、民族、宗教による対立がいまだ無くならないどころか拡大している現状は、前述の結果を裏付けているようにも思える。

大学という見識を広げる場では有効でも、組織という目的を達成するための場においては協調することの方が重要だということなのかもしれない。

それにしても以前、「女性だけで企業を作るべき理由」というエントリを書いたのだけれども、意外に核心を突いていたのかもしれない。同書でも、人脈という観点から、女性の内部昇進にはハンディキャップがあることが紹介されている。

男性社員は男性社員と、女性社員は女性社員とつながりやすく、結果、性別による「ホモフィリー(似たもの同士がつながりやすいこと)な社内人脈」ができるのです。

そして多くの日本企業は男性社員が大半ですから、必然的に「男性のホモフィリー人脈」 が厚くなり、よくも悪くもその中でインフォーマルな会社情報がシェアされるようになります。企業幹部の多くは男性ですので、経営方針、人事制度の変更、社内の異動情報などのインフォーマルな重要情報は、いち早く男性の人脈内で回され、男性はますます情報優位になります。

 同書では、他にも「ブレストのアイデア出しは効率が悪い」、「補完性、囲い込みは企業価値に影響しない一方で、新奇性こそが高い企業価値を実現している」など、他にも面白い話題がたくさん書かれている。文章的にも堅苦しくなく、気軽に読めるので、たいへんお買い得な一冊だ。

低額のベーシック・インカムじゃダメなの?

フィンランドベーシック・インカムを導入するのでは? という観測が流れ話題になっている。

どうも、この話まだ検討中の内容にすぎないということで、この社会実験の実現はまだまだ先のことになりそうなのが残念ではあるけれども。

ベーシック・インカムと聞くと直観的に正しくないと感じてしまったり、究極の社会主義のように思ったりする向きもあるようだ。しかし、ベーシック・インカムには合理的な基礎があることはもっと知られて良いのではと思う。

負の所得税という言葉を聞いたことがあるだろうか。これは文字通り最低の所得税をマイナス(すなわち所得水準が低い人々には給付)する政策で、リベラルの巨人ミルトン・フリードマンが提唱した政策だ。負の所得税の考え方は現在では給付付き税額控除という形で様々な国で採用されている。

ベーシック・インカムは累進的な所得税と組み合わせることで、事実上の負の所得税として機能することが知られている。しかも、負の所得税の欠点である所得把握が不要、要件による排除が起きないという大きなメリットも持っている。社会主義的な政策である一方でリベラルで合理的な裏付けもあるという、なかなかに面白く興味深い制度となっている。

過去に書いた内容の焼き直しになるけれども、個人的には月額2~3万円程度の低額のベーシック・インカムから始めてみてはどうだろうかと思う。「アダプト思考」ではないけれども、何事もビッグバンで始めることはない。良かれと思って始めたことが、失敗するなどよくあるのだから、いったんそのレベルで様子を見るのがいい。

月額2~3万円なんて財源はどうするんだと思われるが、同額分、所得税増税生活保護、年金の減額を行えば、社会保障の枠から外れた人たちだけの財源で済むのだから、たかがしれている。この度、せっかくマイナンバーを導入することになったのだから、国民口座もついでに開設してワンセットで運用すれば給付も納税も効率よい運用が可能になるのではないかと思うのだけれどいかがだろうか。

各データベースで使える識別子

複数データベースに対応したシステムを作ってるとよくわからなくなるのでメモ。

こういう話題だとなにかと OracleANSI標準に沿わないと槍玉にあがるが、MySQLの方が意外と鬼っ子だったりする。

Oracle Database

  • 英字で始まる 英数(A-Z0-9)、アンダースコア(_)、ドル($)、シャープ(#)からなる文字列
  • 30バイト以内
  • 大文字/小文字の区別なし(大文字に正規化)
  • ダブルクォート("識別子")にてエスケープ可能

DB2

  • 英字で始まる 英数(A-Z0-9)、アンダースコア(_)からなる文字列
  • 128バイト以内
  • 大文字/小文字の区別なし(大文字に正規化)
  • ダブルクォート("識別子")にてエスケープ可能

SQL Server

  • 英字で始まる 英数(A-Z0-9)、アンダースコア(_)、アットマーク(@)、シャープ(#)からなる文字列
  • 128バイト以内
  • 大文字/小文字の区別はデータベースの照合順序次第
  • ダブルクォート("識別子")、角括弧([識別子])にてエスケープ可能

MySQL

  • 英数で始まる 英数(A-Z0-9)、アンダースコア(_)、ドル($)からなる文字列
  • 64バイト以内
  • 大文字/小文字の区別なし(ただし、一部の環境では混在不可)
  • バッククォート(`識別子`)にてエスケープ可能、後者は ANSI_QUOTES 有効時はダブルクォート("識別子") も可

PostgreSQL

  • 英字あるいはアンダースコアで始まる英数(A-Z0-9)、アンダースコア(_)、ドル($)からなる文字列
  • 64バイト以内(設定で変更可)
  • 大文字/小文字の区別なし(小文字に正規化)
  • ダブルクォート("識別子")、ユニコードクォート(U&"識\5225+005B50")にてエスケープ可能

*1

H2 Database

  • 英字あるいはアンダースコアで始まる英数(A-Z0-9)、アンダースコア(_)からなる文字列
  • 長さの制限なし
  • 大文字/小文字の区別なし
  • ダブルクォート("識別子")にてエスケープ可能

sqlite

  • 英字あるいはアンダースコアで始まる英数(A-Z0-9)、アンダースコア(_)からなる文字列
  • 長さの制限なし
  • 大文字/小文字の区別なし
  • ダブルクォート("識別子")、バッククォート(`識別子`)、角括弧([識別子])にてエスケープ可能

*1:1/19 ドル記号が抜けていたおり、また、ユニコードクォートによるエスケープ方法もあるため追記修正を行った。

elasticserch で全件データを取得する

elasticsearch で from/to を指定せずに検索したところ、なぜか10件しか取得できない。調べたところ、なんと to のデフォルト値は無制限ではなく 10 件となっている。

なるほど、それならばこの値をものすごく大きい数にすれば解決できなくはない。しかしながら、それを行うとHTTPのプロトコル的に巨大なJSONが返されるに違いなく一旦メモリに確保されてしまうようでは大問題だし、大きな数を指定するというのは適当すぎる。だからと言ってページ分割して問い合わせすると、結果の整合性が保証できない。本当にそんな方法しかないのだろうかと思っていたところ、やはり解決策が用意されていた。

stackoverflow.com

size defaults to 10, so you may also need &size=BIGNUMBER to get more than 10 items. (where BIGNUMBER equals a number you believe is bigger than your dataset)

BUT, elasticsearch documentation suggests for large result sets, using the scan search type.

ただし、この回答で書かれている search_type=scan という記述は現在では古いようで、最新版では以下のように書く必要がある。

curl -XGET 'localhost:9200/test/kens/_search?scroll=1m'

このクエリを発行すると scroll に指定した時間(上記の例だと1分間)検索結果のスナップショットが取られ、最初のページデータと共にそのIDが返される。

{
  "_scroll_id": "cXVlcnlU...zTUE7MDs=",
  "took":2,
  "timed_out":false,
  "_shards":{
    ...

このIDを使い

curl -XGET  'localhost:9200/_search/scroll'  -d'
{
    "scroll" : "1m", 
    "scroll_id" : "cXVlcnlU...zTUE7MDs=" 
}'

のような問い合わせを次々とおこなうことで、残りのデータを順次取得することができる。

時間が経てばこのスナップショットは自動的に消滅するものの、(仕組みを考えれば想像に固くないけれども)状態を保持するコストが大きいので、明示的に削除すべし、とドキュメントには書かれている。

curl -XDELETE  'localhost:9200/_search/scroll' -d '
{
    "scroll_id" : ["cXVlcnlU...zTUE7MDs="]
}'

HTTPはステートレスなプロトコルなので、SQLのフェッチのようなことを実現するのは難しいことを考えれば、こういう仕組みにならざるを得ないのだよなぁ、と思う反面、RDBMS では当たり前に実現できていたことでも REST インターフェイスだと案外面倒なものだな、と思ってしまった次第。

続 React 始めました。相変わらず React.js + Webpack の環境構築。

前回の記事では、Webpack 遅すぎて困ったという話で終わってしまったのだけど、その後、webpack dev serverを使えばリアルタイムプレビューできるよという噂を聞きつけ使ってみたところ、即座に反映することが確認できた。

動作を見る限り、オンメモリで差分を調べながらコンパイルしているように見える。

手順 1. Node.js のインストール

前回同様、Node.jsのサイトから長期サポート版の4.2.2をインストール。

手順 2. package.json の作成

npm init で package.json を生成後、dependencies を記載する。本来は単にインストールすればよいだけのはずなのだけど、webpack 用の babel-loader の依存性の問題でなぜか古いバージョンの babel がインストールされてしまう。現段階ではバージョンを明示する必要があるようだ。

{
  ...
  "dependencies": {
    "react": "^0.14.2",
    "react-dom": "^0.14.2"
  },
  "devDependencies": {
    "babel-core": "^6.1.21",
    "babel-loader": "^6.1.0",
    "babel-preset-es2015": "^6.1.18",
    "babel-preset-react": "^6.1.18",
    "css-loader": "^0.23.0",
    "node-sass": "^3.4.2",
    "sass-loader": "^3.1.1",
    "style-loader": "^0.13.0",
    "webpack": "^1.12.6",
    "webpack-dev-server": "^1.12.1"
  }
}

あとはコマンドラインから一括でインストール。

> npm install

手順 3. webpack.config.js の作成

内容的には前回と変わらないが、パフォーマンスを上げるため、一旦 sourcemap と minify は外した。

wepack-dev-server はファイルを物理的には生成せず、HTTP上に動的に生成されるため、どのURLに生成するかを output.publicPath にて指定している。

module.exports = {
  context: __dirname,
  entry: {
    app: './src/main/js/app.js'
  },
  output: {
    path: './src/main/webapp/js',
    publicPath: '/js/',
    filename: '[name].js'
  },
  module: {
    loaders: [
      {
        test: /\.js$/,
        exclude: /node_modules/,
        loader: 'babel',
        query: {
          cacheDirectory: true,
          presets: [ 'react', 'es2015' ]
        }
      },
      {
        test: /\.scss$/,
        exclude: /node_modules/,
        loaders: [ 'style', 'css', 'sass' ]
      }
    ]
  }
}

手順 4. npm run から実行できるようにする。

webpack-dev-server はコマンドラインからでも実行できるが、package.json に追記すると簡単に起動できる。

  ...
  "scripts": {
    "start": "npm run dev",
    "dev": "webpack-dev-server --content-base src/main/webapp/"
  },
  ...

コマンドラインから実行。

> npm start

ブラウザで http://localhost:8080/js/app.js を実行すると変換された app.js が表示されることが確認できる。試しに app.js を書き換えると、ファイルが監視されており即座に画面のリフレッシュがかかる。

あとは、JavaEE サーバとどうやって組み合わせて使うか。普通は Apache とかでパスをマウントして同じドメインに見せかけるとかするんですかね? 本番はともかく開発環境でそれは面倒なので、なんとかしたい気もする。

MorphDOM を使って jQuery replaceWith を置き換える

仕事では相変わらず jQuery を使っているのだけれども、画面の書き換えには replaceWith を多用している。昨今のブラウザはものすごく高速なので、さほど遅さを感じるわけではないけれども、それでもタブ移動のような場合には、遅れを感じてしまうことがある(仕事で使っているPCが非力ということもあるけれども)。

VirtualDOMについて調べていたところ、VirtualDOMじゃなくてもそんなに速度差ないんだよ、と主張している人々がおり、そのひとつの実装として MorphDOMが紹介されていた。

VirtualDOMを使う場合、あるべきビューとしての仮想DOMと新しい仮想DOMを比較してパッチを当てる方式を取るため、既存の考え方と共存させるのはなかなかに難儀だと思われる。しかし、本物のDOMを比較してパッチを当てるのであれば、DOM の置換と同じように使えるのではないか……という思いつきで作ってみたのが以下のライブラリ。

https://github.com/hidekatsu-izuno/jquery.morphreplace

使い方は、scriptタグでロードするだけでOK。jQuery の replaceWith と replaceAll はこのプラグインが勝手に置き換えるので、プログラム側の変更は不要です。

残念ながら、ローカルの chrome でデモを動かして見た限りだと、普通の replaceWith との速度差はほぼなし。条件によっては有利/不利あるのかもしれないけれども、今のところ、メリットがよくわからない感じ。

なお、ソースコード読んでもらえればわかるように、jQueryメソッドをコピペして replaceChild を MorphDOM に置き換えるだけというお手軽な内容だったりする。創作性のかけらもない。