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