読者です 読者をやめる 読者になる 読者になる

YAPC::Asia Tokyo 2015 1日目(8/21)参加記録

いい加減乗り遅れた感がすごいですが書きます。

というわけでYAPC::Asia Tokyo 2015に行ってきました。最初にTwitterで話題になったときからウォッチして個人スポンサー枠で登録する程度には当初は気合が入っていたのですが、2日目に演奏会本番を入れてしまったり(例によって数日後にエントリが書かれる予定)前夜祭の日は熱出してほぼ1日寝てしまったりで、結局1日目のみの参加となってしまいました。非常に楽しいイベントだっただけに悔しいことこのうえないです。しかも今回でYAPC::Asia Tokyoはラストという…。

Keynote

Perlの話をすると思った?残念!さやかちゃんトールキンでした!」

トールキンの"The Hobbit"と"The Lord of the Rings"をPerl 5とPerl 6になぞらえた話。トールキンにとってのそれぞれの作品とLarry Wallにとってのそれぞれのバージョンは似たような位置づけを持っている、という話。

  • HobbitからLord of the Ringsまでは15年。Perl 5からPerl 6までも同じくらいの時間が経ちつつある。
  • 両作品は登場人物の成長を描いた作品、Perlは「必要のあるときに言語が成長する」
  • Lord of the RingsはHobbitの世界観のre-design。続編は得てしてSecond System Syndromeというものに陥るが、LotRはそれをうまく解決した。Perl 6はPerl 5に対する"Second System Syndrome"をうまくやることを目標としている
  • Hobbitにおける世界観の問題点はLord of the Ringsで触れられて修正されている。Perl 5とPerl 6は「同じ物語」を違う方法で語っている
  • Perl 5とHobbitの同じ弱点として、「既存の伝統を世界観に合わせることなく使用した」 -- 例えばエルフやドワーフというキャラクターを既存のイメージのまま使ったような -- PerlでいうとUNIX正規表現をそのまま使ったりAWKシンタックスをそのまま使ったり

続いてPerl 6での新機能の話。

  • "Phase": Perl 5ではBEGIN, CHECK, INIT, ENDに対してイベントをスケジュールすることができたがスコープのENTER/LEAVE, ループのFIRST/NEXT/LAST, 例外のCATCH/CONTROLなどでイベントをスケジュールできるようになる -- (筆者注:正直よくわかってない)
  • Promises, GoのChannelのようなものの導入
  • イベント処理が例えばこんな感じでかけるようになる:
signal(SIGINT).act: { die "Ow!" }
  • lazy listの導入
constant @fib = 0, 1, *+* ... * ;

my ($a, $b, $c) = 42 xx *; say $c
  • NFG (normalization form graphemes)
  • NSA (not-that-NSA; native shaped arrays)
  • GLR (great list refactor) -- このへんも正直よくわかっていない

設計においてよく言われる言葉に I FAIL GOOD という表現がある。うまく失敗することは大事。"Perl 6 will fail, but it will be a practical and useful failure."

Effective ES6

ES6の全体感
ES6で使われなくなるベストプラクティスなど
来年以降のECMAScriptどうなるの
プロジェクトでどうやって使ったらいいの

Brendan Eich: 「短納期だったんですげえフレキシブルに作ったよみんながんばってね」
Douglas Crockford: 「JS is most misunderstood」

落とし穴

  • prototype inheritance(no class)
  • new, this
  • function scope(no block scope)
  • global variables(no module system)
  • hoisting
  • NaN, undefined
  • typeof null
  • with, eval

Use Prototype to emulate Classes
メソッドはプロトタイプに定義、関数でクラスをエミュレート
newを忘れると危険。関数として実行される。グローバルリーク!

JS開発者は"best practice" = "workaround"をがんばってきた
Effective JS, JS: the Good Parts, ...
「開眼しないと使えない」

function Person(name) {
  if (this instanceof Person) {
    return new Person(name);
  }
  this.name = name;
}

