書いて覚えるSwift入門

第47回 Swiftに足りないものは何か?

この記事を読むのに必要な時間:およそ 4 分

有能ではあるが万能には足りない

前回の予告どおり,今回はSwiftへの不満と将来への期待を取り上げます。

公式サイトのAbout Swiftにはこうあります。

The goal of the Swift project is to create the best available language for uses ranging from systems programming, to mobile and desktop apps, scaling up to cloud services.

「Swift プロジェクトのゴールは,システムプログラムからモバイルおよびデスクトップアプリケーション,そしてクラウドサービスに至るまで最良の言語を創ることである」⁠裏を返すと,Swiftへの不満はこのゴールに足りないものということになります。

RustにあってSwiftにないもの=RustになくてSwiftにあるもの

現時点において,Swiftはシステムプログラミングにほとんど用いられていません。つまりカーネル(kernel)やデバイスドライバ(device drivers)はSwiftでは書かれていないということです。これはSwiftの「先輩言語」の1つであり,Swiftともっとも見た目が似ているRust言語とは対象的です。

RustにはすでにRustで実装されたRedoxというOSがあります図1)⁠それも仮想マシンでただ起動してコンソールが表示されるというレベルではなく,実マシンで動作してGUIも装備しているというレベルです。すごいですね。

図1 Redoxのデスクトップ画面

図1 Redoxのデスクトップ画面

それに対し,Swiftは「故郷」のAppleにおいてすらアプリケーションの開発にしか用いられていません。この違いはどこから来るのでしょうか?

筆者の答えは,過去の遺産の有無です。SwiftはObjective-Cの遺産を継承することが義務付けられましたが,Rustにはそれがありません。SwiftはObjective-CとともにiOSとmacOSの開発者コミュニティをも継承することで,Version 1どころかベータ段階から100万人単位でユーザを確保することに成功しましたが,Objective-Cの「技術的負債」も一部背負うことになりました。

たとえばメモリ管理。SwiftもObjective-C同様,参照カウンタ(reference counter)でメモリ管理を実現しており,それが言語レベルで密結合していますARC:AutomaticReferenceCounting)⁠参照カウンタはプログラミング言語における代表的なメモリ管理技術で,JavaScriptやPerlやPythonなどでも用いられてきましたが,それが唯一の手法でないことは賢明な読者のみなさんはご存じのとおりです。

しかし問題なのは参照カウンタ方式であることそのものより,それが言語仕様と密結合していることにあります。密結合しているおかげで循環参照の解消などをプログラマが制御できるのですが,密結合しているということは別の手法を導入したり,メモリ管理そのものをSwiftで実装したりすることが難しいということでもあります。

これに対しRustは,Ownershipという概念を導入したことで言語自体にメモリ管理を密結合させることを極力避けたうえで,参照カウンタなどの機能はRcなどライブラリとして分離されています。これはRustが難しい言語になっていることの一因(というか最大の理由)にもなっているのですが,システムプログラミング言語として頭1つ抜けている理由でもあると言えるでしょう。

Ownershipがいかに優れた概念であるかは,Swiftにも導入の動きがあることからも伝わってきます。

SwiftはSwiftで書かれていない

Swift 4.2現在,SwiftはSwiftではなくおもにC++で実装されています。別の言い方をするとSwiftはセルフホストされていないということです。JavaScriptからRubyまで,アプリケーション言語の多くはセルフホストされておらず,そのこと自体が問題というわけではありませんが,Cをはじめ,システムプログラムに用いられる言語の多くはその言語自身で実装されています。Swiftのスローガンは⁠Safe, Fast & Expressive⁠ですが,自分自身を表現するというのは表現力を提示する最良の方法だけに,SwiftがSwiftで書かれていないことは物足りなく感じます。

総称関数が関数(オブジェクト)でない

システムプログラミングが「下」に対する不満なら,⁠上」に対する不満ももちろんあります。筆者の一番のそれは,Swiftのジェネリクス(generics)です。

本連載でも以前指摘したとおり,Swiftの関数(function)は第一級オブジェクト(first-class object)ですが,総称関数(generic function)はそうではありません。

たとえば,

func idInt(_ i:Int)->Int{ return i }

と,

let idInt = { (i:Int)->Int in i }

let idInt:(Int)->Int{ i in i }

let idInt:(Int)->Int{ $0 }

は等価で,

var f = idInt
f(42) // 42

と変数に代入することも可能ですが,

func id<T>(_ a:T)->T {
    return a
}

に,

let id = <T>{ (i:T)->T in i }

let id<T>:(T)->T { i in i }

let id<T>:(T)->T { $0 }

という表現はありえず,もちろん,

var f = id

とは書けません。Swiftが静的型言語である以上これは仕方がないことで,嫌ならJavaScriptなど動的言語を使えばいいと思われるかもしれませんが,ちょっと待った!

それができる静的型言語はすでに存在するのです。それもSwiftの先輩言語に。

著者プロフィール

小飼弾(こがいだん)

1969年生まれ,東京都出身。元ライブドア取締役の肩書きよりも,最近はPokemon GOのガチトレーナーのほうが有名になりつつある……かもしれない永遠のエンジニアオヤジ。

活躍の場はIT業界だけでなく,サブカルからアカデミックまで多方面にわたり,ネットからの情報発信は気の向くまま毎日毎秒! https://twitter.com/dankogai,ニコニコチャンネルは,http://ch.nicovideo.jp/dankogai,blogはhttp://blog.livedoor.jp/dankogai/

当社刊行書籍は『小飼弾のアルファギークに逢ってきた』『小飼弾のコードなエッセイ』など。他にも著書多数。