2026年4月5日日曜日

💎J言語を極める j言語faq

 変数がどのように宣言されるかを知り、条件式とループの構文を学び、関数の呼び出し方を学び、編集する例をいくつか手に入れれば、あなたはコーダーだ。 ふざけやがって! Jでは、宣言はないし、ループを目にすることはめったにない。 例題からコーディングすることに関しては、私たちの例題のほとんどは2、3行のコードに過ぎない! 歯を食いしばって、まったく新しいプログラムの書き方を学ぶしかないのだ。

https://www.jsoftware.com/help/jforc/foreword.htm#_Toc191734286

PRI:Primer contents

J言語はとても豊かな言語だ。何年も勉強して使っても、自分は初心者だと思うことができる。これは、ベーシックやJavaのような単純な言語が、数ヶ月の勉強と使用でエキスパートになれるのとは対照的である。Jプログラマーのエキスパートになるために必要な努力は、C++プログラマーのエキスパートになるために必要な努力に近い。

https://www.jsoftware.com/help/primer/why_j.htm

「-2」ではなく「_2」なので混乱するかもしれない。心配しないで、すぐに説明するから。

https://www.jsoftware.com/help/primer/experiment.htm

-は常に動詞である。このため、-が数字のすぐ左で使われる場合は特別なケースがないため、文の評価ルールが単純化される。しかし、-が常に動詞である場合、負の数を綴るには別の文字、_(アンダーバー)が必要になる。

https://www.jsoftware.com/help/primer/negative_number.htm

ダイアドとモナド

すべての動詞には2つの定義がある。左引数と右引数の両方を持つ場合に使われるダイアドと、右引数のみを持つ場合に使われるモナドである。この2つの定義は通常関連しており、「-」の定義が「マイナス」、「否定」の定義が「モナド」である。

https://www.jsoftware.com/help/primer/ambivalence.htm

覚えておこう:すべての動詞はモナドとダイアドの両方の定義を持っている。

ボキャブラリーの5行目の+の行を見てください。この行の最初の項目には + 活用 o Plus. この単語+は動詞で、そのモナドはconjugateと呼ばれ、そのダイアドはplusと呼ばれる。ダイアド+は算数で定義されるプラスである。

https://www.jsoftware.com/help/dictionary/d100.htm

動詞の左側に名詞がある場合、動詞は二単項式で実行されます。動詞の左側の名詞と右側の名詞が、動詞の x 引数と y 引数になります
動詞の左側に名詞がない場合、動詞は単項式で実行され、動詞の右側の名詞が y 引数になります
呼び出しのタイプは呼び出しの価 値と呼ばれ、モナド型かダイアド型かを表します。

https://code.jsoftware.com/wiki/Vocabulary/Verbs#Executing_an_Explicit_Definition:_Private_Namespaces

ランク

名詞のランクは、その軸の数です。原子のランクは 0、リストのランクは 1、表のランクは 2、5 つの軸を持つ配列のランクは 5 です。配列のランクは非常に重要で、動詞が配列に対してどのように作用するかを決定します。
配列の形状は、配列の軸と同じ数の数字を持つリストである。つまり、配列の形状のカウントが配列のランクとなる。

https://www.jsoftware.com/help/primer/rank.htm

Jのパワーの多くは、引数を一連の部分として扱う動詞の能力にある。動詞はそれぞれの部分に自らを適用して、一連の部分的な結果を作り出し、その部分的な結果を最終的な結果に組み立てます

https://www.jsoftware.com/help/primer/verb_arguments.htm

動詞にはランクがあり、それがどのように引数に適用されるかを決定する。ランクkのモナドは引数のk個のセルに適用される。左のランク kl と右のランク kr のダイアドは、左の引数の kl のセルと右の引数の kr のセルに適用されます。動詞のランクは、動詞の配列への適用方法を制御する強力な道具である。
原始動詞のランクはJ辞書の定義に示されている。例えば、 + の定義を見てください。ランク情報は、ヘッダーの単語の後にあります。の場合、これは 0 0 0 です。モナドのランクは0であり、モナド+が原子に適用されることを示す。ダイアド・ランクは、左の引数が0(アトム、つまり0セルに適用されることを示す)、右の引数が0(やはり右の引数のアトムに適用されることを示す)である。