ES6 - 6月に正式に公開
正式にはECMAScript 2015(正式名は今年から)
ES5から6年

  • modern syntax fixing pitfalls
  • better support for large applications
  • no (or few) breaking changes

クラスはどうなっている?

class Person {
  constructor(name) { 
    this.name = name;  
  }
}

newをつけずに呼ぶとエラーになる
プロトタイプでやったり、instanceofでチェックする必要がなくなった

idiomっていうやり方やaltJSっていうやり方があったけどES6を使うことでもういらない。標準仕様だけでいける。

ES6って使えるんですか?
ES6 compatibility table

io.js、モダンなブラウザは50%くらいサポートされている。Safari 9ではかなりサポートされているが IE11は…
( Edgeではサポートするけど )

ES6 Transpiler / ES6 Polyfill
Transpiler - ソースコードを変換する。ES6 -> ES5 / ES3
Polyfill -> ES5/ES3 で ES6のビルトインクラス・関数・オブジェクトを使えるようにするもの

Babel + core-js
jsfiddleもbabel対応したとかしないとか


ES6の機能

  • new syntax
  • new built-in classes and objects
  • improvements of existing classes

arrow function

var add = (a, b) => {
  return a + b;
};

var square = n => n * n;

[1, 2, 3, 4].filter(n => n % 2 === 0).map(...)

selfという文化がJSにはあった。

function(){ 
  var self = this;
  setTimeout(function() { 
    console.log("Hello, I'm "+ self.name);
  }, 1000);
}

arrow functionの中では外側のthisがそのまま引き継がれる

setTimeout(() => {
  console.log("Hello, I'm " + this.name);
}, 1000);

みたくして問題ない

クラス

クラスを継承したいだけなのに言語上用意されてないので「継承はこういう仕組みだ」をオレオレ定義

昔のJavaScriptではビルトインクラスを継承できなかったができるようになった

必要最低限の文法しかない。publicとかprivateとかやりたいですっていうのはまだ。

モジュール

CommonJS modules (node, npm)
requireという関数を呼んだら返って来る
exportsを使ってexport
→ブラウザでは動かないのでbrowserifyとか使うしかない、同期読み込みするものなのでstaticに解析できない(全部解釈しないといけない)

exportキーワード、importキーワード
標準になったのでどこで動く・動かないを気にしなくて済む

モジュール内ではstrictモードが有効化
「"use strict"するのがマナー」だったのが書く必要がなくなった

Hoisting

var a = 'outer';
function bar() {
  console.log(a);
  var a = 'inner';
}

bar(); //-> undefinedが出る

→こういう風に解釈されていた

var a = 'outer';
function bar() {
  var a;
  console.log(a);
  a = 'inner';
}

bar();

→関数内の宣言を全部先頭に持っていけばhoistingは起きないだろ!というベストプラクティスが存在した

let と const
ブロックスコープを作ってくれる
hoistingという謎の現象は起きない
varを使う必要がない!

constはimmutable value (not immutable object)

default parameters, rest parameters

今まで -> argumentsという特殊な引数をArray.prototype.slice.callでやっていた
シグネチャがわからない!
argumentsはArrayっぽいけどArrayじゃない、

function foo(first, second, ...rest) {
  console.log(rest)
}

Destructuring Assignment

let match = /(\d{4})(\d{2})(\d{2})/.exec("20151231")

let {name: a, age: b} = {name: "bob", age: 20}
let {name, age} = {name: "bob", age: 20}

関数の引数としてもできる
名前付きパラメータ、キーワードパラメータ
初期値をつけることもできる

template literal

interpolation

Promise

非同期処理を作るときはPromiseを返す形にする

Map, Set

out of date: Use objects as dictionary

ES6: Map, Setが導入

WeakMap, WeakSet, TypedArray, ...


New Pitfalls

if (a => 1) {
  // will be arrow function
}
// expected this
if (a >= 1) {
  // a is larger-than-eq-to 1
}

