作りたいあるいは欲しいプログラミング言語
思いついた順に書いてく
あと途中cf.とかついてるのはなんとなく思い出したものとか
あとhowmのメモからコピペしただけなのでレイアウト崩れてるかもしれないけど気にしない
それと話があんまり具体的じゃないっていうかまぁなんか垂れ流してるだけです
テンションが完全に深夜なので読み流してください
あとこの記事は随時追加予定です
- 関数は入れ子にできる。
- {}でくくるとスコープを作りだせる。
- Schemeのマクロ
- 実行形式にできる cf. Perl - PAR, Ruby - Exerb, Python - py2exe
- でかい数値計算も誤差なくできる(GMP)
- 実行時にオブジェクトの型情報やメソッド名を参照できる。 cf. C++ - RTTI
- 他の言語の恩恵(ライブラリとか単純に実行時の速度だとか)を受けられるようにする。 cf. Perl - XS, Perl - Inline::*
- 変数にアクセスする時に挙動を決定できる(Perlのtieみたいな)機能を持つ
- アスペクト指向プログラミング
- 並列プログラミング(Thread, Fiber, Actor等)
- 型の違いはコンパイル時にわかる
- スクリプト言語としても実行可能
- シンボルテーブル cf. Perl
- スタックを消費しない呼び出し cf. Perl - goto &SUBNAME
- スコープを細かく指定出来る
- スコープを抜けた瞬間になんらかのアクションが出来る cf. C++ - デストラクタ, Perl - local
- raw文字列 cf. python, C#
- ダックタイピング cf. LL言語, C++ - template
- メタプログラミング
- メタプログラミングとかアスペクト指向プログラミングを特別な文法ややり方で実現するのではなくてPerlのオブジェクト指向みたいに既存のアイデアのみで実現できるのがいい
- LL言語だったらコンパイル時の操作と動的な操作が分けられる cf. Perl - BUILD {}
- 動的に(スクリプトから)構文木を生成できる?
- 数字の間に_を含めていい
- LL言語であってもそうじゃなくても、また両方のハイブリッド言語であっても、メソッドが自身に対して破壊的なメソッドであるかをメソッド名に明治的に含めるようにした方がいいと思う(SchemeやRubyの!みたいな感じで)
- 自身の構文を解析できる機能
- C++のoperatorや他言語のパターンマッチと呼ばれる機能(再帰的に適用できる)
pythonのスライス構文をこんな感じに書ける
(もっといい構文があるはずだけど)
operator[a(:b(:c)?)?]
BNF記法など既存の構文を流用
なるべく新しい構文は作らない
- リテラルとそうでないものを平等に扱う
例えばPerlで
use strict;
このstrictはリテラルでもそうでないものでもなくて「use文」の引数。
構文(?)を新たに追加するより、Schemeのように全て平等に式を扱えるような仕組みにしたい。
(Gaucheの(use srfi-1)のsrfi-1はシンボル?というかuseってマクロだっけ?)
# これはさすがに厳しいか・・・
- Perlのコンテキスト
- ポインタ(リファレンス)
- リファレンス
Cならman
Perlならperldoc(エラーメッセージも調べられる)
- ifやwhileは制御構文じゃない
ifは最後に評価した値を返すなどする。
組込み関数あるいはマクロはどこかのネームスペースに保存されている。
- {}でクロージャを作る
上のと一緒に思いついたやつ。
ifやwhileは制御構文じゃなくてマクロ。自分でも作れる。
# if EXPR BLOCK # # これは紛らわしいのでできない? # if n == 1 say "foo" if n == 1 { val foo = "foo" say foo }
# while EXPR BLOCK var i = 0 while i < 5 { say "foo" i++; } # C/C++でもできるやつ i = 0 var j = 5 while i++, j-- { say "foo" }
ブロックの両サイドのカンマは付けなくていい。
Q. 引数取りたい時どうするの?
A. Rubyのブロック構文みたくすればいい
マクロ定義する時はmacroを使う。
もちろんこれも自分で(ry
リテラル型(Literal)っていうのがあればいいと思う。
PerlのPPIモジュールみたいにソースコードを文書として見て、
マクロの場合返り値としてマクロ展開したソースコードを返す。
あとスクリプト全体の構文木を返すものなんかもあれば面白い。
# ifと(...)の間に空白がなかった場合組込みのmacroはエラーになる? # (そうした方が楽な気が・・・いやでも最初の単語を抜き出すだけだし楽か) # # いやその前にmacroがマクロ展開する前にパーサが(と)と # その間にある文字列を抜き出して一つのLiteral型のインスタンスとして # 扱った方がいいだろjk macro if(...) { # スコープ内でこれらの単語が出てきたらこれを使う # using qw(CORE.if ErrorMessage.syntax_error) # 可変長引数は配列としてなんらかの変数に保存される # ここではthis.args(thisってなに?) apply CORE.if, this.args # ちからつきた # else対応してないし恐ろしく適当 #| if this.args.first.type == Function.type { croak syntax_error % (args[0].line, "first arg is not function") } # iはLiteral型 # ここでevalすると元の環境とは違った結果になることも考えられる # evalメンバ関数は元の環境で評価されたのと同じ結果になるようにする? # でもこの環境で評価したい時もあるかもしれない if this.args.grep { _.type != Function.type }.map { _.eval }.last { this.args.last.eval } else { undef } # なんだか劣化Rubyみたくなっててうける |# }
Literal型は
ソースコード内での行
それぞれの型のID全て(型.typeで取れるもの)
などの情報を持つ。
関数はfunctionじゃ長いのでfn。
# 戻り値は自動的に決まる # (決められるんだろうか) # それか戻り値はやっぱりLLみたく「なんでもあり」にすればいいか fn foo() { "foo" } fn bar() { "bar" }
こうすることでSchemeほどじゃないけどある程度「統一した」書き方ができるような気がする。
いろいろ
- Perlはsigilがあるおかげで予約語を意識せず変数名付けられるのは良いと思う($if = 1)
- ていうか読み易いのとできるだけ短く書きたいっていう両方の要求を満たすのは難しいと思う
- printはprint、printlnはsay
- さくっと書くためには標準で備わってる関数とかちょっとした機能がいっぱいあったほうがなんだかんだ言って得? cf. Perl - perldoc perlvar
- 記号はどこまでメソッドとして定義できればいいだろうか「.」とか「()」は? cf. C++ - operator()(), C++ - operator,()
- 結局自分が欲しい言語は
Perlみたいに「なんでも」できて多数のライブラリを持ち Schemeのような美しさを持ち Cのように「なんでも」できて速くて JavaやC#のような移植性を持ち Erlangのように並列実行を得意とし Luaのように組込み用途にも使え 他の多数の言語で書かれたコードの再利用ができ 大人も子供もおねーさんも楽々使える、そんな言語
1 から 10 を それぞれ 表示
はなるべく短く、「_」などの記号を含まず全て小文字(Perlっぽく)
- ifとかwhileにendいらないのとかelse ifとかelseifあるいはelsifだとか そういう細かいことはとりあえずどうでもいい
- これらは全てマクロ標準関数あるいは標準マクロ(?)
- 括弧にも(, [, {, <とかいろいろあるしそれぞれに意味を持たせてみると面白いかも
- ++, ::, :::, ', :, @, $, %, etc...
- 可読性(ry
- Perlのqwやqqとかもマクロで実装
- それぞれの言語への変換とかできたらいいな
- 自分が言ったことをコードに変換とかできたらいいな
- 考えるの疲れてきたな