Ur语言

Ur也叫作Ur/Web，是一个自由和开源的函数式编程语言，专门用于web开发，由Adam Chlipala在麻省理工学院创建，它从一个单一的程序产生服务器代码、web浏览器客户端代码、和特定于选择的数据库后端的SQL代码。 Ur的语法基于了Standard ML，然而语言也包括来自Haskell的概念，具有额外的类型操纵。Ur支持一种基于行类型的强力的元编程。Ur/Web是Ur加上特殊的标准库和用于解析和优化的关联规则。Ur/Web编译器还产生不使用垃圾回收的非常高效的目标代码。所有这些实现都是开放源代码的。 Ur/Web支持构造以SQL数据库为后端的动态web应用。嵌入到语言中的SQL语法模板便利了表格处理。浏览器客户端，包括了函数式响应式编程设施，使用了(source a)类型和signal单子。Ajax调用/反响，通过叫作“事务”（对应于Haskell的IO）的单子来序列化，并且它的集结和解码被封装在rpc函数中。 标准库的签名（signature），使得有良好类型的Ur/Web程序，在非常宽广的意义上不会出错。不只是在特定页面生成期间不崩溃，它们还能够做到： 不遭受任何种类的代码注入攻击。 不返回无效的HTML。 不包含应用内部死链接。 在HTML表单和它们的处理器所预期的字段之间，没有不匹配。 不包括对远程web服务器提供的Ajax风格服务有不正确假定的客户端代码。 不尝试无效的SQL查询。 在web浏览器和web服务之间或与SQL数据库的通信中，不使用不正确的集结（marshaling）或解散（unmarshaling）。 这种类型安全正是Ur/Web方法论的基础。还有可能使用元编程，通过分析类型结构来建造重要的应用部件。 下面是展示客户端、服务器和数据库采用Ajax通信的演示程序，来自web demos，有着勾画每个构件的额外注释： 接口文件（类似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）列表，跟随着项目模块的列表： # 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。 编译： urweb module1 # 查找module1.urp 作为一个web服务器来执行（其他模态有CGI、FastCGI等等）： ./module1.exe -p 8081 # -h : RTS选项帮助 UrWeb is out of beta. [2021-03-03]. （原始内容存档于2016-06-04）.  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）.  Ur language home page （页面存档备份，存于互联网档案馆） Ur/Web project page on GitHub （页面存档备份，存于互联网档案馆） Ur wiki （页面存档备份，存于互联网档案馆）