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模块
- 服务器端,没有副作用的检索函数的页面(HTTPGET方法),经由一个URL而可访问为/ModulePath/functionName,它们应当具有类型(unit -> transaction page)。
- 要导出可能导致副作用的一个页面,只能通过HTTPPOST方法来访问,包括指定页面处理器的一个实际参数,它具有类型Basis.postBody[6]。
编译:
 urweb module1   # 查找module1.urp
作为一个web服务器来执行(其他模态有CGI、FastCGI等等):
 ./module1.exe -p 8081   # -h : RTS选项帮助
引用
    
- . [2021-03-03]. (原始内容存档于2016-06-04).
- . impredicative.com/ur. [3 April 2016]. (原始内容存档于2020-11-30).
- Adam Chlipala. (PDF). MIT / Association for Computing Machinery (ACM). January 2015 [2021-09-04]. (原始内容 (PDF)存档于2022-01-16).
- . [2021-03-04]. (原始内容存档于2020-11-12).
- Chlipala, Adam. . urweb-doc. January 2015 [8 January 2015]. (原始内容存档于2016-03-04).
- . [2021-03-04]. (原始内容存档于2016-03-04).
外部链接
    
- Ur language home page (页面存档备份,存于)
- Ur/Web project page on GitHub (页面存档备份,存于)
- Ur wiki (页面存档备份,存于)
    This article is issued from Wikipedia. The text is licensed under Creative Commons - Attribution - Sharealike. Additional terms may apply for the media files.