https://www.jsoftware.com/help/primer/verb_rank.htm

副詞と接続詞

副詞は動詞と似ているが、以下の点で異なる:
副詞は左の引数のみを持つ(動詞は両義的で、右の引数または左と右の両方の引数を持つ)。
副詞は名詞または動詞に適用できる(動詞は名詞にのみ適用される)。
副詞は通常、その結果として動詞を持つ (動詞は常に名詞の結果を持つ)
副詞の動詞の結果は、派生動詞と呼ばれます。

原始的な / は副詞です。その結果は新しい動詞です。派生動詞のモナド格が使用される場合、/はinsertと呼ばれます。派生動詞のダイアド格が使われる場合、/はテーブルと呼ばれる。

https://www.jsoftware.com/help/primer/adverb.htm

接続詞は副詞に似ているが、左右両方の引数を取る点が異なる。ランク接続詞は以前のセクションで非公式に紹介した。さらに、摂氏のような動詞の定義に使われる : も接続詞として認識できるようになった。centigradeを定義する際、:は左引数に3、右引数に0を取る。ここまでは動詞の可能性もあるが、結果が動詞であることが接続詞であることを証明している。
接続詞の動詞の結果は派生動詞と呼ばれる。

https://www.jsoftware.com/help/primer/conjunction.htm

摂氏動詞は接続詞 : で明示的に定義された。明示的という用語は、定義における動詞の引数がx.とy.という名前によって明示的に参照されていることを示す。
暗黙の定義では、引数には名前がなく、定義に明示的に登場しない。引数は定義の構文要件によって暗黙的に参照される。あなたはすでにいくつかの暗黙の定義を使っている。

https://www.jsoftware.com/help/primer/tacit_definition.htm

接続詞「!:
は整数のスカラー左引数と右引数に適用され、動詞を生成する。
の場合は副詞を生成する。これらの動詞は、他の動詞と同じように振る舞います。動詞には名前を割り当てることができ、副詞や接続詞の引数として使用することができます。これらの動詞が引数として名前を取る場合、4!:55 'a';'bc' のように名前を枠で囲み、a と bc という名前を消す。括弧で囲まれた左の引数は省略可能であることを示す。

https://www.jsoftware.com/help/dictionary/xmain.htm

J for C Programmers

本書は、本格的なアプリケーションを開発するための言語としてJを使用するのに十分なJについて説明するが、J言語を学ぶこと以上に、プログラミングにおいて「大きく考える」こと、そしてJでのプログラミングがCでのプログラミングと根本的にどのように異なるかについて書かれている。Cのプログラムはスカラー(単一の数値や文字)を密接に扱い、それらのスカラーを配列や構造体にまとめる場合でも、配列や構造体に対する操作はスカラーに対する操作によって定義される。 配列の各項目を確実に操作するために、配列の各要素を訪れ、その要素に対してスカラー演算を実行するループが作られる。
スカラー言語でコードを書くと、部隊を一人一人訪問して耳元でささやきながら命令を下す将軍のようになる。 そのようなハリーに触れるような将軍のやり方は、勝利という結果を得ることができるし、命令をその人に合わせることができるという利点もある。 偉大なロンメルでさえ、時には過労に見舞われた。
それとは対照的に、Jプログラマーは軍隊の前に立ち、軍隊全体への命令をブチ上げる将軍である。 すべての兵士が同じ命令を受けるが、命令自体には個々の兵士が適切に行動するのに十分な詳細が含まれている。 このような将軍は、小隊と同じくらい簡単に軍団を指揮することができ、常に「全体像」を念頭に置いている。
さて、あなたはロンメルではないかもしれないが、現役のプログラマーであり、実用的なプログラムで配列演算として表現できるものはほとんどないのではないか--行列の乗算とか、数値のリストの加算とか--、また、仮に幅広いプログラムが可能だとしても、サポートされる演算のセットは実用的というには膨大すぎるのではないか--と疑っているのではないだろうか。
本書の前半は、配列操作を使って意味のあるプログラムを書くことが実際に可能であることを示すことに費やされている。 ループのさまざまな使われ方を見て、配列操作を使って同じ結果を得るためにJがどのような機能を持っているかを見ていくアプローチをとります。 Jには、数ダースの配列処理プリミティブと、それらのプリミティブを接続して、実用的なプログラミングに必要な配列処理関数を無限に提供することを可能にする、非常に巧妙に選択された1ダースほどの配管継手が含まれていることがわかるだろう。
より複雑な配列操作の説明の間に、実用的なプログラミングに必要な他の事柄、すなわち構造体の定義、入力と出力、性能測定、DLLの呼び出し、モジュール化されたプログラミングが挿入されている。 最終的には、Jでif-then-elseやdo-whileを使う方法を学ぶことになるが、同じ結果を得るためにもっとエレガントな方法を学ぶことになるだろう。
本書の最後の部分は、関数型プログラミングのためのJ言語である暗黙プログラミングのオプション・トピックに費やされている。 タシット・プログラミングはアルゴリズムを表現する極めて簡潔な方法であり、1ページのC言語から数行のJ言語に圧縮されたプログラムをさらに圧縮することを可能にするものである。

