Your browser doesn't support the features required by impress.js, so you are presented with a simplified version of this presentation.

For the best experience please use the latest Chrome, Safari or Firefox browser.

よりSchemerフレンドリなJavaScriptへ

'("Kyoto.lisp Tech Talk #1" . "@taiju")

免責

自己紹介

自己紹介

(define profile
  (hash-table 'eq?
    '(name . "HIGAHI Taiju")
    '(from . "Fukui")
    '(twitter . "@taiju")
    '(blog . ("あと味" . "http://d.hatena.ne.jp/jdg"))
    '(favorites . ("JavaScript" "Perl" "Scheme"))))

Agenda

JavaScriptはSchemerが作った

JavaScriptはSchemerが作った

Brendan Eich
俺が作った
As I’ve often said, and as others at Netscape can confirm, I was recruited to Netscape with the promise of “doing Scheme” in the browser.

Popularity | Brendan Eich

Agenda

JavaScriptとSchemeの共通点

JavaScriptとSchemeの共通点

※1 JavaScriptではlambdaではなくfunctionと書く

※2 JavaScriptではレキシカルスコープは関数を定義することによって発生する

第一級関数

JavaScript

var add = function(f1, f2) { return f1() + f2() };
var one = function() { return 1 };
var two = function() { return 2 };
add(one, two);
// 3
    

Scheme

(define add (lambda (f1 f2) (+ (f1) (f2))))
(define one (lambda () 1))
(define two (lambda () 2))
(add one two)
;; 3
    

変数と関数の名前空間が同一

JavaScript

var f = function() {};
var f = "function";
f();
// f is not a function

Scheme

(define f (lambda ()))
(define f "function")
(f)
;; invalid application

lambda式

JavaScript

var arithmetic = function(x, y, op) {
  return op(x, y);
};
arithmetic(5, 2, function(x, y) { return x * y });
// 10

Scheme

(define arithmetic (lambda (x y op)
  (op x y)))
(arithmetic 5 2 (lambda(x y) (* x y)))
;; 10

レキシカルスコープ

JavaScript

(function() {
  var i = 100;
  (function() {
    var i = 200;
    console.log(i);
    // 200
  })();
  (function() {
    var i = 300;
    console.log(i);
    // 300
  })();
  console.log(i);
  // 100
})();
console.log(i);
// i is not defined

Scheme

(let
  ((i 100))
  (let ((i 200))
    (print i))
    ;; 200
  (let ((i 300))
    (print i))
    ;; 300
  (print i))
  ;; 100
(print i)
;; unboud variable i

Webに携わっていれば、多かれ少なかれ触ることになるJavaScriptですが、作った人がSchemerで本当に良かったと個人的に思ってます。

手前味噌ですが、以前もSchemeとJavaScriptの共通点について書きました。

ここにいろんな参照先が載ってます。

jstudyで「JavaScriptとLisp」ってタイトルのLTしました - あと味

Agenda

よりSchemerフレンドリなES.next

の前にES.nextに向かうまでの、ECMAScriptの歴史について簡単にご紹介。

ECMAScript 3

ほとんどのブラウザで安心して使える堅いバージョン。

IE6-IE8はこのバージョンのサポートで止まっている。

ECMAScript 4

クラスベースのオブジェクト指向の導入を試みる大胆な取り組みだったが、反対も多く、最終的に放棄されたバージョン。

ActionScript 3はこのバージョンを採用したため、JavaScriptと似てるようで全然違う言語になった。

Schemerは好んで使わんでしょう。 ;-p

ECMAScript 3.1 ECMAScript 5

ECMAScript 4の失敗を経て、対抗勢として策定が進んでいたECMAScript 3.1をベースにECMAScript 5と名前が変更されリリースされたバージョン。

現在、主な主要ブラウザは大体このバージョンが使える。

IEはIE9とIE10でサポート。

※ただし、一部サポートされていない機能のあるブラウザもある。

ECMAScriptの歴史の紹介は以上ですが、ECMAScript 5がサポートされたことで、Schemerにとって嬉しいだろうポイントをご紹介。

Schemerにとって嬉しいだろうポイント

Arrayオブジェクト

  • .forEach
  • .map
  • .every
  • .some
  • .filter
  • .reduce
  • .reduceRight

Functionオブジェクト

  • .bind

ES5では、特にObject周りが充実しましたが、JavaScriptユニークな仕様に関するものなので、Schemer的に嬉しいかどうかは微妙です。

とは言え、ES5は、IE8ですらサポートしていないので、先に紹介したメソッドなどは、ライブラリを利用して、機能追加するか、自分で再定義する必要がありますね。

標準仕様で使いたい人向け: es5shim.js
標準仕様よりも利便性という人向け: Underscore.js

ES5の実装状況などは下記のサイトが参考になります。

ECMAScript 5 compatibility table

よりSchemerフレンドリなES.next

よりSchemerフレンドリなES.next

ES.next(EcmaScript 6)はずいぶんSchemerフレンドリになってきます。

※2012年05月12日の[[harmony:proposals]]を参考にしています。

let

ES.next(ES6)

{ let i = 100;
  { let i = 200;
    console.log(i); }
    // 200
  { let i = 300;
    console.log(i); }
    // 300
  console.log(i); }  
  // 100
  console.log(i);
  // i is not defined

Scheme

(let ((i 100))
  (let ((i 200))
    (print i))
    ;; 200
  (let ((i 300))
    (print i))
    ;; 300
  (print i))
  ;; 100
(print i)
;; unbound variable i

harmony:block_scoped_bindings [ES Wiki]

分割代入

ES.next(ES6)

{
  let [a, b] = [1, 2];
  let [c, d] = [3, 4];
  [a, b, c, d];
  // [1, 2, 3, 4]
}

Scheme

(use srfi-11)
(let-values (((a b) (values 1 2))
             ((c d) (values 3 4)))
  (list a b c d))
;; (1 2 3 4)

harmony:destructuring [ES Wiki]

レストパラメータ

ES.next(ES6)

var f = function(a, b, ...z) {
  return [a, b, z];
};
f(1, 2, 3, 4, 5);
// [1, 2, [3, 4, 5]]

Scheme

(define f (lambda (a b . z)
  (list a b z)))
(f 1 2 3 4 5)
;; (1 2 (3 4 5))

harmony:rest_parameters [ES Wiki]

ジェネレータ

ES.next(ES6)

function* fibonacci() {
  let [prev, curr] = [0, 1];
  for (;;) {
    [prev, curr] = [curr, prev + curr];
    yield curr;
  }
}
let seq = fibonacci();
print(seq.next()); // 1
print(seq.next()); // 2
print(seq.next()); // 3
print(seq.next()); // 5
print(seq.next()); // 8

harmony:generators [ES Wiki]

ES.next(ES6)の実装状況などは下記のサイトが参考になります。

ECMAScript 6 compatibility table

おまけ - Mozjs

Brendan Eich先生がCTOだけあって、MozillaはES6の機能を相当前から先行実装していたり、JavaScriptの処理系の中でもRhinoにおいては、インタープリターモードにて、末尾呼び出しの除去や、継続オブジェクトをサポートしていたりします。

Optimization

Agenda

よりSchemerフレンドリな
ES Harmonyの未来

Harmony Of My Dreams by Brendan Eich

JavaScriptをこんな風にしたいんだと、proposalに上がっていないものも含めて、Brendan Eich先生がざっくばらんに語っている記事。

Hermony Of My Dream
My JSConf.US Presentation
※Harmony Of My Dreamsのエントリーの後に開かれたカンファレンスの資料

文章から、Brendan Eich先生のScheme愛や、
Guy Steel先生への尊敬の気持ちが伝わってくる熱い文章です。

CoffeeScriptにずいぶん感化されてるご様子。

より小さい言語にしていきたいとのこと。まるでSchemeですね。

proposalにまだ上がってないものとしては、関数のリテラル表記、レコード、タプル、末尾呼び出しの表記例が載っています。

最後にこんなことを言っています。

This is a long post. If you made it this far and take away anything, I hope it is Guy's "Growing a Language" meta-point. JS will be around for a very long time, and it has a chance to evolve until its users can replace TC39 as stewards of its growth.

適当な訳

長文スマソ。このまま良い感じになって、Guyの言う"成長する言語"を作れたらいいな。JSはすげー長く使われると思うし、ユーザーがECMAScriptを置き換えるこの時が、チャンスなんだよね。

The promised land would be macros, for syntactic abstraction and extensibility.

適当な訳

小さな言語の最終的な到達点はマクロだと思ってる。

I am not holding my breath, but even without macros, the Harmony-of-my-dreams sketched here would be enough for me.

適当な訳

まー、でもそこまではいいわ。マクロなくたって、ここに書いたことが実現できたら俺はそれで充分っす。

Schemeフレンドリになると力説してきましたが、マクロを導入するとかは、さすがにないっぽいですね...

諦めんなよ!
諦めんなよ、お前!!
どうしてそこでやめるんだ、そこで!!
もう少し頑張ってみろよ!
ダメダメダメ!諦めたら!
周りのこと思えよ、応援してる人たちのこと思ってみろって!
あともうちょっとのところなんだから!

とエールを送りつつも、
Schemerフレンドリになる、
未来のJavaScriptはとても楽しみですね。

Agenda

ご清聴ありがとうございました

Use a spacebar or arrow keys to navigate