ESLint
arrow-parensを使うと上記のは避けられる


May the Babel be with you!

IE11は2023年まで生き続ける…
ネイティブでサポートする機能はtranspileしないという設定もある
ES201Xにも対応する

どの要件?
transpileできる/できないものを判断して機能を使う

TBD / Matz

「"Toward Brain-Friendly Design"のことだと言っておく」


「プログラミングRuby創始者」

一番最初に講演したのが1997 Perl Conference Japan
Perl ConferenceでRubyの紹介をする」

2000 Perl/Ruby Conference
2006 YAPC::Asia Tokyo
2015 YAPC::Asia Tokyo Final
割と頻繁にPerlカンファレンスに出ている
「3年前もRubyKaigiがFinalといっていたような…」

今回こそはRubyの話は封印

Perl に else if を追加した話」: 2006年やろうとした話

言語デザイナー

3D XPoint : すごく速いメモリ 高速大容量不揮発性メモリ

  • DRAMの速度と耐久性
  • SSDの容量と不揮発性

を同時に持つデバイスが登場したとして

CPU -> 揮発性一次記憶 -> 不揮発性二次記憶

みたいなアーキテクチャ

CPU -> 不揮発性一次記憶 以上終わり

になるのでは?

1TB不揮発性メインメモリ以上終わりになったときにどんな言語・OSが必要か?

と思ったが… 15分くらいでネタ切れなのでごめんなさい。


「今新しい言語を設計したらどんな言語にしますか?」

Rubyの反省点、悪口

Rubyの悪口言って一番恨まれないのは私なので…」

一番悪い点:Perlの影響。
どう考えてもやりすぎた。特に$変数。「$=」:文字列比較の大文字小文字が無視できるように挙動を変えられる
取り込んじゃって消すに消せない。
歴史的に間違った判断がいくつかあった。Perlの間違った判断を間違ったまま真似してしまった。

次:Lispの影響が大きすぎた。
Fixnum, Bignum
Integerだけあればよかった。数の大きさがある程度を超えたら勝手に内部構造を変えればよかった。
Ruby 2.0ではFloatが64ビットに収まらないなら内部的にヒープ上に置く、というのをやってる
String, Symbolの区別はLispから。
ProcとLambdaとか、似たようなものだけど違うものをできるだけ減らしたほうがいい
「使い分け」を避ける
他の言語に比べてクラスが少ない。「JavaとかC++とかコンテナクラスいくつあるんだよ」

アーキテクチャの変化:特にマルチコア
スレッドセーフ性。人類には早すぎた。
Global Interpreter Lock: スレッド使ってもクラッシュしないようにしてあげてるのに「GILのせいでマルチコアできねー」って言われる。
スレッドセーフじゃないって言われるのはCライブラリのせいだったりする。グローバル変数あるとスレッドセーフじゃない。
「node.jsはえー」っていってマルチコアのことを忘れる

アクターモデル
シェア・ボロー・モデル(Rustのメモリ管理にあるような)
もしかしたらRuby 3.0に入るかも。何年先やら

どっちかっていうとRubyとは違う言語の話をしよう

高レベル抽象(DSL)
普段は楽にできるけど難しいこと記述するときはCとかJavaとかGoとか
関数型言語の影響。普通のプログラマが関数型に手がとどくようになってきた
Javaの登場によってGCが一般的になった。GCは1960年代頃に発明されてたけど一部の言語以外では遅い使えない言われてた。

アーキテクチャの振り子
サーバー・クライアント
パフォーマンスと生産性: プログラムを高速化するにはなんでもする(コンパイルアセンブリを書く)→それよりも人間の生産性が重要だ(LL・スクリプト言語)→みんながインターネット使うようになると毎秒n万アクセスさばきたい

シェルスクリプトの再評価。マルチコアだとパイプの前と後ろが別のコアに割り当てられる可能性が高い。
プログラミング言語としてのシェルってすごく残念。

