前言:
以下介绍目前在上的Coursera课程的第一周课程,分为三个部分,第一部分是课程目标,第二部分是软件安装及平台搭建,第三部是ML语言的基本语法。
参考资料:CMU, Programming in ML 教材
课程目标:
该课程分为A、B、C三部分,第一部分以ML语言作为教学语言,第二部分用Racket作为教学语言,第三部分采用Ruby,所有的语言都是为了学习编程的范式及概念,以便后续能快速学习新语言,找出共通之处和不同之处。
简而言之,即:
- 学习基本出现于所有编程语言的基本概念。
- 学习这些概念是如何组合在一起的。
- 对比不同语言看他们是如何利用互补的方法来展示这些基本概念。
该课程主要使用函数式编程语言,该类语言强调数据的不可修改性,即无赋值语句。
环境安装
编译器:Standard ML of New Jersey, 安装成功后可以通过cmd,直接输入sml进行repo界面。
编辑器:使用Emacs,windows下载安装即可。
Emacs配置:
Meta + X list package 选择SML Mode进行下载,其中Meta可以用Alt键替代
Emacs常用命令
• C-x C-c: Quit Emacs
• C-g: Cancel the current action
• C-x C-f: Open a file (whether or not it already exists)
• C-x C-s: Save a file
• C-x C-w: Write a file (probably more familiar to you as Save as...)
• C-Space to set a mark and then moving the cursor to highlight a region.
• C-w: Cut a highlighted region
• M-w: Copy a highlighted region
• C-k: Cut (kill) from the cursor to the end of the line
• C-y: Paste (yank)
• C-x 2: Split the window into 2 buffers, one above the other (Use the mouse or C-x o to switch between them)
• C-x 0: Undo window-splitting so there is only 1 buffer
• C-x b: Switch to another buffer by entering its name
• C-x C-b: See a list of all current buffers
• C-h: Help. Hitting this will display a short message in the minibuffer: C-h (Type ? for further options).
• C-h b: Key bindings. This lists all key bindings that are valid for the current mode. Note that key bindings change from mode to mode.
• C-h a: Command apropos. After typing C-h a you can type a symbol and a window will appear that lists all symbols and functions that match that phrase.
- SML/NJ REPL(Read-Eval-Print Loop)
写完一个sml文件后,C-x C-s保存后,可输入C-c C-s进入REPL, 然后使用use "sml文件"; 即可导入sml文件里的函数和变量,编译器会对其进行类型检查。
注意分号不可少。
语法
C,Java程序是一系列修改电脑内存的命令,每步的执行都会检查内存中当前的内容,执行运算,修改内存,然后继续下一步,每个命令都会对internal memory, registers, external devices造成影响。运算的过程是通过对表达式的evaluation进行的,如布尔测试,或算术操作。很多语言都对expression与command有区分。
ML的计算则有所不同,其强调对evaluation of expressions的计算,而非execution of commands. 例如给定x的值,计算一个多项式表达式的值。
由于其与数学相关性较强,能更好地从计算上确保程序正确执行,而不用tedious的测试和诸多的debugging,而这些debug仅仅解决error,不是确保其不发生。此外ML更易维护和理解,execution of commands对内存的影响可以被作为evaluation of expression的特例-通过引入primitive operations,用于分配,访问以及修改内存。
expression有三个属性需要考虑,一个式type, 一个是value, (每个表达式都默认必须有一个type, 另外我们可以从表达式计算一个value出来,value的type必须与表达式预测的type一致)
,最后一个要考虑的是表达式是否会有副作用。
type 包含 name, value, operation
例如int 类型,name为int,值可以为0,1,1,2,2 等等,可被应用的操作符有+,-,*,div,mod等,表达式的类型是由type assertion决定的,表达式的值是由evaluation assertion决定的。
其他的类型:
real: 3.14, 0.1E6等,操作符+,-,*,/,=,<等
char: #"a", #"b"等,操作符ord, chr, = , <等
string: "abc", "1234"等,操作符^, size, =, <
bool: true, false等,操作符if .. then .. else
ML里变量无法修改,不能先声明,即声明时需赋值,而这个值将会终生绑定在这个变量上,这叫value binding。类型则可通过type binding将type constructor绑到type上。
变量无法修改,但利用shaowding,即创建一个同名变量将覆盖之前的变量(可通过let使变量仅生效在创建的scope里)
即let dec in exp end
函数的evaluate是通过call-by-value规则,即函数是在值上进行运算的。函数是first-class values.
数据结构:tuple, list, array, tree等,在ML里,对数据结构的创建及回收不用过于关心,可以认为数据结构也是first-class values.
数组Tuple:
Type-typ1...typn;
Value-(val1,...,valn)
空数组()有type,为unit
获取数组元素可以用#1 数组名获取第一个元素
记录Record:
{lab1=val1,...,labn=valn}.
{lab1=pat1,...,labn=patn}
列表List:
[val1,....,valn]
hd 获取第一个元素,tl获取剩余列表
Option:
NONE--option value "carrying nothing"
SOME--option that carry one value
isSome--判断变量是否是非空
valOf--可用于获取SOME携带的值
逻辑关系:
andalso, orelse等
此外还有递归,后续再介绍
小结:
- 理解不可变的用处及实际意义
- 学习和定义一门语言所必须了解的--
1. Syntax: 语法/句法,如何写语言中不同的部分
2. Semantics: 语义,语言的不同特性含义是什么,例如expressions evaluated是什么样的
3. Idioms: 风格或语法,常用的利用某个语言特性的去计算的方法或表述
4. Libraries: 库,有哪些库是已经写好的,离开库不能做的事情有什么办法吗
5. Tools: 哪些工具是所需的,如编译器,read-eval-print loops, debuggers等