上海做网站的公司电话,网站里做任务,移动网站开发服务,如何打开网站网页2019独角兽企业重金招聘Python工程师标准 Scheme语言入门 最早听说 LISP#xff0c;是 Stallman 的 GNU Emacs 中将 LISP 作为嵌入语言#xff0c;定制和增强 Emacs。GNU Emacs 是一个文本编辑器#xff0c;文本就是一种符号#xff0c;而 Lisp 正好就是针对… 2019独角兽企业重金招聘Python工程师标准 Scheme语言入门 最早听说 LISP是 Stallman 的 GNU Emacs 中将 LISP 作为嵌入语言定制和增强 Emacs。GNU Emacs 是一个文本编辑器文本就是一种符号而 Lisp 正好就是针对符号计算发明的因此在GNU Emacs 中使用 Lisp 是顺理成章的事情。 Lisp 语言的历史已经很久了几乎与 Fortran 一样长。二十世纪五十年代计算机科学家先是发明了针对数字计算的 Fortran 语言后来针对符号计算由MIT 的John McCarthy于1960年开发出了Lisp(List processing)语言。该语言原来是为表处理而设计的编程语言后来广泛用于处理人工智能问题。Lisp 程序中充满了一对对嵌套的小括号这些嵌套的符号表达式体现着递归。递归是数学上的基本概念之一从递归理论出发一切可以计算的函数最终都可以划归为几种基本的递归函数的种种组合。 1994年时众多 Lisp 版本又得到了相当的统一统一之后的版本称为Common LISP。Common Lisp 含有非常丰富的库仅仅语言的规范就长达千页以上包括面向对象的 CLOS。 Scheme 语言是 Lisp 的一个现代变种、方言诞生于1975年由 MIT 的 Gerald J. Sussman and Guy L. Steele Jr. 完成。Scheme语言的规范很短总共只有50页甚至连Common Lisp 规范的索引的长度都不到但是却被称为是现代编程语言王国的皇后。它与以前和以后的 Lisp 实现版本都存在一些差异但是却易学易用。 DSSSL需要完成的工作是解析文档它的设计就采用了Scheme语言。本书时介绍DocBook的专著因此并不打算写一个Scheme大全只是想通过蜻蜓点水的介绍使读者认识Scheme能够达到看懂和简单的修改DSSSL。 Scheme特点 Scheme语言具有它独特的魅力看看Scheme的语法特点 括号嵌套 Lisp 程序中充满了一对对嵌套的小括号这些嵌套的符号体现了最基本的数学思想——递归。 语法简洁 Scheme语言的规范很短总共只有50页。 函数编程语言 一个函数Function是这个编程语言中所谓的第一等的公民。也就是说函式可以像一个 int 或者 float 一样被很方便的传递来传递去。这也就是所谓Functional 编程语言中Functional 一词的由来。 自动内存管理 自动内存管理可不是JAVA的专利呦。 可移植性好 Scheme开发的程序有很好的可移植性这是由于Scheme是一种解释语言在不同的平台都可以有相应的解释器。 适合于作为脚本语言和嵌入语言 语法简洁这使得Scheme的实现可以非常的经济一个Scheme解释器可以非常的小巧。Scheme可以作为脚本语言而内嵌于一些工具之中如GNU Emacs。 其他特点还有关键字对大小写不敏感。 数据结构 数字 下面都是合法的数字表示方法471/32.34.3e1413i。 字符 字符前面需要用#\做前缀。如下面都是合法字符 #\a #\A #\b #\B #\space #\newline 字符串 由双引号括起来的字符组成字符串。如A little string 布尔值 布尔值True和False分别用 #t 和 #f 表示。 列表 用圆括号括起来的可以包含任何数据类型的称为列表。如 (a little (list of) (lists)) 数组vector 用#为前缀如 #(1 2 string #\x 5) 函数或称为过程 把函数作为一种数据类型是Scheme语言的特色。 符号 符号除了不能够以数字开头的任何字符可组成符号。如Symbols: this-is-a-symbol foo a32 c$23*473-is-a-symbol-too! 表达式和函数 注释 分号开始一段注释。如 ( 3 1) ;return 4 常量表达式 常量表达式 常量表达式返回本身的值。如 3.14 ; 返回 3.14 #t ; 返回布尔值 #t #\c ; 返回字符 #\c Hi! ; 返回字符串 Hi! 引用Quotation 语法(quote obj) 或者简写为 obj ( 2 3) ; 返回 5 ( 2 3) ; 返回列表 ( 2 3) (quote ( 2 3)) ; 返回列表 ( 2 3) 表达式记法 Scheme的表达式的写法有些特别表达式用括号括起来。括号里面的第一个出线的是函数名或者操作符其它是参数。Scheme的这种表达式写法可以叫做前置式。下面是一些Scheme的表达式的例子以及其对应的C语言的写法。 Scheme C ------------------------------------------------------------------ ( 2 3 4) (2 3 4) ( low x high) ((low x) (x high)) ( (* 2 3) (* 4 5)) ((2 * 3) (4 * 5)) (f x y) f(x, y) (define (sq x) (* x x)) int sq(int x) { return (x * x) } 赋值和函数定义 let 表达式和赋值 语法(let ((var val) ...) exp1 exp2 ...) 说明let 表达式的赋值只在表达式内部有效。 示例 (let ((x 2) (y 3)) ( x y)) ; 先赋值 x2, y3再计算xy的值结果为5。注意 (x 2) 和 (y 3) 外还有一层括号。 更多的示例 (let ((f )) (f 2 3)) ; return 5 (let ((f ) (x 2)) (f x 3)) ; return 5 (let ((f ) (x 2) (y 3)) (f x y)) ; return 5 用define 和 set! 赋值 语法(define var exp) , (set! var exp) 说明define和 set! 表达式的赋值在全局有效。define 和 set! 的区别是define既能赋值又能定义变量而set!只能对已经定义的变量赋值。 示例 (define a 1) a ; return 1 (set! a 2) a ; return 2 (let ((a 3)) a) ; return 3 a ; return 2 (let ((a 3)) (set! a 4) a) ; return 4 a ; return 2 (let ((a 3)) (define a 5) a) ; return 5 a ; return 2 (set! b 1) ; 错误b尚未定义 lambda 表达式和函数定义 语法(lambda (var ...) exp1 exp2 ...) 说明lambda 表达式用于定义函数。var ... 是参数exp1 exp2 ...是函数的执行 部分。通常需要结合局部定义 let 或者全局定义表达式 define再进行函数调用。 示例 ((lambda (x) ( x x)) (* 3 4)) ; return 24 说明先用lambda定义了函数参数是x函数返回xx。同时该语句也完成了函数调用实参是 12 (等于3*4)因此返回值是 24 等于1212。 在let表达式中定义函数。 Scheme语言中函数作为一种数据类型通过赋值语句将lambda表达式赋值给相应的函数。 示例 (let ((double (lambda (x) ( x x)))) (list (double (* 3 4)) (double (/ 99 11)) (double (- 2 7)))) ; return (24 18 -10) 说明let表达式将lambda定义的函数赋值给double参数是x返回 xx。接下来分别三次调用 double 函数并将结果以列表形式返回。list 表达式负责生成列表。 用define全局定义表达式来定义函数。 用 let 定义的函数只能在 let 表达式中有效如果想定义在整个程序中有效的函数定义需要用到全局定义表达式——define。 示例 (define double (lambda (x) ( x x))) (double 12) ; return 24 (double (* 3 4)) ; return 24 说明define表达式定义了全局有效的函数 double。两次调用double的返回值都是 24。 定义函数的简写 用 define 定义的函数的语法可以简化即将 lambda 去掉。即将语法 (define var0 (lambda (var1 ... varn) e1 e2 ...)) 简写为 (define (var0 var1 ... varn) e1 e2 ...) 示例 (define (double x) ( x x)) (double 12) ; return 24 (double (* 3 4)) ; return 24 说明本例是前一个例子的简化版本。更简介明了。 顺序计算表达式 语法(begin exp1 exp2 ...) 说明顺序执行表达式 exp1, exp2, ...返回最后一个表达式的结果 示例 (define x 3) (begin (set! x ( x 1)) ( x x)) ; 返回结果 8 说明begin 表达式依次先用set!表达式为x赋值为4在运算xx返回结果8。 条件表达式 关系运算符 ( -1 0) #t ( -1 0) #f (eqv? a a) #t 逻辑运算 (not #t) #f (not #f) #t (not 1) #f (not (a b c)) #f (or) #f (or #f) #f (or #f #t) #t (or #f a #f) a (and) #t (and #f) #f (and #f #t) #f (and #f a #f) #f (and a #t b) b if 表达式 语法(if test consequent alternative) 说明如果test表达式为真返回 consequent否则返回 alternative。 示例 (define (abs n) (if ( n 0) (- 0 n) n)) 说明函数abs功能为取绝对值。 cond 表达式 语法(cond (test exp) ... (else exp)) 说明多路分支判断表达式类似于C语言的 if ... else if ... else。 示例 (define abs (lambda (n) (cond (( n 0) 0) (( n 0) (- 0 n)) (else n)))) 说明用cond表达式重新实现取绝对值函数 abs。 case 表达式 语法(case exp0 clause1 clause2 ... ) clause 的语法结构为((key1 ...) exp1 ...) 最后一个表达式的结构可以为(else exp1 exp2 ...) 说明类似于C语言的 switch ... case... 语句。 示例 (let ((x 4) (y 5)) (case ( x y) ((1 3 5 7 9) odd) ((0 2 4 6 8) even) (else out-of-range))) ; 返回 odd 说明case 表达式先计算 xy 的值为9接下来在key中进行匹配并返回对应的表达式的值 odd。 循环 do 表达式 语法(do ((var1 val1 update1) ...) (test res ...) exp ...) 说明类似于C语言的for循环。先将val1赋值给var1...之后循环开始在每次循环的开始先执行表达式 test如果返回布尔值真则循环终止并返回结果 res如果表达式 test返回布尔值#f则运行表达式 exp...之后依次用 update1 ... 的值来为变量 var1 ... 重新赋值。 示例1计算阶乘 n! n*(n-1)! (define factorial (lambda (n) (do ((i n (- i 1)) (a 1 (* a i))) ((zero? i) a)))) (factorial 10) ; 返回 3628800 说明其对应的C语言实现如下 long factorial(int n) { int in; long a1; for (in;; i--) { if (i 0) return a; a * i; } } 示例2计算fibonacci数列f(n1)f(n)f(n-1) , n0, f(1)1, f(0)0 (define fibonacci (lambda (n) (if ( n 0) 0 (do ((i n (- i 1)) (a1 1 ( a1 a2)) (a2 0 a1)) (( i 1) a1))))) (fibonacci 6) ; 返回 8 说明其对应的C语言实现如下 long fibonacci(int n) { long f1; int i n; int a1 1; int a2 0; if (n 0) return 0; while(1) { if (i 1) return a1; i--; a1a1a2; a2a1; } } map 表达式 语法(map procedure list1 list2 ...) 说明列表 list1 list2 ... 必须具有同样的长度过程 procedure 接受的参数个数同列表的个数各个列表中对应的变量分别作为过程 procedure 的参数被执行 将每次的运算结果以列表形式返回。 (map abs (1 -2 3 -4 5 -6)) ; 返回 (1 2 3 4 5 6)abs接受一个参数 (map (lambda (x y) (* x y)) (1 2 3 4) (8 7 6 5)) 返回(8 14 18 20) lambda (x y) 接收两个参数 for-each 表达式 语法(for-each procedure list1 list2 ...) 说明同 map表达式 但是不返回结果列表。 转载于:https://my.oschina.net/zhoukuo/blog/349453