《Chez Scheme初探》定义变量、递归、测试性能、并列代码编写

简介:html

Chez Scheme与DrRacket相似,都是Scheme语言家族,其编程总体思路跟传统语言有很大区别。其语言结构主要采用递归的形式,顺序执行语句内容须要使用begin关键词。使用define语句来定义变量和函数,使用let语句来绑定某个变量的值并规定做用域,使用time来统计语句运行的时间。java

; 注释形式,使用分号

; 四则运算
(+ 1 2)   ; 3
(- 5 1)   ; 4
(* 4 3)   ; 12
(/ 4 2)   ; 2

; 条件判断
(= 2 3)   ; #f

; 变量定义
(define a 3)

; 变量赋值
(set! a 6)

字符串以及symbol(不可变字符串,带'号的字母)node

; 建立字符串
"awefawef"
; 定义字符串
(define a "awefawef")
; 使字符串中全部字符变为大写
(string-upcase "awefawef")

; 建立symbol(不可变的字符串)
'awefawef
; 定义symbol
(define a 'awefawef)

相互转换:
(symbol->string 'Apple)    ;"Apple"
(string->symbol "Apple")   ;'Apple

函数定义以及操做python

; 定义函数
(define (func1 x) (string-upcase x))
; 使用函数
(func1 "awer")
; 在map中使用函数
(map func1 a)

list数据结构(相似java的ArrayList),是一种链表结构。但跟传统的arraylist不一样,它的append方法不改变原来的变量,只返回修改后的listapache

; 建立list数据结构
(list "red" "green" "blue")
; 定义list数据结构变量
(define a (list "red" "green" "blue"))
; 查看list长度
(length (list 1 2 3 4))
; 取出list中第2个元素
(list-ref (list 'a 'b 'c) 2)  ; 结果为'c


; 遍历list(使用map函数)
(map (lambda (x) (string-upcase x)) (list "red" "green" "blue"))


; 取元素相关操做
(car (list 1 2 3))  ; 取第一个元素,结果为1
(cdr (list 1 2 4))  ; 取第二个及之后元素,结果为(2 4)

; 改元素相关操做:
; Don’t confuse cons and append. The cons function takes an element and a list, 
; while append takes a list and a list. That difference is reflected in their types:
(cons 1 '(2 3))             ; 元素和表一块儿合并成一个新表,并返回
(append '(1 2) '(3 4))      ; 表和表一块儿合并成一个新表,并返回

vector数据结构(相似Java的数组),与list的区别详解(6.6.10 Vectors编程

; 建立vector
(vector 'a 'b)  ; 输出结果为#(a b)
(define v1 (vector 'a 'b))
; 取出vector第0个元素
(vector-ref v1 0)  ; a
; 修改第0个元素
(vector-set! v1 0 'c)

; 相互转换
(vector->list vec)
(list->vector lst)

操做哈希表数组

> (define a make-hash-table)  ; 注意区别,不在make-hash-table两旁加括号的话,系统会认为你是把这个函数赋值给a,而不是把函数的执行结果赋值给a
> a
#<procedure make-hash-table>
> (define ht (make-hash-table))
> ht
#<eq hashtable>
; 往表中添加(或修改)元素
(put-hash-table! ht 'b "wtf")  ; 注意感叹号别漏了
; 使用key获取对应元素,该实例是获取'b这个key对应的元素,而最后一个参量是指获取失败的时候返回的默认值。
(get-hash-table ht 'b #f)
; 获取key的vector(返回值是一个vector类型,长得像这样#(a b c))
(hashtable-keys ht)
; 获取value的vector(返回值是一个vector类型,长得像这样#(a b c))
(hashtable-values ht)

普通fib函数bash

(define (fact n) (if (= n 1) 1
                             (* n (fact (- n 1))  )
                 )
)

尾递归fib函数数据结构

(define (fact-tail n) (fact-rec n n))
(define (fact-rec n p) (if (= n 1) p
                                   (let ( (m (- n 1)) ) 
                                        (fact-rec m (* p m))
                                   )
                       )
)

性能测试app

(let ([a 120000]) (begin (time (begin (fact a) (+ 30 3) )) (time (begin (fact-tail a) (+ 30 3) ))))

测试结果:

(time (begin (fact a) ...))
    115 collections
    11.843750000s elapsed cpu time, including 0.031250000s collecting
    11.867882300s elapsed real time, including 0.040223800s collecting
    13241981264 bytes allocated, including 13012956832 bytes reclaimed
(time (begin (fact-tail a) ...))
    229 collections
    9.796875000s elapsed cpu time, including 0.062500000s collecting
    9.816385400s elapsed real time, including 0.084685200s collecting
    14538387792 bytes allocated, including 14538258416 bytes reclaimed
33

机器:

CPU:i7-8550U  内存24GB

 

后记:

初学scheme类语言会遇到一个比较混淆的东西,就是set!、define、let的区别,以后会进行深刻的探讨和讲解

输出结果中带井号的标识符具体含义

参考racket的数据类型

DATA STRUCTURE   ACCESS       NUMBER     INDICES
List:            sequential   Variable   not used
Struct:          random       Fixed      names
Vector:          random       Fixed      integer
Growable vector: random       Variable   integer
Hash:            random       Variable   hashable
Splay:           random       Variable   non-integer, total order