-
Notifications
You must be signed in to change notification settings - Fork 82
v0.1.z での構文の変更案
let succ (x : int) = x + 1 in succ 42
トップレヴェルでの値の束縛は(let
ではなく)val
によって行なう.局所的な束縛は引き続き let
.rec
は独立したキーワードとする.let-inline
は val inline
/let inline
で記述する.inline
,block
,math
は新たにキーワードとする.math
は(引き続き)型名としても使う.
val add x y =
x + y
val add-partial x =
let f y = x + y in f
val rec power n =
if n <= 0 then 1 else n * power (n - 1)
val inline ctx \display-power n =
Inline.read ctx (Inline.embed-string (String.arabic (power n)))
val is-even-nat (n : int) : bool =
let rec odd n =
if n == 0 then false else even (n - 1)
and even n =
if n == 0 then true else odd (n - 1)
in
if n < 0 then false else even n
区切り記号を ;
ではなく ,
にする.また,末尾の ,
も許容する.
val nums = [3, 1, 4, 1, 5, 9, 2]
val people =
[
(| name = {Alice}, age = 25 |),
(| name = {Bob}, age = 32 |),
]
いわゆるぶら下がりの防止のため.
val is-empty xs =
match xs with
| [] -> true
| _ :: _ -> false
end
type tree 'a =
| Leaf
| Node of list (tree 'a)
val rec tree-size 'a (tr : tree 'a) =
match tree with
| Leaf -> 0
| Node(trs) -> trs |> List.fold-left (fun n tr -> n + tree-size tr) 0
end
module List : sig
val find-map 'a 'b : ('a -> option 'b) -> list 'a -> option 'b
end
val get-name 'a ('b :: (| name : 'a |)) : 'b -> 'a
従来はモジュールの表現力が限られていたこともあって “グローバルな名前空間でも束縛する,val
の拡張版” として direct
を用意していたが,これはモジュールシステムのF-ing modules化により不用意な複雑化を避け廃止したい.一方でコマンドをグローバルな名前空間へと取り出すのは使う側の責務とする.
cycle
,controls
,--
,..
,<[
,]>
といったトークンとそれによる構文を廃止する.もともとはTikZ風にパスを記述できるようにするためのものだったが,パス用プリミティヴやグラフィックス用のモジュールで事足りるようになった.
プリミティヴは直接アクセスできないようにし,ひとつのモジュール Prim
にまとめる.名前空間を節約するほか,更新を後方互換にしやすくする意図がある.
さらに言えば,この Prim
のメンバ自体も通常の用法ではできるだけ直接使用せず,satysfi-base
などを介して使うことを推奨するようにする.
従来はトップレヴェルの名前空間で直接束縛できたが,衝突防止のためこれをできないようにする.したがってライブラリをなす各ファイルは以下のような構造に限定される:
〈require など他のファイルへの参照〉
module 〈モジュール名.原則としてファイル名と同じ〉 : sig
〈API〉
end = struct
〈実装〉
end
また,これはデファクトスタンダードのパッケージマネージャであるSatyrographosとの責務の分担を議論する必要がありそうだが,今のSatyrographosが扱っているopamパッケージの単位で “1パッケージにつき丁度1モジュールがexportされる” という制約を設ける.例えば satysfi-base
なら Base
というモジュールのみがグローバルに読み込まれ,個々の機能のモジュールは Base.String
とか Base.RegExp
といった入れ子のモジュールになる要領.
この仕組みを先んじて設計・実装したSesterlでなかなか奏功している様相のため,SATySFiでも同様の仕組みにするとよいかもしれないという検討.
従来の @require:
で相対パスを指定するのではなく,モジュール名で指定して同ライブラリ中の別モジュールまたは外部パッケージを読み込む:
require Base
ただし,“require
の記述のみからマシンにインストールされたパッケージで該当のものを見に行く” という従来の @require:
と同様の振舞いをさせるか否かはやや議論の餘地がありそう.文書という長期の保守が重要となりうる用途であることを鑑みるとビルドの再現性が高いことが望ましく,ライブラリのヴァージョンなどの情報が別途メタ的に記述される仕組みがある方が無難ではないか.
- ライブラリの場合:
- Satyrographosの
Satyristes
ファイルなどに与えればよさそう. - ただし,SATySFi本体も何らかの方法でそのメタ情報に依存して処理をする必要があるのが少し厄介.
- メタ情報に明示されていないがマシンにインストールされているパッケージを見に行くような挙動をすべきでないため.
- Satyrographosの
- 文書ファイルの場合:
- メタ情報は勿論必要.
- ちょっとしたレポートなどの執筆にも使われるので,軽量に書けることが望ましい.
- 文書本体の上部にメタ情報を書ける仕組み(OCamlの
[@@foo …]
とかRustでいう#[foo(…)]
のようなものでよい)があるべきかも. - ヴァージョン情報などが省略されていても,既に該当の名前のライブラリがマシンにインストールされていれば警告を出しつつ処理を継続する,というくらいでよいかも.
- 文書本体の上部にメタ情報を書ける仕組み(OCamlの
ちなみに,無くても言語機能上の支障はないが,以下のように補助的に名前変更やopenを簡便に行なう機能があってもよさそう:
require Base as B
require open Base
- トップページ
- The SATySFibook Web公開版 第1版
- Wiki
- 目的別パッケージ一覧
- コマンドライン書式
- SATySFiコマンド一覧
- Satyrographos(パッケージマネージャ)
- 新しい言語機能の紹介
- 言語機能の構想