WIP:俺言語3
概要
インクリメンタルに開発
一般的な文法っぽいけど、Lisp のようなマクロができる
俺言語2ではオブジェクト指向だったが、総称関数でチャレンジする
構文
code:text
# 関数呼び出し
add 1 2
[add
1
2]
# 関数定義
fn add x y {}
fn add x: Int y: Int -> Int {}
fn hoge x: Int = 1 {}
fn hoge x:: 1 {}
# 関数型定義
Fn Int Int -> Int
# ラムダ式定義
lm x y {add x y}
lm x Int y Int -> Int {}
@[x y ->
add x y
add it 3
]
# ラベル定義
name = 1
name: Int = 1
# 配列定義(型注釈あり)
ArrayInt 1 2
# 配列定義マクロ
# 配列の便利なやつ
# 配列が引数の関数定義
result = Array Int
each x [lm value Int index Int -> Int {
}]
return result
}
ジェネリクスないとしんどい
ジェネリクス入れると構文が複雑になってLispできない
静的型は諦めて、動的型に振り切る
# 配列が引数の関数定義2
fn map x: Arr callback: Fn -> Arr {
each x [lm value index {
}]
return result
}
レコード型定義
def_record User {
address Str
age Int
}
new_record User {
address "Tokyo"
age 19
}
# 型をユーザー定義
module Set {
fn new type: Type -> T {}
fn new args:Args -> T {}
}
fn add x: Set.T y: Set.T
add x y
# ユーザー型定義2
Set = Type type: Type {
Type args: Args {
each args @[x -> set data hash x x] return data
}
}
# ユーザー型定義3
Set = new Type
fn new type:: Set t: Type {
new Hash Int t
}
fn set data: Set value {
}
# ユーザー型定義4
type Set {
constructor args: Args {
data = Hash
each args { x . set data hash x x} return data
}
set self: Self value {
}
}
# ユーザー型定義5
Set = new Type Hash
fn new type:: Set {
}
fn set data: Set value {
d = downcast data
return data
}
inherit Set show
s = new Set
set s 1
set s 2
# ユーザー型定義5(レコード版)
普通のレコード
User = new Record name age
new User name "keke" age 124
MyList = new Record list size
fn new type:: MyList {
new MyList list [] size 0
}
# 型情報はラベル(コンパイル時)とデータ(実行時)の両方で持つ
# ディスパッチ優先順は型の詳細順
Type は詳細度 0
Int は詳細度 1
Array は詳細度 1
Record は詳細度 1
Fn は詳細度 1
# ディスパッチ優先順。どちらが呼ばれるのか?
左優先、はやめたい
定義できないようにするか?検知できるのか?
julia はエラーが出るようにしてた。実行時だったかな?
julia が色々参考になりそう。ていうか julia で良くない?
サブタイピングもありかも
引数の型を Set 入れて比較すれば検知できそう(ダメ)
ダメ