if文はどうなったのか?

プリミティブに組み込まれている。 ほとんどのループがプリミティブの中に隠されているように、ほとんどの条件文もプリミティブの中に隠されています。 あなたが書く関数も、組み込みの条件式を含むことができます。

文の区切り記号は何ですか?

ありません。 ステートメントは正確に1行の長さです。

Jのコードを見たことがある。 他の文字はすべてピリオドかコロンだ。 目の前にシミができた。 こんなの誰が読めるんだ?

そのうち慣れるよ。 Jには非常に多くのプリミティブがあり、1行に多くの計算を収められるように名前を短くすることが重要です。そのため、名前は>のような1文字か、ピリオドやコロンが付加された文字(>.) ピリオドやコロンは名前の一部に過ぎません。 i.のようにピリオド/コロンを付加した1文字もプリミティブに使用されます。 プリミティブに独自の名前を付けたい場合は許可されていますが、スペースとタイピングを節約するために、すぐに短い名前に戻りたくなるでしょう。

宣言はどこにあるのか? Jでは配列を使わないのですか? 変数の型を知るには?

そうそう、Jでは配列を使っている。 どんな変数でも配列になる。 型と次元が何であるかについては、あなたが変数を代入したのでしょう? あなたが変数に入れたもの、数値、文字列、配列、構造体...。 Jが覚えているだろう。 プログラム・ロジックで変数の現在の属性を調べる必要があれば、Jが教えてくれます。
プリミティブも、あなたが書いたプログラムも、すべてのJプログラムは自動的に配列に適用できる。 入念に考え抜かれたこの方法は、Jの長所のひとつである。
x + y
という文は、「xとyを足す」という意味であり、xとyが単数であっても、多次元配列であってもそうなる。 個々の数値を操作するために必要なループ処理は、プログラムではなく言語に組み込まれている。

Jのコードを一行見てみたが、構文もよくわからずぐちゃぐちゃだ。

例えば
lifodd =. ]`[@.(2&|@[)
おそらく、左オペランドが奇数なら左オペランドを返し、そうでなければ右オペランドを返すプログラムだろう?
忍耐。 すべての文字には意味があり、たとえ` " [ ] { }の文字であっても、ペアとしてではなく個々に動作する。 それらの意味を学べば、すべてが明らかになるだろう。

1 2 + 3。 余分な数字が空間に浮かんでいるのはなぜだろう?

1 2は、1と2の値を持つ2つの数値の1次元配列である。 Jでは配列がよく出てくるので、配列の要素の値以上の構文を必要とせずに、配列を定義するためにこの省略記法を使う。

