Ur語言
Ur也叫作Ur/Web,是一個自由和開源的函數式程式語言,專門用於web開發,由Adam Chlipala在麻省理工學院建立[3],它從一個單一的程式產生伺服器代碼、web瀏覽器客戶端代碼、和特定於選擇的資料庫後端的SQL代碼。
編程範型 | 函數式, 響應式 |
---|---|
語言家族 | ML |
設計者 | Adam Chlipala |
釋出時間 | 2014年12月[1] |
目前版本 |
|
系統平台 | POSIX |
許可證 | 三條款BSD許可證 |
副檔名 | .ur, .urs, .urp |
網站 | impredicative |
啟發語言 | |
ML[2], Haskell |
概述
Ur的語法基於了Standard ML,然而語言也包括來自Haskell的概念,具有額外的類型操縱。Ur支援一種基於行類型的強力的元程式設計[2]。Ur/Web是Ur加上特殊的標準庫和用於解析和最佳化的關聯規則。Ur/Web編譯器還產生不使用垃圾回收的非常高效的目標碼[2]。所有這些實現都是開放原始碼的[2]。
Ur/Web支援構造以SQL資料庫為後端的動態web應用。嵌入到語言中的SQL語法模板便利了表格處理。瀏覽器客戶端,包括了函數式響應式編程設施,使用了(source a)
類型和signal
單子。Ajax呼叫/反響,通過叫作「事務」(對應於Haskell的IO)的單子來序列化,並且它的集結和解碼被封裝在rpc函數中。
標準庫的簽章(signature),使得有良好類型的Ur/Web程式,在非常寬廣的意義上不會出錯。不只是在特定頁面生成期間不崩潰,它們還能夠做到[2]:
例子程式
下面是展示客戶端、伺服器和資料庫採用Ajax通訊的演示程式,來自web demos[4],有着勾畫每個構件的額外註釋:
介面檔案(類似ML的簽章)具有.urs
副檔名:
(* 环境单子叫做transaction,对应于Haskell的IO单子 *)
val main : unit -> transaction page
實現檔案(.ur
副檔名):
datatype list t = Nil | Cons of t * list t
table t : { Id : int, A : string }
PRIMARY KEY Id
(* 服务器端数据库访问,通过AJAX XmlHttpRequest调用,
封装为rpc函数(远程过程调用) *)
fun add id s =
(* sql dml模板,据有表达式{[expression]} *)
dml (INSERT INTO t (Id, A) VALUES ({[id]}, {[s]}))
fun del id =
dml (DELETE FROM t WHERE t.Id = {[id]})
fun lookup id =
(* haskell风格单子代码 *)
ro <- oneOrNoRows (SELECT t.A FROM t WHERE t.Id = {[id]});
case ro of
None => return None (* return是单子提升函数 *)
| Some r => return (Some r.T.A)
(* check由客户端onClick事件处理器调用,
所以它将被编译成JavaScript,成为嵌入了客户端脚本的页面 *)
fun check ls =
case ls of
Nil => return ()
| Cons (id, ls') =>
ao <- rpc (lookup id); (* Ajax调用至服务器端 *)
alert (case ao of
None => "Nada"
| Some a => a
);
check ls'
fun main () =
idAdd <- source "";
aAdd <- source "";
idDel <- source "";
(* 生成包含有JavaScript的web页面 *)
return <xml><body>
<button value="Check values of 1, 2, and 3"
onclick={fn _ => let val mylist = 1 :: 2 :: 3 :: []
in
check mylist
end
}/><br/>
<br/>
<button value="Add"
onclick={fn _ => id <- get idAdd;
a <- get aAdd;
rpc (add (readError id) a) (* Ajax调用到服务器端 *)
}/>
<ctextbox source={idAdd}/>
<ctextbox source={aAdd}/><br/>
<br/>
<button value="Delete"
onclick={fn _ => id <- get idDel;
rpc (del (readError id)) (* Ajax调用到服务器端 *)
}/>
<ctextbox source={idDel}/>
</body></xml>
專案檔案(.urp
副檔名),必須包含可選的指令(directive)列表,跟隨着專案模組的列表[5]:
# hash号前缀于行注释
rewrite url Module1/main # 设置根URL至Module1/main函数
exe myexename
database dbname=test # 数据库特性和参数
sql noisy.sql
$/list # stdlib模块前缀着"$/"
module2 # 如果被module1所用则必须前导于它
module1 # main模块
- 伺服器端,沒有副作用的檢索函數的頁面(HTTP
GET
方法),經由一個URL而可訪問為/ModulePath/functionName
,它們應當具有類型(unit -> transaction page)
。 - 要匯出可能導致副作用的一個頁面,只能通過HTTP
POST
方法來訪問,包括指定頁面處理器的一個實際參數,它具有類型Basis.postBody
[6]。
編譯:
urweb module1 # 查找module1.urp
作為一個web伺服器來執行(其他模態有CGI、FastCGI等等):
./module1.exe -p 8081 # -h : RTS选项帮助
參照
- ^ UrWeb is out of beta. [2021-03-03]. (原始內容存檔於2016-06-04).
- ^ 2.0 2.1 2.2 2.3 2.4 2.5 The Ur Programming Language Family. impredicative.com/ur. [3 April 2016]. (原始內容存檔於2020-11-30).
- ^ Adam Chlipala. Ur/Web: A Simple Model for Programming the Web (PDF). MIT / Association for Computing Machinery (ACM). January 2015 [2021-09-04]. (原始內容 (PDF)存檔於2022-01-16).
- ^ Ur language demo programs. [2021-03-04]. (原始內容存檔於2020-11-12).
- ^ Chlipala, Adam. The Ur/Web Manual – Project files. urweb-doc. January 2015 [8 January 2015]. (原始內容存檔於2016-03-04).
- ^ The Ur/Web Manual - The Structure of Web Applications. [2021-03-04]. (原始內容存檔於2016-03-04).