ML(MetaLanguage:元语言)是一个通用的函数式编程语言。ML是静态作用域的。ML知名于使用了多态的Hindley-Milner类型系统,它自动的指定多数表达式的类型,不要求显式的类型标注,而且能够确保类型安全,已经正式证明了有良好类型的ML程序不会导致运行时间类型错误。
ML提供了对函数实际参数的模式匹配、垃圾回收、指令式编程、传值调用和柯里化。它被大量的用于编程语言研究之中,并且是全面规定了的和使用形式语义验证了的少数语言之一。它的类型和模式匹配使得它非常适合并且经常用于在其他形式语言上进行操作,比如在编译器构造、自动化定理证明和形式验证中。
ML是由爱丁堡大学的RobinMilner及他人在二十世纪七十年代早期开发的,它的语法是从ISWIM得到的灵感。ML是为了帮助在LCF定理证明器中寻找证明策略而构想出来的,LCF的语言是“pplambda”,联合了一阶逻辑演算和有类型的多态的λ演算,拥有ML作为元语言。
超实用性的Python零基础入门到进阶视频源码淘宝¥2购买已下架ML特性包括:传值调用的求值策略,头等函数,带有垃圾收集的自动内存管理,参数多态,静态类型,类型推论,代数数据类型,模式匹配和异常处理。
不同于Haskell,ML与大多数编程语言一样使用及早求值,也就是说所有的子表达式总是被求值,尽管可以通过使用闭包来完成惰性求值。因此可以像Haskell那样建立和使用无限串流,但是它们的表达是间接的。
今天在ML家族中有好几种语言:两种主要的方言是StandardML和OCaml,其他的包括F#,它是针对Microsoft.NET平台的开放研究项目。ML中的思想影响了众多的语言,例如Haskell,Cyclone和Nemerle,ATS和Elm。
ML的实力大多被用于语言设计和操作(编译器、分析器、定理证明器),但是它作为通用语言也被用于生物信息和财务系统等领域。
ML特别是StandardML是具有一些不纯粹特征的函数式语言。用ML书写的程序构成自要被求值的表达式,而非语句或命令,尽管一些表达式返回一个平凡的unit值并且只为其副作用而求值。
就像所有的函数式语言一样,ML的关键特征是函数,它被用于进行抽象。例如阶乘函数用纯ML可表达为:
funfac0=1
facn=n*fac(n-1)
这里将阶乘描述为递归函数,具有一个单一的终止基础情况。它类似于在数学教科书见到的阶乘描述。多数ML代码在设施和语法上类似于数学。
凭借类型推论编译器能推导出,fac接受整数0作为实际参数,则形式参数n也是整数类型int,而fac0的结果是整数1,则函数fac的结果也是整数类型。函数fac接受一个整数的形式参数并返回一个整数结果,它作为一个整体从而有着“从整数到整数的函数”类型int-int。函数及其形式参数的类型还可以用类型标注(annotation)来描述,它是可选也可忽略的。它使用E:t表示法,可以被读作表达式E有类型t。使用类型标注,这个例子可重写为如下:
fac(n:int):int=n*fac(n-1)
这个函数还依赖于模式匹配,这是ML语言的重要部分。注意函数形式参数不必须在圆括号内但要用空格分隔。当一个函数的实际参数是0,它将返回整数1。对于所有其他情况,尝试第二行。这是一个递归,并且再次执行这个函数直到达到基础情况。它可以使用case表达式重写为:
funfacn=casen
of0=1
n=n*fac(n-1)
这里case介入了模式和对应表达式的序列。它还可以重写为将标识符绑定到lambda函数:
valrecfac=
fn0=1
这里的关键字val介入了标识符到值的绑定,fn介入了匿名函数的定义,它可以用在fun的位置上,但使用=算符而非=。绑定到递归的匿名函数需要使用rec关键字来指示。
通过将主要工作写入尾递归风格的内部迭代函数,借助于语言编译或解释系统进行的尾调用优化,这个函数可以得以增进性能,它的调用栈不需要随函数调用数目而成比例的增长。对这个函数可以采用向内部函数增加额外的“累加器”形式参数acc来实现:
funfactn=let
funfac(0,acc)=acc
fac(n,acc)=fac(n-1,n*acc)
in
fac(n,1)
end
let表达式的值是在in和end之间表达式的值。这个递归函数的实现不保证能够终止,因为负数实际参数会导致递归调用的无限降链条件。更健壮的实现会在递归前检查实际参数为非负数,并在有问题的情况,即n是负数的时候,启用异常处理:
if(n0)
thenraiseFailnegativeargument
elsefac(n,1)
End