Rubyの反省、Rubyと違う判断 → Streemという言語
Stream or Flow based language

パイプラインを組み立てる手続き型 -> パイプラインをデータが流れる

stdin | stdout (cat pipeline)

# simple echo server on port 8007
tcp_server(8007) | {s ->
  s | s
}
# simple netcat on port 8007
s = tcp_socket("localhost", 8007)
stdin | s
s | stdout

プログラムの役割はパイプラインを組み立てる。イベントループの中でデータが流れることによって

ピタゴラスイッチプログラミング(Rube Goldberg Programming)

見た目で言語の区別がつくと嬉しい。RubyとCの区別が一目でつく
Streem:見るからに言語モデルが違うのでbraceでいいや
データはimmutable。変数がいきなり変わったりするとまずい動きをする。lockとかunlockとか入れるのやだ。

エラー処理は言語作る人にとってホットなトピック
明示的チェック(C, Go)
例外処理(Java, Ruby, etc)
Optional(Swift, OCaml, etc) - 静的型によって明示的チェックを行おう
Streemでは?→デフォルト無視。パイプライン組み立て中は例外出すけどパイプラインにデータ流れたあとはデフォルト無視

大クラス主義
使い分けを減らす
数値・文字列・配列しかない
array elements can be (partially) labeled


  1. Hashというデータ構造の名前についてどう思うか? → アーアーキコエナーイ

WebAudioで入門する信号処理

WebAudio != WebMusic

今までのWeb: 画面の表示を更新するだけ。限られた範囲の光の制御ができるにすぎない。
これからのWeb: WebAudioで空気を振動させられる!ヘッドホン端子から電気信号を直接出せる!
Webから物理世界に直接干渉する新しい手段を得た!


WebAudioの考え方

AudioNodeが基本単位。マイク入力ノード、スピーカー出力ノード、各種フィルタノードなど
AudioNodeを複数接続していく

connect : 他のノードとつないでストリームが送られる
基底のメソッドは基本これしかつかわない。

var context = new AudioContext();
var gain = context.createGain();
gain.gain.value = 0.5;
var osc = context.createOscillator();
osc.frequency.value = 600;

osc.connect(gain);
gain.connect(context.destination);
osc.start(0);

context.destination -> スピーカーとかヘッドホンに出力

OscillatorNode : 周波数を無限に発生
AudioBufferSourceNode : 任意の一定時間波形を発生させることができる
MediaElementAudioSourceNode : audio, video要素から音を取り出す
MediaStreamAudioSourceNode: マイク・ビデオ入力から音を取り出せる

AudioDestinationNode - 通常の出力
MediaStreamAudioDestinationNode - WebRTC的なやつ

ChannelSplitterNode, ChannelMergerNode

フィルタ系
GainNode, BiquadFilterNode(ローパス・ハイパス・バンドパスフィルタ), ScriptProcesserNode, AnalyserNode(FFT)

ScriptProcesserNode
指定したバッファサイズごとにコールバックが来る 信号処理用です(断言)

データはどう来るか?
onaudioprocessイベントをlisten
イベントオブジェクトごとにFloat32Array

残念なお知らせ: Deprecated。

AudioWorkerNodeになります。しかしまだ実装がない。実行コンテキストがworkerになるだけだと思う。
オーディオはすごいスピードで来るのでコールバックだと重くてブラウザが死ぬ。別のJavaScriptコンテキストになるのでメインのスレッドは固まることはない。

navigator.getUserMedia()
マイク入力・ビデオ入力を得られる。今の所はベンダプリフィクス(webkitとか)が必要。
使用時にユーザーの許可が必要。

残念なお知らせ: Deprecated on insecure origins (HTTPでは使えなくなる)。
個人開発でもHTTPSのサーバーを建てなきゃいけない…


オーディオ帯域の信号処理
20Hz - 20kHz、サンプリングレート44.1KHz
音声帯域: 300Hz - 3.4KHz : 電話回線がこの帯域。会話できる最低限。

