はじめに
Kinx v1.0.0 を正式にリリースしました! やっとプレリリース卒業です。実は1~2週間前くらいにリリースしてたのですが、あまりアピールしてなかったので書きました。Kinx の Release Pageをご覧ください。
さて、「見た目は JavaScript、頭脳(中身)は Ruby、(安定感は AC/DC)」 でお届けしているスクリプト言語 Kinx。 Kinx v1.0.0 は、プロジェクト開始から開発されたすべての機能を含む第1回目の公式リリースバージョンとなります。
- 参考
- 最初の動機 ... スクリプト言語 KINX(ご紹介)
- 個別記事へのリンクは全てここに集約してあります。
- リポジトリ ... https://github.com/Kray-G/kinx
- Pull Request 等お待ちしております。
- 最初の動機 ... スクリプト言語 KINX(ご紹介)
ちなみにこれは秘密なのですが、次の目標はGitHubでのシンタックスハイライトです。Kinx が何百ものリポジトリで使われていることが一つの基準になっているようなので、非常に厳しいですね。誰か Kinx を使ったリポジトリを作成してくれる人いないかなー。
Kinx ちょっとしたご紹介
コンセプト
コンセプトは "「見た目は JavaScript、頭脳(中身)は Ruby、(安定感は AC/DC)」" です。いや、リポジトリ上は "Looks like JavaScript, feels like Ruby, and it is a script language fitting in C programmers." (JavaScript のように見え、Ruby のように感じられ、C プログラマにぴったり)なんですけど。
- 見た目は JavaScript ... C ライクな構文のスクリプト。
- 頭脳(中身)は Ruby ... プログラミングを楽しみましょう。Enjoy!
- (安定感は AC/DC) ... どうでもいいですね。
ここでいう "C ライクな構文" とか "C プログラマにぴったり(fitting in C programmers)" とかは比喩で、それぞれ「使い慣れた(見慣れた)構文」とか「多くのプログラマにぴったり」といった意味で使ってます。なんだかんだ言って、大概のプログラマは多かれ少なかれ C を使っているか、もしくは少なくとも知識として知ってはいるでしょう、ということで。
主な特徴
主な特徴は以下の通り。
- 動的型付け言語 で、オブジェクト指向プログラミング 言語です。
- クラス と継承、高階関数、レキシカルスコープ、クロージャ、ファイバー、ガベージコレクション、等々。
- native キーワードによる JIT コンパイル。制限はありますが高速です。
- 便利なライブラリを オールインワン で提供。
ライブラリ
オールインワンで提供されるライブラリは以下の通り。
- Zip ... ZIPパスワードだけでなく、AESパスワードを使って ZIP/Unzip が可能。
- Xml ... XML DOM をサポート。
- libCurl ... HTTP のみ実装済です。(もっと色々できるはずだが)
- SSH ... SSH ログインしてコマンドを実行することができます。
- Socket ... シンプルな TCP/UDP ソケット。
- Iconv ... テキスト・エンコーディング変換。
- SQLite3 ... SQLite3 を利用する便利な Database クラス。
- Regular Expression ... 正規表現ももちろんサポート。
-
Parser Combinator ...
Parsec
のようなParsek
という名前のパーサコンビネータ。 - PDF ... HaruPDF ベースの PDF コアライブラリ。
- JIT ... 抽象化アセンブラ・ライブラリによる、様々なプラットフォームで使用可能な JIT ライブラリ。
インストール
Windows/Linux
Releases ページからインストーラをダウンロードできます。
Scoop (for Windows)
もしくは Windows であれば Scoop を使ったインストールが可能です。
# scoop bucket add is needed only at the first time.
scoop bucket add kinx https://github.com/Kray-G/kinx
scoop install kinx
実行方法
kinx
または kinx.exe
へのパスを確認し、以下のように実行します。
# For Windows
$ kinx.exe [options] [<script-file>]
# For Linux
$ kinx [options] [<script-file>]
仕様
だいたいできてる感のある仕様は以下の通りです(英語ですが...)。リリース後に無いなーと思った doc は Issues に上げました。。。
最近実装したものは含まれていませんが、以下に Qiita に投稿した各種記事へのリンクがまとまっています。紹介記事からもリンクがありますが、基礎文法最速マスターも書いたので一応。ただし、パイプライン演算子とかは実装前なので、最新にはなってません(いつか直すかも)。
例
リポジトリにもサンプルは多く入れてありますが、特徴的なものだけご紹介。
hello, world.
誰もが最初に書くスクリプトです。
System.println("hello, world.");
Fibonacci
見た目は JavaScript。
function fib(n) {
if (n < 3) return n;
return fib(n-2) + fib(n-1);
}
System.println("fib(34) = ", fib(34));
Fibonacci in native
function
を native
に変えるだけで速くなります。
native fib(n) {
if (n < 3) return n;
return fib(n-2) + fib(n-1);
}
System.println("fib(34) = ", fib(34));
Closure
レキシカルスコープとクロージャ。
function newCounter() {
var i = 0; // a lexical variable.
return function() { // an anonymous function.
++i; // a reference to a lexical variable.
return i;
};
}
var c1 = newCounter();
System.println(c1()); // 1
System.println(c1()); // 2
System.println(c1()); // 3
System.println(c1()); // 4
System.println(c1()); // 5
Lambda
匿名関数の例。
function calc(x, y, func) {
return func(x, y);
}
System.println("add = " + calc(10, 2, { => _1 + _2 }));
System.println("sub = " + calc(10, 2, { => _1 - _2 }));
System.println("mul = " + calc(10, 2, { => _1 * _2 }));
System.println("div = " + calc(10, 2, { => _1 / _2 }));
// add = 12
// sub = 8
// mul = 20
// div = 5
Class
オブジェクト指向ですから。
class A {
var flag_ = false; // a local private variable.
public flagOn() {
@flagOnActual();
}
public flagOnActual() {
@flag = true; // a public variable.
}
}
var a = new A();
a.flagOn();
System.println(a.flag ? "true" : "false"); // => true
Module
後付けで機能をクラスにミックスインできます。
module M {
public method1() {
System.println("This is a method1");
}
}
class A {
mixin M;
}
new A().method1(); // => This is a method1
Fiber
ファイバーも使えます。
var fiber = new Fiber {
System.println("fiber 1");
yield;
System.println("fiber 2");
};
System.println("main 1");
fiber.resume();
System.println("main 2");
fiber.resume();
System.println("main 3");
// main 1
// fiber 1
// main 2
// fiber 2
// main 3
Spread/Rest Operator
ES6 で導入されたのが便利過ぎて入れました。色々な使い方はありますが、一つだけ。超便利。
function sample(a1, a2, ...a3) {
// a1 = 1
// a2 = 2
// a3 = [3, 4, 5]
}
sample(1, 2, 3, 4, 5);
Pattern Matching
パターンマッチでの代入も可能。宣言文や、関数の引数でも同じスタイルを使えます。
[a, b, , ...c] = [1, 2, 3, 4, 5, 6];
{ x, y } = { x: 20, y: { a: 30, b: 300 } };
{ x: d, y: { a: e, b: 300 } } = { x: 20, y: { a: 30, b: 300 } };
System.println("a = ", a);
System.println("b = ", b);
System.println("c = ", c);
System.println("d = ", d);
System.println("e = ", e);
System.println("x = ", x);
System.println("y = ", y);
// => .y.b requires 300, but it is 3 in actual.
{ x: d, y: { a: e, b: 300 } } = { x: 20, y: { a: 30, b: 3 } };
// a = 1
// b = 2
// c = [4, 5, 6]
// d = 20
// e = 30
// x = 20
// y = {"a":30,"b":300}
// Uncaught exception: No one catch the exception.
// NoMatchingPatternException: Pattern not matched
// Stack Trace Information:
// at <main-block>(test.kx:14)
Pipeline Operator
パイプライン演算子もサポートしましたよ。
function doubleSay(str) {
return "%{str}, %{str}";
}
function capitalize(str) {
return str.toUpper(0, 1);
}
function exclaim(str) {
return str + '!';
}
var result = exclaim(capitalize(doubleSay("hello")));
System.println(result); // => "Hello, hello!"
var result = "hello"
|> doubleSay
|> capitalize
|> exclaim;
System.println(result); // => "Hello, hello!"
Function Composition Operator
関数合成も可能です。JavaScript ではまだサポートされていませんね。
const double = &(n) => n * 2;
const increment = &(n) => n + 1;
// Normal case.
var r1 = double(increment(double(double(5)))); // 42
System.println(r1);
// Function composition operator is higher priority than a pipeline operator.
var r2 = 5 |> double +> double +> increment +> double; // 42
System.println(r2);
おわりに
やっと公式リリースしましたが、まだバグが残っていたり期待しない動作をしたりするかもしれません。ぜひぜひお試しいただいて、リポジトリ の Issues からご報告いただければ幸いです。
あと★つけてくれるとやる気出ます。GitHub Star が 100 超えたので、結構浮かれてます。
ではまた!