ハクソク

世界を動かす技術を、日本語で。

キップ:トルコ語の文法的格に基づくプログラミング言語

概要

Kip Kipは、トルコ語の文法格と母音調和を型システムに統合した実験的プログラミング言語
自然言語形態論と型理論の融合を目指した研究・教育プロジェクト
文法格による柔軟な引数順序やパターンマッチなど独自機能を搭載
インストールや実行方法、例題プログラム、構造・テスト方法も公開
今後も構文や挙動が変更される可能性が高い試験的プロジェクト

Kip Kip プログラミング言語概要

  • Kip Kipは、トルコ語の文法格(ismin halleri)と母音調和を型システムに活用する実験的言語
  • 自然言語の形態論とプログラミング言語設計の融合を追求する研究・教育目的プロジェクト
  • 本格的な実用言語ではなく、言語学と型理論の接点を探るための実験場
  • 英語・トルコ語のチュートリアルが用意され、言語の記述方法を学習可能
  • 構文・挙動は今後も変更されるため、安定性は未保証

言語の特徴

  • トルコ語文法格を型として利用
    • 名詞の格(例:yalın hal, -i hali, -e haliなど)が関数引数の関係性を決定
    • 例:accusative(-i hali)は「sayiyi」、dative(-e hali)は「sayıya」
  • 引数順序の柔軟性
    • 格や型が異なれば、引数の順序が入れ替わっても意味が通る
      • (5'le 3'ün farkını) yaz. と (3'ün 5'le farkını) yaz. は同じ意味
  • 代数的データ型の定義
    • トルコ語構文で自然数や真理値などの型を表現
      • 例:「Bir doğal-sayı ya sıfır ya da bir doğal-sayının ardılı olabilir.」
  • 多相型(ポリモーフィック型)
    • ジェネリックデータ構造を型変数で表現可能
      • 例:「Bir (öğe listesi) ya boş ya da bir öğenin bir öğe listesine eki olabilir.」
  • パターンマッチ(-sa/-se)
    • 条件接尾辞でパターンマッチを記述、ネストやワイルドカードにも対応
      • 例:「(bu doğruluğun) tersi, bu doğruysa, yanlış, yanlışsa, doğrudur.」
  • 定数定義(diyelim)
    • 「diyelim」で名前付き定数を定義
      • 例:「sıfırın ardılına bir diyelim.」
  • 入出力・効果表現
    • -ip/-ıp/-up/-üpでI/Oシーケンス、olarakで束縛
      • 例:「isim olarak okuyup, ("Merhaba "yla ismin birleşimini) yazmaktır.」
  • 組み込み型・演算
    • 整数(tam-sayı)、文字列(dizge)、入出力(yazmak/okumak)など