音声帯域の通信といえば…ピーピョロリロギャーギャー
ダイアルアップ:DTMFダイアル、遅いハンドシェイク通信、早い通信の開始

WebAudioでモデム作った
2値FSKによるモデム 300bps、誤り訂正なし

信号処理で知っておくべきキーワード
周波数
振幅 0から最大の絶対値まで
位相 波と波のズレのこと。同じ周波数でしか定義できない。
サンプリング周波数 - アナログ信号をデジタル化するときどれくらいの頻度でデータを取得するか
ナイキスト周波数 = サンプリング周波数の半分。再現可能な最大の周波数。
周波数変換 - 2つの波形を合成すると差と和の波ができる。1000Hzと1500Hzの音が鳴っているとき500Hzと2500Hzの音も聞こえる。 うなり・モアレ

周波数帯域と通信速度
帯域が広いほど速度は速くできる
ノイズが少ないほど速度は速くできる
シャノン・ハートレーの定理

搬送波: 信号を伝送するための基本周波数
AMラジオ 1242kHzといった場合、周波数帯域は1242kHz +- 7.5kHz

変調(modulation)、復調(demodulation)
mod + dem = モデム
信号を伝送用に変換すること
変調方式によって伝わり方が違う

On-Off Keying OFK = 音のあるなし
信号が弱いときに信号が弱いのかゼロなのか判断できない
一方ノイズに強い
基本的には使わない

ASK 0がちょっと弱い、1が強い
AMラジオのデジタル版

FSK
FMのデジタル版。プーピープーピー
振幅が関係ないからノイズに強い。周波数だけ感知すればいい。

PSK
位相の変化を使う

QAM = ASK + PSK
16QAM, 64QAM, 256QAM

直交位相
InPhase + QuadraturePhase
90度位相差があると合成しても元に戻せる

エラー訂正
リード・ソロモン符号

まともなモデムの実装

  • データをパケット化
  • 誤り訂正
  • インターリーブ
  • 誤り訂正
  • →送信

ってするが…前のやつはそれしてないのでまともじゃない

WebAudioはデバッグが難しい。波形を見えるようにした。canvasでトリガ付きオシロスコープを書いた。


WebAudioの昨今

超高音通信
16kHz〜くらいの音での通信
超音波とかいわれているけど超音波ではない
AndroidGoogle Playにも入ったらしい?

メリット:マイク・スピーカーで送受信可能、近接通信が可能
デメリット:マイクやスピーカーに特性の保証がない、人によっては不快に聞こえるのでスペクトラム拡散すれば…?、遠距離通信が難しい、周波数が低くノイズが多いので速度は出ない

IoTとの連携
WiFiに接続させたい!→接続情報をどうやって入力させるの?→直接ヘッドホンポートに電気信号を送ればいいのでは!

WebAudio直結UART
追加のファームウェア実装なしでシリアル通信!

2400bpsくらいならいけそう。4800bps, 9600bpsもいけそうだけど回路の修正が必要。

SSIDとパスワードをIoTデバイスに送ってセットアップできそう。追加部品が若干必要だがHTTPサーバーを実装するよりはちっさい。

WebAudioで電源供給!?
音量MAXで出力→昇圧→LEDが光らせられる!(約50mW)


(このへんでパソコンの電池が切れ手書きのノートに)


Electron: Desktop App Built with Web Technology

Webテクノロジーでファイルシステムクリップボードへのアクセス・ネイティブライブラリの使用などのネイティブアプリの特権だった機能が使えるようになった、という話。GitHubAtomMicrosoftVisual Studio Code、FacebookのNuclideあたりがこれを使って作られている。

テキストエディタ以外にも猫の顔認識やドローアプリが作れる。これもNode.jsで多くの機能がすでに公開されているからそれを借りただけでほとんどコードを書かずに作れた。

Electronで動くロボットやElectronで書かれたゲームエディタもある。

