---
# System prepended metadata

title: 自作言語 案

---

# 自作言語 案

## 構文

### 方針

- Python に寄せた構文
- 記号はあまり使わない
- インデントはタブ
- インデントによるブロックは**必ず**その前の行の最後が `:`
- インデントは次の場合にしか使わない
	- ブロック
	- 一つの式を複数行にわたって記述する
	- この場合改行 + それ以降の式は 1 インデント
- 記号ではなくなるべく文字を使う
- パターンマッチのパターンにできるものは大文字、それ以外は小文字
- 多相バリアント

### コメント

```=
# コメント
#- 
複数行
-#
```

### ラムダ式

```=
f: Int -> Int
f = lambda(x): 
	x + 1

//同値
f: Int -> Int
def f(x): 
	x + 1 
```

複数引数のラムダ式

```=
f: Int -> Int -> Int
f = lambda(x, y): 
	x + y

f: Int -> Int -> Int
def f(x, y): 
	x + y
```

自動でカリー化される
上のは下と同値

```=
f = lambda(x): lambda(y): x + y;

f: Int -> Int -> Int
def f(x):
	lambda(y): x + y;
```

### let ブロック

def, lambda 式で使える
return の右の式が帰る

```=
def f(x):
	y = 2
	return x + y
  
f = lambda(x):
	y = 2
	return x + y
```

また、let ブロックとしても使える

```
x : Int = let:
	y = 2
	z = 3
	return y + z
```

### Context

context 文で async await 的なことが出来る

```=
main : Context (EFF Void) Unit
main = context:
	log("Hello World")     # log : forall a op. Show a => a -> Context (EFF op) Unit
	x <- random            # random : forall op. Context (EFF op) Double
	y = x + 1              # 単なる代入
	log(y)                  
	return unit            
```

いわゆる Extensible Effects

### パターンマッチ

```=
x = match y:
	case Just(z : Int) if w == z: 
		z + 1
	case Nothing:
		0
```

### if 式

```=
x = 
	if w == z:
		1
	else:
		0
```

### 演算子

```
+, *, -, /, %

==, !=, <, >, =<, =>, &&, ||

++ # 配列、文字列の結合

|>, <| # パイプライン
```

### 型アノテーション

定義の時、引数に書ける

```=
f : Int -> Int
f = lambda(x: Int): 
	x + 1
```

### type 宣言

```=
type Hoge:
	Fuga : Int -> Hoge
	Piyo : String -> Hoge
	FugaFuga : Hoge
	
type Maybe(t):
	Nothing
	Just(t)
```
 
### ジェネリクス、制約

```=
mp : forall t u. (t -> u) -> t -> u
def mp(f, x): 
	f(x)
	
append : forall t. Monoid t => t -> t -> t
append = ...
```

### 拡張可能バリアント

```=
type Foo(a):
	Foo: forall y. Int -> Foo(x)
	a
	
type Bar(x):
	Bar: forall x. String -> Bar(x)
	x
```

### クラス

```=
class Semigroup<t>:
	append : t -> t -> t
	
class Monoid<t when Semigrop<t>>:
	empty: t
	
instance Semigroup<String>:
	append = ...
	
instance Monoid<String>:
	empty = ""

class Reader<m when Monad<m>>:
	type t: Type
	read: m<t>
```

## FFI

### 外部 data 型

```=
foreign data HtmlDivElement :: Type;
```


### 値のインポート

別ファイル
```javascript=
const plusOne = (x) => x + 1
```

```=
foreign plusOne: Int -> Int;
```
