はじめに
こんにちは!日本CTO協会24卒アドベントカレンダー22日目を担当するnakadate00です。
本記事では、なでしこというプログラミング言語に触れつつ、日本語プログラミング言語を用いた命名についてお話ししたいと思います。
また、生成AIであるBoltを用いることで、言語学習の時間を短縮する試みも同時に行っていますので、そちらにも注目していただけると幸いです。
きっかけは命名に迷った経験
私は24卒で、エンジニアとしての経験はまだ浅いのですが、日々の業務で命名をどうすべきか迷うことが多々あります。
その都度、このドメインに適している英単語は何なのか、この機能を表現するための英単語は何にすればいいのか迷います。
つい先日も、「依頼」という言葉に対してrequest
かoffer
のどちらが適しているかをチームメンバーに相談しました。
リーダブルコードでも第2章で以下のように書かれています。
「名前に情報を詰め込む」には、明確な単語を選ばなければならない。「空虚な」単語は避けるべきだ
例えば、「get」はあまり明確な単語ではない。
ここで重要なのは、命名に必要なのは基礎となる英単語力や、ドメインごとに適切な英単語を選択するための業務知識であるということです。
そのような中、ドメイン駆動設計 モデリング/実装ガイドでは、ユビキタス言語の文脈で以下のように書かれていました。
ユビキタス言語における英語の有利さ
「会話でも、ドキュメントでも、コードでも」を実現するのに、英語はとても有利です。モデリングした言葉をそのままコードに落とせるからです。
残念ながら日本語でモデリングした言葉はそのままコードに落とすことはできないため、工夫が必要になります。代表的なものはだいたい次の3つに絞られます。
- 日本語と英語の対応を決めて変換する
- ローマ字表記でコーディングする
- 日本語でコーディングする
3つ目はなかなか大胆ですが、言語のサポートがあれば実現は可能です。
日本語と英語の対応を決めて変換するのが主流ではあるものの、日本語でコーディングができれば、英語への変換を一切行わずに、意味の損失や認識ずれの問題を解決できることになります。
そこで私は、「命名問題について日本語プログラミング言語が解決策になり得るのではないか?」と考えたのです。
日本語プログラミング言語について
私は今までPythonやPHP、Ruby on Rails、Goといった言語しか触れてこなかったため、日本語プログラミング言語について簡単に調査することから始めました。
代表的なものとして、「Mind」「プロデル」「なでしこ」「ドリトル」といった言語が挙げられます。
今回は、もともと触れてみたいと思っていた「なでしこ」を選びました。
日本語の語順を使用するか、分かち書きをするか、オブジェクト指向に対応するかなどで違いがあるとのこと1なので、機会があれば他の言語にも触れてみたいと思いました。
また、本記事では生成AIを用いようとしていたため、コードが正しく生成されるかどうかが懸念されました。
しかし、たまたまChatGPTとやりとりすることで「なでしこ」のコードを自動生成できている記事2を見つけたので、生成が可能であることを確認できたことも選択理由になります。
Boltについて
なでしこを選択したものの、知識が皆無だったので、本記事では生成AIに自分が指定したユースケースのコードを生成させることで、学習時間を短縮しようと考えました。
そこで利用したのが、Boltオープンソースリポジトリの上に構築される、Bolt.newです。
Bolt.new is an AI-powered web development agent that allows you to prompt, run, edit, and deploy full-stack applications directly from your browser—no local setup required.
Bolt.newはAIを搭載したウェブ開発エージェントで、ブラウザから直接フルスタックアプリケーションをプロンプト、実行、編集、デプロイすることができます。
Boltであれば、なでしこの知識がなくても、単純なコードの生成だけでなく、アプリケーションの構築まで容易にできると考えました。
実際にコードを生成した結果
初めに以下のプロンプトを投げました。
日本語プログラミング言語「なでしこ」でTodoアプリを作りたい。
まずは、タスクの一覧取得と、タスクの作成だけができるアプリケーションを作って欲しい。
すると、「なでしこを使いたいなら、なでしこ3を選択してください」という返答が返ってきました。この時点で、生成できそうだなという感触を得ていました。
申し訳ありませんが、WebContainerの環境では「なでしこ」プログラミング言語を直接実行することができません。WebContainerは主にJavaScript/Node.jsベースの環境で動作するため、なでしこの実行環境をセットアップすることができません。
代わりに以下のような選択肢をご提案させていただきます:
JavaScriptでTodoアプリを作成し、日本語のコメントや変数名を使用する
なでしこ3(JavaScript版)を使用する - これはなでしこの文法をJavaScriptで実装したバージョンです
どちらの方法がご希望でしょうか?
ということで、次は以下のように、なでしこ3を指定しつつ、Webアプリケーションという言葉をプロンプトに入れて投げました。
日本語プログラミング言語「なでしこ3」でTodoアプリを作りたい。
まずは、タスクの一覧取得と、タスクの作成だけができるWebアプリケーションを作って欲しい。
結果は以下のように、良い感じのコードとプレビューが確認できる状態で生成されました。
しかし、文字を入力して追加ボタンをクリックしても全く反応せず、タスクの一覧が表示されるはずの空白部分も変化はありませんでした。
これはコードがうまく生成できていないと感じたので、コードをエクスポートしてローカル環境で確認してみることにしました。
VSCodeの拡張機能があることも調査の段階で知っていたので、拡張機能を入れて、VSCodeで見てみると、めちゃくちゃ怒られていました。
DOM要素などの記法も公式サイトにありましたが、学習時間短縮の趣旨も考慮して、一度ここで区切りをつけようと思いました。
今回のプロンプトで、Todoアプリとしてタスクの一覧取得と作成を生成させたのは、Get
の部分の日本語での命名を確認したかったことと、アプリケーションとしてインタラクティブなものの方が視覚的にも分かりやすいと考えたからです。
結果として、プロンプトでタスクの一覧取得
、タスクの作成
と投げていますが、コードでは、取得
の他にも内容
、表示
、追加
、更新
といった単語が書かれていることが分かりました。
また、以下のように、タスク
、一覧
、取得
、作成
といった単語を使わずに、新しいチャットでプロンプトを投げるとどうなるか検証してみました。
日本語プログラミング言語「なでしこ3」でTodoアプリを作りたい。
まずは、することを全て持ってくるのと、することを作ることだけができるWebアプリケーションを作って欲しい。
すると、タスク
、取得
、内容
、表示
、追加
、更新
といった先ほどの結果と同じ単語のみが使われていました。
これらの結果から、少なくともBoltでの生成においては、決められた単語だけで処理の内容や機能の記述を使い分けできているように感じました。
こちらが投げた「一覧」「作成」といった単語は使われていないことからも、「取得」「内容」「表示」「追加」「更新」も表記ゆれによるものではなく、意図した使い分けをしていると考えられます。
つまり、機能を示す命名については、私たちが普段コードを説明するときに使う単語で表現できるということです。
私が感じた印象としては、コードコメントに書かれていることがそのままプログラムになっているというものでした。
さいごに
この結果から私は、日本語プログラミング言語によって、命名に迷う問題が軽減できるケースもあるのではないかと思いました。
それは、私たちが普段口にしている単語をそのままコードに落とし込むことができると感じたからです。
例えば、会話やドキュメントですでに「依頼」として共通認識が取れている場合は、依頼
をそのままコード内でも使うことができると考えられます。
また、今回は学習時間短縮の意味合いも兼ねて生成AIを利用しましたが、機会があれば公式サイトを熟読して、一から実装してみたいと思います。
なでしこ以外の日本語プログラミング言語についても触れてみたいです。
おまけ
VSCodeで確認したときに、文法が間違っていたことが分かったコードについて、ChatGPTに修正依頼を投げたところ、以下のように修正してもらいました。
以下のようにJavaScript形式で文法を修正します。このコードでは、同様の動作を維持しつつ、ブラウザで直接動作するJavaScriptとして書き直しています。
<!DOCTYPE html>
<html lang="ja">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>タスク管理アプリ</title>
<style>
body {
font-family: sans-serif;
margin: 2em;
}
.container {
max-width: 600px;
margin: 0 auto;
}
#taskList div {
margin-bottom: 0.5em;
padding: 0.5em;
border: 1px solid #ccc;
background-color: #f9f9f9;
}
</style>
</head>
<body>
<div class="container">
<h1>タスク管理アプリ</h1>
<div>
<input type="text" id="taskInput" placeholder="タスクを入力">
<button id="addTask">追加</button>
</div>
<div id="taskList"></div>
</div>
<script>
// グローバル変数の定義
const タスク一覧 = [];
// DOMの取得
const 追加ボタン = document.querySelector("#addTask");
const タスク入力 = document.querySelector("#taskInput");
const タスク表示 = document.querySelector("#taskList");
// タスク一覧更新関数
function タスク一覧更新() {
タスク表示.innerHTML = ""; // タスク表示エリアをクリア
タスク一覧.forEach((表示タスク) => {
const タスク要素 = document.createElement("div");
タスク要素.textContent = 表示タスク;
タスク表示.appendChild(タスク要素);
});
}
// タスク追加処理関数
function タスク追加処理() {
const タスク内容 = タスク入力.value.trim(); // 入力値を取得し、前後の空白を削除
if (タスク内容 === "") {
return; // 空なら処理を終了
}
タスク一覧.push(タスク内容); // タスクを配列に追加
タスク一覧更新(); // 表示を更新
タスク入力.value = ""; // 入力欄をクリア
}
// イベントの設定
追加ボタン.addEventListener("click", タスク追加処理);
// 初期表示
タスク一覧更新();
</script>
</body>
</html>