例題プログラム

  • ユーザーから数値を入力し、その数だけフィボナッチ数列を出力するサンプル
    • コメントは(* ... *)形式
    • 文法格付きリテラル(例:5'i yaz.)
    • パターンマッチや再帰を活用した関数定義

インストール方法

  • 前提ツール
    • Foma(有限状態形態素解析ツール)
      • macOS: brew install foma
      • Debian/Ubuntu: apt install foma libfoma-dev
      • Fedora: dnf install foma foma-devel
    • Stack(Haskellビルドツール)
      • haskellstack.org参照
  • ビルド手順
    • リポジトリをクローンし、install.shで一括インストール
      • chmod +x install.sh
      • ./install.sh
    • またはstack buildで手動ビルド
  • 実行方法
    • REPL起動: stack exec kip
    • ファイル実行: stack exec kip -- --exec path/to/file.kip
    • PATHへのインストール: stack install

WASM Playground

  • playground/ディレクトリにWASMビルド環境を用意
    • kip-playgroundをwasm32-wasi向けにコンパイル
    • HTML/JSラッパーでブラウザ上でKipを実行可能
    • 詳細はplayground/README.md参照

バイトコードキャッシュ

  • 各.kipファイルの型検査済みバイトコードを隣接する.izファイルにキャッシュ
    • ソースや依存が未変更なら.izを再利用
    • 強制再型検査には.izファイル削除
    • .izにはコンパイラハッシュを含み、バージョン変化時は自動無効化

プロジェクト構成

  • app/
    • Main.hs(CLIエントリポイント)
  • src/Kip/
    • AST.hs(構文木)、Cache.hs(キャッシュ)、Eval.hs(インタプリタ)、Parser.hs(構文解析)、Render.hs(整形出力)、TypeCheck.hs(型検査)
  • src/Language/
    • Foma.hs(Fomaバインディング)
  • lib/
    • giriş.kip(Prelude)、temel.kip(コア型)、temel-doğruluk.kip(ブール関数)、temel-dizge.kip(文字列関数)、temel-etki.kip(I/O)、temel-liste.kip(リスト関数)、temel-tam-sayı.kip(整数関数)
  • tests/
    • succeed/(成功テスト)、fail/(失敗テスト)
  • vendor/
    • trmorph.fst(TRmorphトランスデューサ)

テスト・検証

  • stack testで自動テスト実行
    • tests/succeed/は成功テスト
    • tests/fail/は失敗テスト

形態素解析と曖昧性対策

  • KipはTRmorphを用いてトルコ語形態素解析を実施
    • 解析結果が複数候補の場合、型検査時に解決
    • 明示的な解析指定にはアポストロフィを使用
      • 例:taka'sı(taka+所有格) vs takas'ı(takas+対格)

ライセンス

  • LICENSEファイルを参照

Hackerたちの意見

ハハ、カジュアルなトルコ語が少し読めるんだけど、これでめっちゃ楽しい気分になった!トルコ語の格システムがこんなにしっかりしてて標準化されてるからこそ、うまくいくんだよね。柔軟な引数の順序がこんなにうまく機能する言語、他に知らないな。
> 他の言語で柔軟な引数の順序がこんなにうまくいくのは知らないな。それってどれくらいのサンプルサイズなの?ケースシステムと柔軟な引数の順序はほぼ同じことだよ。英語でも柔軟な引数の順序は強い現象だしね。1. マスタード大佐は5時に自分のナイフで彼を研究室で殺した。2. マスタード大佐は5時に研究室で彼を殺した。3. マスタード大佐は研究室で自分のナイフで彼を5時に殺した。4. マスタード大佐は自分のナイフで5時に研究室で彼を殺した。5. マスタード大佐は5時に自分のナイフで研究室で彼を殺した。6. マスタード大佐は研究室で自分のナイフで5時に彼を殺した。もし他の言語を見たいなら、有名なラテン語の詩があって「Quis multa gracilis te puer in rosa perfusus liquidis urget odoribus grato, Pyrrha, sub antro?」って始まるんだ。これをできるだけ直訳すると、「何の細い少年が液体の香りに浸されて、あなたを多くのバラの中で押しつけるのか、ピュラ、心地よい洞窟の下で?」ってなるよ。ちなみに、ここでの単語の並びは「何の多くの細い君の少年がバラの中で液体の香りに浸されて押しつける、ピュラ、洞窟の下で?」って感じ。ロシアの詩も同じように複雑な語順があるって聞いたことがあるよ。
> 他の言語で柔軟な引数の順序がこんなにうまく機能するのは知らないな。高度に屈折した言語にはそういう特性があるよね。スラブ語やサンスクリット語(もっと広く言えばインド・アーリア語)がその代表例だと思う。フィンランド語やハンガリー語を話す人も似たようなことを言うんじゃないかな。
先入観を持ってリンクをクリックしたら、定義がすごく分かりやすくてクリーンだった!ドイツ語版もあったらいいな、笑えると思う。
うん。既存の言語(たいていはRust)でキーワードがトルコ語に置き換えられてるのを期待してたけど、実際にはすごくいい感じだね。
言語そのものとは関係ないけど、文法について: https://languagelog.ldc.upenn.edu/nll/?p=73
特にワクワクした!数年前に似たようなアイデアを試してみたから: https://github.com/celaleddin/sembolik-fikir これについては今後さらに調べてみるね。シェアしてくれてありがとう!
それ、めっちゃクールだね!私が見た感じ、接尾辞に基づいて形態素的な推測をしてるみたい。アポストロフィがなかったら、曖昧さの問題が出てくる(例えば「aşı」、ワクチンの意味か、目的格の「aş」の意味か?)けど、アポストロフィがその問題も解決してるんだ。Kipではこの問題をTRmorphを使って形態素解析を徹底して、タイプチェックや詳述で曖昧さを解消することで解決したよ。(だからKipではほとんどアポストロフィが必要ない。)それが価値があったかは分からないけど、解決するのは楽しい問題だったよ。 :)
みんな、こんにちは!Kipの開発者です!プロジェクトについてもっと投稿するのは、プレイグラウンドとランディングページが完成するまで待とうと思ってたんだけど、今のところのブラウザベースのプレイグラウンドを紹介するね(Alperen Kelesのおかげで)言語を試してみたい人はここからどうぞ: https://alpaylan.github.io/kip/ (JavaScriptのトランスピレーションの作業は今日始まったばかりで、今は動かないけど、言語を実行するのは大体うまくいくはず。ただしバグがあるかもしれないから、リポジトリの問題で教えてもらえると嬉しい!)
素晴らしい仕事だね!ずっと探求したいと思ってた分野だ。
ごめん!あまりにも美しかったからシェアせずにはいられなかった。でも、準備が整ったらHNに投稿できると思うよ。
いくつかの構文について質問があるんだけど、面白いアイデアだと思う。セキュリティの観点からも、隠すことで安全になるってのはいいよね。これって本当にコードなの?でも、数字の部分についてだけど、例えば「(5'le 3'ün farkını) yaz. (3'ün 5'le farkını) yaz.」って書いたら、どうやって5 - 3 = 2なのか、3 - 5 = -2なのかを判断するの?「farkını」の意味や「'le」と「'ün」の位置で、いつも2を返すのかな?つまり、(5が最初、3が2番目、差)を書くのと、(3が2番目、5が最初、差)を書くのとで違うの?グーグルで調べたら「5と3の差を書け」とか「3と5の差を書け」って返ってきた。トルコ語にはあまり詳しくないけど、翻訳を使ってなんとか理解した感じ。数学の定理を定義するための言語みたいに見えるね。「ゼロの次は1、1の次は2」みたいな。自然言語を使った書き方の特徴なのかな?
「Kip(トルコ語で「文法的ムード」を意味する)」って言葉、文法的ムードが何かよくわからないから、いくつかの翻訳サービスを試してみたら、kip == "mode"って出た。でも、Googleは「modal」「paradigm」「tense」「module」も出してた。私的には「tense」がいいかな。ただ、英語では「tense」にはいくつかの意味があるからややこしいよね!ここでは動詞の時制について話してると思うけど:https://www.bbc.co.uk/bitesize/articles/zh4thbk#zyh2s82 時制は感情とも同義で使われることもあるし、緊張や緊密さを表すこともあるよ。
トルコ語を数年間勉強してたけど、文法的・膠着的な特徴から面白いプログラミング言語になりそうだなって思ってた。Çって名前を付けようと思ってたけど、実際に作るつもりはなかったんだ。誰かがやってくれて嬉しいな!
そういえば、更新されたウェブページとプレイグラウンドがあるよ: https://kip-dili.github.io/
わぁ、これめっちゃすごい!ちょっと見てみないと!考えが好きだな、私も https://logicaffeine.com/studio で似たようなことやってるよ。Logos langもチェックしてみて、いつか話せたらいいな。Haskellを選んだのもいいね!
ある年代の人はLingua::Romana::Perligataを覚えてるかもね:https://metacpan.org/dist/Lingua-Romana-Perligata/view/lib/L...
彼女がトルコ人だから、言語を学んでるんだ。今はプログラミングの頭を使って、学習を加速させられる!すごい!
うん、これは自分が想像してなかったスキルの組み合わせだな。(トルコ人と結婚してる)。中級の壁を乗り越えるいい理由かもね。
親の構造の順序はまだアングロサクソン文法に従っているみたいだけど、行やファリサイ派はトルコ語だね。こんな感じのものが見てみたいな: Fibonacci-Dizisi (n): nが0なら: 停止。そうでなければ: この数を表示。次の数を、(この数 + 次の数)、(n - 1)でFibonacci-Dizisiに続ける。メインフロー: "数を入力してください: "を表示。入力を読み取る -> 入力。入力の整数部分: なければ: "無効な数"を表示。あれば (n): 0, 1でFibonacci-Dizisiを開始。開始: メインフロー。とはいえ、いいスタートだね、おめでとう。
AIのおかげで、どの国でも独自の民族言語伝統を反映したプログラミング言語に開発を移行できるようになったね。すごく力強いことだと思う。