2. 言語の基礎要素
グリフ
グリフ(glyph)は1文字で関数やmodifierなどを表す、多くのプログラミング言語では出現しない表意文字を意味する1。 BQNでは一連のグリフ列が1トークンを構成することはない(常に1文字が1トークンとなる)。そのためグリフ間には空白文字を置く必要はない。
g ← "+-×÷⋆√⌊⌈∧∨¬|≤<>≥=≠≡≢⊣⊢⥊∾≍⋈↑↓↕«»⌽⍉/⍋⍒⊏⊑⊐⊒∊⍷⊔!˙˜∘○⊸⟜⌾⊘◶⎊⎉˘⚇¨⌜⍟⁼´˝`∞@π"
t ← "array"‿"number"‿"char"‿"func"‿"1-mod"‿"2-mod"
⍉t≍(≠⊸⋈)¨•type∘•BQN∘⋈¨⊸⊔∧g
┌─
╵ "array" ⟨ 0 ⟨⟩ ⟩
"number" ⟨ 2 "π∞" ⟩
"char" ⟨ 1 "@" ⟩
"func" ⟨ 44 "!+-/<=>|«¬»×÷↑↓↕∊√∧∨∾≍≠≡≢≤≥⊏⊐⊑⊒⊔⊢⊣⋆⋈⌈⌊⌽⍉⍋⍒⍷⥊" ⟩
"1-mod" ⟨ 9 "`¨´˘˙˜˝⁼⌜" ⟩
"2-mod" ⟨ 11 "∘⊘⊸⌾⍟⎉⎊○◶⚇⟜" ⟩
┘
定義を調べてないので,表意文字と言い切っていいのか自信はない。
型とatom
以下の型を持つ。他の配列指向言語と同様に enum
や struct
などのユーザ定義データ型は存在せず、配列のみで対象領域をモデル化することになる。
ただし名前空間を class のように使うことでオブジェクト指向的なプログラミングスタイルを取ることもできる2。
#3 | 型 | 備考 |
---|---|---|
0 | 配列 | CBQNでは使える次元(rank)は0から100(間違っているかも) |
1 | 数値 | 保持する値に応じた表現(CBQNではf64, i64, bool)を自動選択 |
2 | 文字 | Unicode code pointを採用。UTF-8ではないそうだ。 |
3 | 関数 | |
4 | 1-modifier | |
5 | 2-modifier | |
6 | 名前空間 |
配列以外の型を持つ値を atom と呼ぶ。
リテラル
-
文字定数の記法はちょっと変わっているので原典を参照のこと。エスケープ文字がないのでそのようなものが必要な文字はnull文字を表す'
@
'への加算で作り出さないといけない。 例えば、TAB =ctrl-I
は@+'I'¬'A'
または簡略化して@+9
となる。 -
数値リテラルとして以下の文字
- '
¯
' -- 負の数を表す。-
は減算または符号を反転を意味する関数としてのみ使用される - '
∞
' - '
π
'
が使えるので注意。 この3文字は数字の一種なので識別子の2文字目以降としても使えるので注意。
- '
識別子
- 識別子は大文字で始まると値のroleを持つ。
- 識別子が小文字で始まると関数のroleを持つ。
- 識別子がアンダースコア'
_
'列で始まり、アンダースコア'_
'列で終わらないなら1-modifierのroleを持つ。 - 識別子がアンダースコア'
_
'列で始まり、アンダースコア'_
'列で終わるなら2-modifierのroleを持つ。
roleは出現毎に選択できるのでf
は文脈さえ適切であればF
として参照できる。つまり f
とF
は同じものを指す。
さらに識別子中のアンダースコア '_
' は無視される。つまり以下のようになる。
a_b ← 1 # 変数 'a_b' の定義
1
a_b # これは当然
1
ab # 定義してないはずなのだが
1
aB # 定義してないはずなのだが
1
A_b # 関数のroleなのでは?? どう書くかよりも型が優先された??
1
ab____ # modifierに見えるが後置アンダースコアはroleには影響しないし無視される
1
_m2_ ← ○ # 2-modifier '_m2_' の定義
○
+ _m2_ + # これは当然
+○+
+ __m2__ + # 定義してないはずなのだが
+○+
+ ___m___2___ + # 定義してないはずなのだが
+○+
このことがわかってないと、名前空間を使う際に思いもかけないことになる。
ns_ ← {
s___ ⇐ 0
F___ ⇐ +
__m1 ⇐ ´
_m2_ ⇐ ⌾
}
{s‿f‿m1‿m2⇐}
関数適用
他の配列指向言語と同様に関数およびmodifierは1引数または2引数に限定される4。 関数適用は右結合なので自分より右のものを簡約し終わった値が関数の右引数𝕩の値となる。
私見だがこの制約はpoint-free coding styleと相性がいい。