PerlでElectron App作ってよ!」→「CPANにすでにあります」

趣味から育てたWebサービスで生きて行く esa.io

Markdownによるドキュメント共有。2ヶ月+のトライアル→500円/(ユーザー・月)

esa LLC:2014/11〜、2人

esaを始める前はAndroid/iOS、クライアントサイド・サーバサイド、Java/Node/PHP/Ruby、BtoB/BtoCいろいろやった。Android appで5つ、Ruby Gemを24個、Chrome Extensionは30+個公開。いろいろやるとどれかうまくいく。公開するとチャンスが増える。

某ドキュメント共有サービスの試用期間が切れた→自作しよう!ということで開発合宿で作った。pplogの開発メンバーでドッグフーディング、さらに開発を続ける。

esaの会社を作った。open betaにしたら大量の申請が来て待たせてしまった。

2月にesaじゃないほうの会社をやめた。有料で使ってくれる人が思ったよりも多かったため。

どうやって開発しているか?
楽しく開発したい。「自分たちが楽しく開発することがユーザー価値を最大化する」という信念。
しかし楽しさやモチベーションはコントロールできない。なのでコントロール可能なものを見極めてそれをコントロールすることに集中。

  • 毎日bundle update、その差分のPull Request作成を自動化
  • bug fixタイムアタック -- 外出中にスマートフォンからdeployできると技術点が高い
  • フィードバック駆動開発
  • リリースノート駆動開発
  • 心からのドッグフーディング
  • よく寝る -- 毎日決済処理があると眠れないので月一に変更した
  • We're not Hiring: 今のところ少人数のほうがメリットが大きい、ユーザーサポート=意思決定者であることのメリットが大きい
  • Herokuを使う:インフラを気にしなくてよくなる
  • 開発スケジュールを決めない
  • かわいさ重要 -- アルファリリースの前から公式グッズ

LT

とりあえず覚えているものを中心にメモ:

  • 幕間宣伝枠:ネコトーストラボさんの宣伝。ノベルティ同梱のサイリウムの提供。「同人サークルではない」
  • Gitの作り方:Gitのファイル保存方法について、Gitにファイルを取り込む・Git形式からファイルを取り出す部分の実装
  • SaaSをうまく活用した障害対応:障害を検知したらReactioにトピック作成・Qiita::Teamにまとめ記事を自動生成までを自動化、即時の反応+あとからトラックするのが容易になる
  • PHPregister_globalsを5.4以降で再現する:
  • CPANクライアントのダウンロードを並列実行するようにしたら爆速になったcpmの話

個人的メモや感想

もはやPerlなんて書けなくなって久しいわけですがそれでも楽しかったです。ああやっぱり前夜祭と2日目出たかった悔しい。

Perlから遠のいて10年以上経つわけですがそれでもPerlユーザーのWeb業界への浸透度・影響力の高さはさすがですね。2000年前後のプログラミングといったらCGICGIといったらPerlみたいな時代から現役だった人たちが多いのではないでしょうか。自分も結局紆余曲折を経てWeb技術という原点に戻ってきたので感慨深くもあります。その当時と違う点としては、Web技術でできることが増えている(聞いた中ではWebAudioとかElectronとかがいい例)、それを実装するための方法がよくなっている(ES6とか)、というのが「JavaScript?alert出すための言語でしょ?」の時代から大きく進歩した点。10年前はPHP使うことに何も抵抗はなかったわけですが、今やJSやPHPをそのまま使うなんてやってられなくなりました。できることが多くなってこれからもできることが増えていきそうというのはWebに戻ってきてよかったと思うことですね。一方で技術の振り子は「簡単にできる」ことから「性能が出ないといけない」方向に倒れていることもあり技術的なチャレンジが尽きない分野であることもよいことです。WebAudioでダイアルアップモデムの再現デモがあったことも含めて懐かしい気持ちになると同時に原点を振り返るいい機会になったと思います。

運営の皆様お疲れ様でした&ありがとうございました!