fluorite-7の
生まれた背景
九九表のCSVを出したい
こんなの
1,2,3,4,5,6,7,8,9
2,4,6,8,10,12,14,16,18
3,6,9,12,15,18,21,24,27
4,8,12,16,20,24,28,32,36
5,10,15,20,25,30,35,40,45
6,12,18,24,30,36,42,48,54
7,14,21,28,35,42,49,56,63
8,16,24,32,40,48,56,64,72
9,18,27,36,45,54,63,72,81
perl
こうか
$ perl -E 'for $a (1 .. 9) { say join(",", map { $a * $_ } 1 .. 9) }'
1,2,3,4,5,6,7,8,9
2,4,6,8,10,12,14,16,18
3,6,9,12,15,18,21,24,27
4,8,12,16,20,24,28,32,36
5,10,15,20,25,30,35,40,45
6,12,18,24,30,36,42,48,54
7,14,21,28,35,42,49,56,63
8,16,24,32,40,48,56,64,72
9,18,27,36,45,54,63,72,81
可読性もっとよくならないか
say join "\n", map { $a = $_;
join ",", map { $b = $_;
$a * $b
} 1 .. 9
} 1 .. 9
1から9までの各aにおいて、(
1から9までの各bにおいて、(
aとbの積
)を , で結合したもの
)を改行で結合したものを出す
(短さではなく)
数式(?)
1から9までの各aにおいて、(
1から9までの各bにおいて、(
aとbの積
)を , で結合したもの
)を改行で結合したものを出す
jq
こうか
$ jq -nr 'range(1; 10) as $a | [range(1; 10) | $a * .] | @csv'
1,2,3,4,5,6,7,8,9
2,4,6,8,10,12,14,16,18
3,6,9,12,15,18,21,24,27
4,8,12,16,20,24,28,32,36
5,10,15,20,25,30,35,40,45
6,12,18,24,30,36,42,48,54
7,14,21,28,35,42,49,56,63
8,16,24,32,40,48,56,64,72
9,18,27,36,45,54,63,72,81
長い・打ちにくい
perl -E 'say join "\n", map { $a = $_; join ",", map { $b = $_; $a * $b} 1 .. 9} 1 .. 9'
jq -nr 'range(1; 10) as $a | [range(1; 10) | $a * .] | @csv'
perlは範囲演算子が2文字で済む
$ perl -E 'say 1 .. 9 '
123456789
$ jq -n ' range(1; 10) '
1
2
3
4
5
6
7
8
9
頻出するので演算子でいいんじゃないかな
jqはmapが1文字で済む
$ perl -E 'say map { $_ * 10 } 1 .. 9 '
102030405060708090
$ jq -n 'range(1; 10) | . * 10'
10
20
30
40
50
60
70
80
90
頻出するので演算子でいいんじゃないかな
jqは自動的に改行つきでprintする
$ perl -E 'say 1'
1
$ jq -n '1'
1
値だけポンと置いて勝手に表示してくれた方が楽
こういうのでいい
a ∈ 1 .. 9 | [b ∈ 1 .. 9 | a * b]
- デフォで改行区切りで自動出力
-
var ∈ list | formula
=map { $var = $_; formula } @list
-
[
]
で囲むと,
区切りで横に並べる
イメージ
$ hoge 'a ∈ 1 .. 9 | [b ∈ 1 .. 9 | a * b]'
こういう言語無いか
面白そうだから作ろう(既にあると思うけど知らん)
## pegjs onlineで頑張る
成れの果て
$ hoge 'a ∈ 1 .. 9 | [b ∈ 1 .. 9 | a * b]'
↑理想 現実↓
$ fl7 'a : 1 .. 9 | [1 .. 9 | a * _]'
1,2,3,4,5,6,7,8,9
2,4,6,8,10,12,14,16,18
3,6,9,12,15,18,21,24,27
4,8,12,16,20,24,28,32,36
5,10,15,20,25,30,35,40,45
6,12,18,24,30,36,42,48,54
7,14,21,28,35,42,49,56,63
8,16,24,32,40,48,56,64,72
9,18,27,36,45,54,63,72,81
圧倒的短さ
node -e 'console.log(Array.from({length: 9}, (v, k) => k + 1).map(a =>
Array.from({length: 9}, (v, k) => k + 1).map(b => a * b).join(",")).join("\n"))'
perl -E 'say join "\n", map { $a = $_; join ",", map { $b = $_; $a * $b} 1 .. 9} 1 .. 9'
jq -nr 'range(1; 10) as $a | [range(1; 10) | $a * .] | @csv'
fl7 'a : 1 .. 9 | [1 .. 9 | a * _]'
極限低文字数アタックでなく、
その言語の標準的な書き方で短いのがポイント
こうしてこの言語は始まった
「ストリーマ」と「配列」
$ fl7 '1 .. 3'
1
2
3
$ fl7 '[1 .. 3]'
1,2,3
ストリーマは縦、配列は横
「パイプ」
$ fl7 'a : 1 .. 3 | a * 10'
10
20
30
$ fl7 '1 .. 3 | _ * 10'
10
20
30
左辺の各値について右辺を評価した結果を返す
変数名は明示しないと_
になる
「ストリーマ」と「配列」と「パイプ」
$ fl7 '1 .. 3 | [1 .. 3 | 5]'
5,5,5
5,5,5
5,5,5
$ fl7 'a : 1 .. 3 | [1 .. 3 | a * _]'
1,2,3
2,4,6
3,6,9
jqみたいに配列を溶かしたり凍らせたりして操作する
perlやjqみたいにリスト構造を主軸にしよう
(
)
は平坦になる
$ fl7 '1 .. 3, (4 .. 6), (7), ((8), 9)'
1
2
3
4
5
6
7
8
9
折角だから四則演算とか入れよう
$ fl7 ' 6 + 3, 6 - 3, 6 * 3, 6 / 3 '
9
3
18
2
$ fl7 ' 6 < 5 ? 100 : 10000 '
10000
$ fl7 ' 10 / 3, 10 `DIV` 3 '
3.3333333333333335
3
JSなので整数と小数の区別が苦手
折角だから関数作れるようにしよう
$ fl7 ' (a -> a * 10)(5) '
50
$ fl7 ' (a -> a(5))(a -> a * 10) '
50
$ fl7 ' (f -> n -> f(f)(n))(f -> n -> n == 0 ? 1 : n * f(f)(n - 1))(5) '
120
5! = 120
祝☆チューリング完全
折角だからjqみたいにJSON扱えるようにしよう
$ fl7 ' JSON({a : 5; b : [1 .. 4]}) '
{"a":5,"b":[1,2,3,4]}
$ echo '{"a":5,"b":[1,2,3,4]}' | fl7 ' FROM_JSON(&IN).b '
1,2,3,4
-
IN
= 1行ずつの文字列 - 前置
&
= 1個の文字列にする
折角だから変数作れるようにしよう
$ fl7 '
a : 11;
b : 6;
b = 5;
a * b
'
55
-
var : defaultValue
宣言 -
var = newValue
代入
折角だからクラス作れるようにしよう
$ fl7 '
Obj : {
new : class, val -> class {
val;
};
get_value : this -> this.val;
};
obj : Obj::new("Value!!!");
obj::get_value()
'
Value!!!
- クラスもオブジェクトも
{
}
で作る -
parent {
}
で継承つきオブジェクト -
obj::method(args)
=obj.method(obj; args)
文字列埋め込みとか
$ fl7 ' x : 567; "x = $x" '
x is 567
$ fl7 ' "pi = $%010.4f(PI)" '
pi = 00003.1416
偽ERB
$ fl7 ' %><ul>
<%= i : 1 .. 5 | %>
<li><%= i %></li>
<% %>
</ul><% '
<ul>
<li>1</li>
<li>2</li>
<li>3</li>
<li>4</li>
<li>5</li>
</ul>
制御構文
$ fl7 ' TRUE ? ( OUT("Yes"); ) : ( OUT("No"); ); '
Yes
$ fl7 ' 1 .. 3 | ( OUT(_); ); '
1
2
3
- 予約語などというつまらないものはない
- 定数はある
単位計算的なの
$ fl7 '
UNIT_h : a -> a * 60 * 60;
UNIT_m : a -> a * 60;
UNIT_s : a -> a;
(3h + 36m + 15s) / 1h
'
3.6041666666666665
クラスと演算子挙動上書き(演算子オーバーライド)を使えば
複雑な単位を持つ計算も簡潔に記述できる
外部プロセス
$ fl7 'EXEC("perl"; "-e", "print 11 * 7")'
77
$ fl7 'EXEC("perl"; "-e", "print 11 * <STDIN>"; "7")'
77
$ fl7 'EXEC("perl"; "-e", %>print $ENV{v} * <STDIN><%; "7"; {v : "11"})'
77
すべての外部プログラムはfl7から利用可能なライブラリだ!
怪文書
$ fl7 ' 1 .. 100 => GREP >> \(_ == 2 || !(i : 2 .. *SQRT | _ %% i)) => ARRAY '
2,3,5,7,11,13,17,19,23,29,31,37,41,43,47,53,59,61,67,71,73,79,83,89,97
$ fl7 '1~10|Fizz*!(_%3)&Buzz*!(_%5)||_ '
1
2
Fizz
4
Buzz
Fizz
7
8
Fizz
スクリプト言語化
$ echo '{定数 : 77777}' > lib.fl7
$ echo '@USE("lib.fl7"); "定数 is $定数"' > scr.fl7
$ fluorite7 scr.fl7
定数 is 77777
-
USE
でライブラリ読み込み - 前置
@
でインポート - 非ASCII文字は全部まとめてラテン文字扱い
オンラインエディタ
影響を受けた言語
- C Java JavaScript D
- Perl Ruby Raku Groovy
- jq bash Haskell
- hg Excel
やたら機能があるけど、「どこかで見たことのある演算子」が大半を占める
まとめ
まとめ
- fluorite-7は九九表を短く書ける創作プログラミング言語
- 混沌関数型言語
- 実用性は考えてない
リンク集
- fluorite-7 日本語チュートリアル
- オンラインエディタ
- カレントディレクトリにダウンロード
curl https://raw.githubusercontent.com/MirrgieRiana/fluorite-7/master/install.bash | bash