あるJのコードを見てみたが、そこには変数がまったくない。 それが何を意味するのか?

ああ、あなたは暗黙のプログラムに出くわしてしまったのだ。暗黙のプログラムは、変数を参照することなく、記号的なパラメーターさえも使わずに計算を記述する。 古典的な教育例は
平均 =.
これは数値の配列の平均を求める。 暗黙のプログラムは本書では高度なトピックとみなし、巻末のセクションで取り上げている。 そのため、多くのJプログラマーはこれを好んで使うが、単純なJを学んでからでもよい。
例題の中で、あなたが代入文だと言った=:と=.を含む行しか見当たりません。 どうやってプログラムを書けばいいのですか?
代入文のいくつかはプログラムです。 Jでは、名前に関数の値を代入すると関数名になります。

プログラムを書いたら、どうやって実行するのですか? 関数呼び出しのようなものは見当たりません。

Jでは、関数呼び出しのための特別な構文はありません。 マイナス」関数を - y で、「引き算」関数を x - y で実行するのと同じように、ユーザー定義関数を呼び出すには、オペランドの前または間にその名前を入力します: x DifferenceSquared y または FindPrimeGreaterThan 1000。

プログラムはどのようにコンパイルするのですか?

コンパイルはしない。 J言語はインタプリタです。 プログラムを入力すれば(あるいはファイルから読み込めば)、すぐに使えるようになる。 ここにスターター・プログラムがある:
h =. 動詞 : '''Hello world.''
と入力し(三重引用符に注意)、それを
h ''

三重引用符は醜い。

腹を立てるのはやめよう。 この本を読めば、三重引用符を避ける方法がわかるだろう。 Cの10行をJの4分の1行で置き換えたことを思い出し、自分でその方法を学んでください。

数学でも使われる言葉をコンピュータ言語から奪う 関数は動詞になる

プログラミングの要素を説明するために、Jが使うのは、もしかしたら恐ろしいかもしれないが、なじみのある語彙、つまり英文法の語彙である。 名詞、動詞、そういったものを使って話をする。 読書感想文を書く必要はないのでご安心を!
この専門用語の使い方は、見た目ほど奇妙なものではない。 例えば、「動詞」はC言語の「関数」や「演算子」に相当する。 なぜ「演算子」と言わないのか? この単語は数学や物理学でも使われ、C言語とはまったく異なる意味を持つ。 Cの'関数'でさえ、真の数学的関数ではない。
Jでは、使い慣れた単語を選び、まったく新しい意味を与えることで、不正確な用法を避けている。 J言語は言語なので、選ばれた語彙は英文法のものである。 しかし、Jの意味さえ覚えれば、文法的な意味は忘れても構わない。

https://www.jsoftware.com/help/jforc/preliminaries.htm

動詞defineの結果は動詞であり、通常はその結果を名前に割り当てて、必要なときにその名前で動詞を実行できるようにする。 動詞defineの後の行から始まり、')'のみを含む次の行の前までが、動詞のテキストとして読み込まれ、保存されます()を省くと、天罰が下ります!)。 動詞は'コンパイル'されない--最も初歩的な構文チェックを行った後、テキストは保存され、動詞が実行されたときに解釈される。
動詞の各行は文(ステートメント)である。 最後に実行された文の結果が、動詞全体の結果となる(これは正確には正しくないが、今のところはこれに近い--詳細は「制御構造」で明らかになる)。
J動詞のオペランドは1つか2つしかないので、C言語の関数定義のようにパラメータ名のリストを提供する必要はありません。 動詞の実行開始時に、プライベート名yは動詞の右オペランドの値で初期化される。 動詞が二項演算の場合、プライベート名xは左オペランドの値で初期化される。 多くのプログラマーは、これらの値をより説明的な名前に代入して動詞を開始したがります。

特別な名前に関する注意

Jでは、動詞などの引数を表すためにx、y、u、v、m、nという名前を使用します。 これらの名前を他の目的で使用することは避けるべきです。