あらためてSwiftを始めませんか?
本稿を執筆しているのは(とくに政治的に)波乱含みどころか波乱しかなかった感のある2016年末ですが、皆さんに届くころには新年気分も過ぎ、2017年という表記に読者の皆さんも慣れているころだと思います。新言語を学びはじめるにはちょうどいいころあいかと。
本連載はこれまで連載ということもあって、すでにSwiftという言語には本連載開始時点から慣れ親しんでいる読者を対象にしてきたのですが、本誌をはじめて手にとった方、つまり本誌にはある程度の理解はあるけれどもSwiftはまだ知らないという読者に向けて、Swiftとはどんな言語なのかを紹介するころあいでしょう。
安全、高速、豊かな表現力
いったいSwiftとはどういう言語なのでしょう? 公式サイトのAbout Swiftには3つの特長が掲げられています。
- 安全(Safe)
- 高速(Fast)
- 豊かな表現力(Expressive)
Swiftは静的型を採用していますが、これは安全性に寄与しています。たとえばvar i = 42
でInt
型として初期化されたものにi = "one"
とStringを代入しようとしても、コンパイル時にエラーとして弾きます。SwiftはCやC++やObjective-Cを置き換えることを標榜しているだけあって、同じことを同じように書いた場合、速度はそれらにまさるとも劣りません。それでいて、動的型を採用しているJavaScriptやPerlやPythonやRubyに匹敵する表現力を持ちます。動的言語のように速く書けて、静的言語のように速く実行できる。そのような言語はすべての言語デザイナの夢ですが、Swiftはその夢に最も近い言語だと筆者は感じています。
Getting Started
ではさっそくはじめてみましょう。え、Macなんて持ってない? ご安心を。Swift Sandboxのおかげで、今やSwiftはWebブラウザさえあればお試しできるのです(図1)。
もともとはApple製品専用開発言語としてスタートしたSwiftですが、オープンソース化にともない、MacだけでなくLinuxも公式にサポートされています。Linux版はWindows 10 Anniversary Editionに搭載されたLinux on Windowsでも動きます。本稿に限らず、本連載ではなるべくプラットフォームに依存しないように当初から心がけているので、本書の連載を理解するにあたってApple製品は必須ではありません。
とはいえ、Swiftの醍醐味をもっとも堪能できるのは、MacのXcodeということになります。とくにPlaygroundは現状Mac版とiPad版しか存在しません。Swiftを100%したかったら、やはりMacが第一選択肢となります。
演習:言語処理系を実装してみる
では、さっそく言語処理系を作ってみましょう。え、いきなりハードルが高い? 心配ご無用。ここで実装するのは、その言語でプログラムするよりその言語の処理系を書くほうが簡単と定評のあるBrainfuckです(図2)。リスト1はわずか36行ですが、それでも写経するのが面倒だというのであれば、gistにソースを用意しておきましたので利用ください。
リスト1を実行してみると、図3のとおりに標準出力されます。図3はMacの例ですが、Linuxでは最初のDarwin
がGlibc
になった以外同じものが出力されるはずです。
これをたとえばecho.swift
というテキストファイルにセーブしたうえで、次のようにシェルからコンパイルして実行してみます。
echo.swift
の中身がそのまま出力されれば成功です。
では処理系中の最後から2番目のsrc
を+++++++++[>++++++++>+++++++++++>+++++<<<-]>.>++.+++++++..+++.>-.------------.<++++++++.--------.+++.------.--------.>+.
にしたうえで、もう一度同じようにしてみてください。Hello, world!
と表示されましたか?
それではあらためて処理系のソースコードを見てみましょう。こんな小さなコードからでも、次のことが読み解けるはずです(表1)。
- 変数(
var
)や定数(let
)を定義するにはどうすればよいか
- 文字列中に変数を展開(interpolate)するにはどうすればよいか
- 型を指定すればどうなるか
- →指定しない場合はどうなるか?
- →
bf2swift:[Character:String]
の:[Character:String]
を消したらどんなエラーが出るか
- 辞書(Dictionary)をどう初期化してどう使うか
- 配列(Array)をどう初期化してどう使うか
- 文字列を1文字ごとに処理するにはどうすればよいか
- 既存のデータ型(String)にメソッドを追加するにはどうすればよいか(extension)
- アーキテクチャごとに処理を変えたい場合はどうすればよいか(#if)
表1 CとSwift実装比較
BF | C | Swift |
> | sp++; | sp += 1 |
< | sp--; | sp -= 1 |
+ | data[sp]++; | data[sp] += 1 |
- | data[sp]-- | data[sp] -= 1 |
[ | while(data[sp]){ | while data[sp] != CChar(0) { |
] | } | } |
. | putchar(data[sp]) | putchar(Int32(data[sp])) |
, | data[sp] = getchar() | data[sp] = {c in CChar(c < 0 ? 0 : c)}(getchar()) |
※ BF:Brainfuck
余裕があったら、次の課題にも挑戦してみてください。
- BrainfuckにはBrainfuck自身で書かれた処理系が存在するが、その処理系を本処理系で生成してみる
- 現状ソースコード中の
src
にハードコードされたBrainfuckコードではなく、任意のソースファイルをコンパイルできるようにしてみる
- Swift処理系をBrainfuckで実装してみる
最後はさすがに冗談ですが、ある言語で簡素な言語の処理系を実装するというのは、その言語を覚える一番の近道の1つ。さすがにBrain fuckほど簡単ではありませんが、Lispの実装などはなかなか楽しそうです。
では、今月はこのへんで。
- 第1特集
MySQL アプリ開発者の必修5科目
不意なトラブルに困らないためのRDB基礎知識
- 第2特集
「知りたい」「使いたい」「発信したい」をかなえる
OSSソースコードリーディングのススメ
- 特別企画
企業のシステムを支えるOSとエコシステムの全貌
[特別企画]Red Hat Enterprise Linux 9最新ガイド
- 短期連載
今さら聞けないSSH
[前編]リモートログインとコマンドの実行
- 短期連載
MySQLで学ぶ文字コード
[最終回]文字コードのハマりどころTips集
- 短期連載
新生「Ansible」徹底解説
[4]Playbookの実行環境(基礎編)