华盛顿大学Programming Language Week2
Week1目录
- ML Expressions and Variable Bindings(ML的表达式以及变量绑定)
- Using use (使用use:主要运行源代码文件)
- Variables are Immutable (变量不可变的)
- Function Bindings (方法绑定)
- Pairs and Other Tuples (数对和其他元组)
- Lists(列表)
- Let Expressions(let表达式)
- Options(一种语法)
- Some Other Expressions and Operators
- Lack of Mutation and Benefits Thereof
- The Pieces of a Programming Language
ML Expressions and Variable Bindings
首先从一个非常非常简单的代码开始,变量的绑定
An ML program is a sequence of bindings.讲述的是指在ML语言中就是不断的变量绑定
在进行变量绑定时,需要涉及到type-checked和evaluate这两个内部操作,还有static environment和dynamic environment。
static environment中存放的是变量的类型即
type
dynamic environment中存放的是数值,在进行evaluate时就需要在这里面进行查找和使用
学习程序设计语言时需要学习三个东西syntax、semantics(type-check&evaluate)
- syntax (how to write it) : 语法,是指的一段代码的语言的规则例如
val x = e;在这句话中就明确的指出了变量定义的方法。其中的e可以是任意的变量,也可以是表达式(expression) - semantic(how it type-checks and evaluates) : 语义,在进行type-check时,会使用到static environment ,是会创建一个新的静态环境;而在进行evaluate时,使用的是dynamic environment,会赋予一个数值,具体如下:
val x = 34;
(* static environment: x-->int *)
(* dynamic environment: x-->34 *)
val y = 17;
(* static environment: y-->int, x-->int *)
(* dynamic environment: y-->17, x-->34 *)
(* to evaluate an addition, evaluate the subexpressions and add *)
(* to evaluate a variable, lookup its value in the environment *)
val z = (x + y) + (y + 2);
(* static environment: z-->int, y-->int, x-->int *)
(* dynamic environment: z-->70, y-->17, x-->34 *)
在最后进行计算时,首先会在environment中进行查找,检查是否可以进行操作。
在本小节中,要学会的是对于一种新的程序设计语言都可以从三个方面去分析它,包括syntax、type-check、evaluate。例如:



这里只说了三个分析的例子,其他也是类似的
Using use
这里的use指的是要使用read-eval-print-loop,其意思是指读取、运算、循环输出,英文Wiki如下:
A read–eval–print loop (REPL), also termed an interactive toplevel or language shell, is a simple, interactive computer programming environment that takes single user inputs (i.e., single expressions), evaluates (executes) them, and returns the result to the user; a program written in a REPL environment is executed piecewise.
在该课程种使用的是ML language,搭配emacs,使用use "filename.sml";作为对写的文件进行调用,这个就和Java运行中的,编译+运行一样:javac hello.java然后java hello是一个道理的。
Variables are Immutable
在程序设计语言中一个很关键的就是immutable和mutable,它涉及了在语言中是否可以进行更改,是否可变。在ML中,变量进行赋值后,在这个dynamic environment中,x始终是map到一个数的。
如果是在一个dynamic environment中使用重新赋值是不会改变的,示例如下:
- val x = 10;
val x = 10 : int
- x = 20;
val it = false : bool
在这个语句中,首先对x进行赋值得到x = 10但是进一步使用x = 20时得到的时false,而不是赋值变换。
Function Bindings
Function类似于Java中的Method(方法)
学习Function的绑定,也是从三个方面来进行学习
- syntax:
fun x0(x1:t1,x2:t2...xn:tn) = e其中的x1-xn是变量名,其中的t1是type的简写,讲述的是变量的类型,最后的e是expression,是Function的表达式,一个简单的求x^y可以写为:
(* 涉及了一个递归的思想,而不是迭代*)
fun pow(x:int,y:int) =
if y = 0
then 1
else x*pow(x,y-1)
- type-check: 在ML中,Function的类型和变量绑定的类型一致,例如x0首先是从static environment中得到x1...xn的类型,在得到类型之后进行自己的计算得到e的类型,最终x0的类型便是(t1 t2...tn -> t3)
- evaluation:Function也只是在dynamic environment中的一个值。
Function Calls
- Syntax:
e0 (e1,...,en) - Type-check: 对于上面的e1...en的每一个类型都需要和e0这个Function在static environment中的类型相匹配
- Evaluate:最终在dynamic environment中找到e1对应的v1(value)以及剩下的其他value。完成最终计算。
fun cube(x : int) =
pow(x,3)
val ans = cube(4)
Pairs and Other Tuples
前面讲述的都是一些简单的变量绑定,这里讲的Tuples(元组)则是一种组合变量,在其内部有多个值。
- syntax:(e1,e2)其中的e1,e2也可以是组合变量。
- evaluate:(e1,e2)对应的值为(v1,v2)
使用方法为#1 或者#2得到对应位置的变量。
- val a = (1,2,3,4);
val a = (1,2,3,4) : int * int * int * int
- #1 a;
val it = 1 : int
- #3 a;
val it = 3 : int
(*一个典型的例子就是div_mod,使用Java等其他语言需要创建一个类,来导出这两个东西*)
fun div_mod(x:int,y:int) =
(x div y,x mod y)
Lists
和Tuple相比,Lists可以无限长,没有限制,但是在List中的所有元素必须是同类型的,不能有混杂类型。
- Syntax:[]使用的是方括号,
操作:
- null 判断list是否为空,如果为空则返回true
- val c = [];
val c = [] : 'a list
- null c;
val it = true : bool
- hd 获得list的第一个元素
val cc = [1,3,4]
- hd cc;
val it = 1 : int
- tl 获取除了头元素的剩下的元素
- tl cc;
val it = [3,4] : int list
- :: 使用这个可以向list中添加元素
- 0::cc;
val it = [0,1,3,4] : int list
在这些基本操作里面没有办法知道List的长度,所以在这里大部分是使用Recursion(递归)
fun append (xs : int list, ys : int list) =
if null xs
then ys
else (hd xs) :: append(tl xs, ys)
fun countdown (x : int) =
if x=0
then []
else x :: countdown(x-1)
浙公网安备 33010602011771号