`
lobin
  • 浏览: 382767 次
  • 性别: Icon_minigender_1
  • 来自: 上海
社区版块
存档分类
最新评论
阅读更多

简介

#null

 

> (if #null (display "not null") (display "null"))
null$33 = "null"


> (#null)
#(#(quote #null))


  ====================================
java.lang.NullPointerException

> (if (#null) (display "not null") (display "null"))
#(#(quote #null))


  ====================================
java.lang.NullPointerException

 

 

向量

向量通过vector定义,还可以通过make-vector定义。向量长度指定后不可再改变。

 

定义一个空的向量:

> (vector)
$61 = #()

定义一个长度为8的向量:

> (define vct (make-vector 8))
$76 = #(#null #null #null #null #null #null #null #null)

  

填充:

> (define vct (make-vector 8))
$76 = #(#null #null #null #null #null #null #null #null)

> (vector-fill! vct 0)
$78 = #!undefined

> vct
$79 = #(0 0 0 0 0 0 0 0)

 

 

定义一个包含3个元素(数字)的向量:

> (vector 4 5 6)
$50 = #(4 5 6)

 

向量中包含向量:

> (vector 1 2 3 (vector 4 5 6) 7 8 (vector 9 0))
$49 = #(1 2 3 #(4 5 6) 7 8 #(9 0))

 

 

根据下标获取元素:

> (define vct (vector 1 2 3 4))
$39 = #(1 2 3 4)

 

> (vector-ref vct 0)
$43 = 1

> (vector-ref vct 1)
$44 = 2

> (vector-ref vct 2)
$45 = 3

> (vector-ref vct 3)
$46 = 4

> (vector-ref vct 4)
#({vector-ref} {vct} #(quote 4))


  ====================================
java.lang.ArrayIndexOutOfBoundsException: 4

 

设置指定下标的元素:

> (vector-set! vct 0 9)
$47 = 9

> vct
$48 = #(9 2 3 4)

 

列表

> (list 1 2 3 4)
$112 = (1 2 3 4)

> '(1 2 3 4)
$113 = (1 2 3 4)

car

 

cdr 

 

cdar

cdar函数顾名思义就是car+cdr,它先是对列表进行car求值,在对得到的结果进行cdr求值操作。cdar的参数为list,需要注意的是,参数list的第一个元素也必须是一个list,如下:

 

> (cdar
    (list
      (list 1 2 3 4) 5 6))
$10 = (2 3 4)

 

list-ref

定义如下:

((list-ref L N ) returns the (N+1)st element of L. So (list-ref L 0) returns the first element of L.

用于取list的第N+1个元素,或者理解为根据元素在list中的下标位置取值。

> (list-ref (list #'a' #'b' #'c' #'d') 0)
$16 = #'a'

> (list-ref (list #'a' #'b' #'c' #'d') 1)
$17 = #'b'

> (list-ref (list #'a' #'b' #'c' #'d') 2)
$18 = #'c'

 需要说明的是,这里的N在指定为负数的时候,它取得还是第1个元素。另外list L必须为一个非空的list,否则会提示错误:expected object of type pair(i.e. non-empty list), but got: , "()"。

> (list-ref (list #'a' #'b' #'c' #'d') -2)
$13 = #'a'

> (list-ref (list #'a' #'b' #'c' #'d') -1)
$14 = #'a'

 

如果N大于等于list长度时,会提示错误:expected object of type pair(i.e. non-empty list), but got: , "()"

> (list-ref (list #'a' #'b' #'c' #'d') 4)
#({list-ref}
  #({list}
    #(quote #\a)
    #(quote #\b)
    #(quote #\c)
    #(quote #\d))
  #(quote 4))


  ====================================
SchemeException: expected object of type pair(i.e. non-empty list), but got: , "()"

 

 

list-tail

返回从N+1个元素开始的列表。

(list-tailL N ) returns the list obtained by removing the first N elements from L

 

 

取最后一个元素

> (let
    ((lst (list 1 2 3 4 5 6 7 8 9)))
    (list-tail
      lst
      (-
        (length lst) 1)))
$14 = (9)

 

上面实际上返回的是以最后一个元素组成的列表。如果需要返回的是元素,可以这样:

> (let
    ((lst (list 1 2 3 4 5 6 7 8 9)))
    (car
      (list-tail
        lst
        (-
          (length lst) 1))))
$15 = 9

 

 

member函数

 

判断是否是list成员,member函数定义如下:

 

 

(member x L) return #t if x is a member of the list L
 这里的定义说明并不准确, 它的返回值并不是“如果x是L的其中一个,则返回#t”。其返回值说明应该是:如果x不是L的其中一个,则返回#f。否则: 如果x是L的其中一个,则返回“the first pair of list whose car is object”, 也就是返回包括x及后面的成员的一个列表。参考附加说明, 和member函数类似的还有memq、memv函数。
附加说明:

 

 

procedure: memq object list
procedure: memv object list
procedure: member object list
These procedures return the first pair of list whose car is object; the returned pair is always one from which list is composed. If object does not occur in list, #f (n.b.: not the empty list) is returned. memq uses eq? to compare object with the elements of list, while memv uses eqv? and member uses equal?.(10)
(memq 'a '(a b c))                      =>  (a b c)
(memq 'b '(a b c))                      =>  (b c)
(memq 'a '(b c d))                      =>  #f
(memq (list 'a) '(b (a) c))             =>  #f
(member (list 'a) '(b (a) c))           =>  ((a) c)
(memq 101 '(100 101 102))               =>  unspecified
(memv 101 '(100 101 102))               =>  (101 102)
 

 

 

> (if (member 1 (list 1 2 3 4)) (display "yes"))
yes$94 = "yes"

> (if (member 6 (list 1 2 3 4)) (display "yes"))
$95 = #f

 

 

> (member 1 (list 1 2 3 4))
$110 = (1 2 3 4)

 

类似的,获取元素在列表中的下标位置:

> (define fx
  (lambda
    (lst e)
    (set! e
      (let
        ((i -1))
        (do
          ((j 0 (+ j 1)))
          ((>= j (length lst)))
          (if
            (eqv? (list-ref lst j) e)
            (set! i j)))
        i))
    e))
$18 = (lambda ?? (lst e)...)

> (fx (list 9 8 7 6 5 4 3 2 1) 8)
$19 = 1

 

 

member函数用于vector的话,无效:

> (member 1 (vector 1 2 3 4))
$114 = #f

> (member 6 (vector 1 2 3 4))
$115 = #f

> (if (member 1 (vector 1 2 3 4)) (display "yes"))
$117 = #f

> (if (member 6 (vector 1 2 3 4)) (display "yes"))
$118 = #f

 也不报错。

 

assoc

类似将list当成key-value形式的map操作的函数,类似map的根据key取value的操作:

(assoc x alist) alist is a list of pairs (key value), if x is one of those keys, the value is returned. equal? is used to compare x and key.

 需要注意的是, list中的元素也必须是list, 并且元素不允许为空的list。

 

> (assoc #'a' (list (list #'a') (list #'b') (list #'c') (list #'d') (list #'e')))
$20 = (#'a')

> (assoc #'a' (list (list #'a' 1) (list #'b' 2) (list #'c' 3) (list #'d' 4) (list #'e' 5)))
$21 = (#'a' 1)

 

> (assoc #'x' (list (list #'a') (list #'b') (list #'c') (list #'d') (list #'e')))
$22 = #f

> (assoc #'x' (list (list #'a' 1) (list #'b' 2) (list #'c' 3) (list #'d' 4) (list #'e' 5)))
$23 = #f

 

如果list的元素出现空的list时, 会提示出错:expected object of type pair(i.e. non-empty list), but got: , "()"

 

> (assoc #'c' (list (list #'a') (list)))
#({assoc}
  #(quote #\c)
  #({list} #({list} #(quote #\a)) #({list})))


  ====================================
SchemeException: expected object of type pair(i.e. non-empty list), but got: , "()"

  

 

 

但其实跟map是不一样的, 如下面的例子:

第1个form在构造key-value是,key为#‘c’有两个, 但在取值时只能渠道第1个。所以构造key-value时本质上它还是list结构, 只是assoc取值行为有点类似key-value map。

 

> (assoc #'c' (list (list #'a' 1) (list #'b' 2) (list #'c' 3) (list #'d' 4) (list #'e' 5) (list #'c' 6)))
$47 = (#'c' 3)

> (assoc #'c' (list (list #'a' 1) (list #'b' 2) (list #'d' 4) (list #'e' 5) (list #'c' 6)))
$48 = (#'c' 6)

 

 

set!函数

 

(set! VAR EXPR) -- Here VAR must be a global or local scheme variable or a Java Literal representing a static Java variable. In each case, the EXPR is evaluated and its value is assigned to the variable.

 函数说明: 赋值操作。

 

其实应该叫绑定操作,或者如set原意设置操作。对EXPR进行求值后, 将VAR绑定到所求的值。需要特别说明的是,如果VAR事先还没定义(参考define), 则先define,然后求值绑定。

 

> (define x 100)
$193 = 100

> (set! x "101大厦")
$194 = "101大厦"

> x
$195 = "101大厦"

 

 

 

> aaac
SchemeException: ERROR: undefined variable "aaac"
        at jsint.E.error(E.java:14)
        at jsint.E.error(E.java:19)
        at jsint.DynamicVariable.getDynamicValue(DynamicVariable.java:27)
        at jsint.Evaluator.execute(Evaluator.java:361)
        at jsint.Evaluator.eval(Evaluator.java:283)
        at jsint.Evaluator.eval(Evaluator.java:272)
        at jsint.Evaluator.readEvalWriteLoop(Evaluator.java:129)
        at jsint.Evaluator.runJscheme(Evaluator.java:106)
        at jsint.Scheme.runJscheme(Scheme.java:170)
        at jsint.Scheme.defaultMain(Scheme.java:134)
        at jsint.Scheme.main(Scheme.java:109)
        at jscheme.REPL.main(REPL.java:156)
> (set! aaac 1)
$188 = 1

> aaac
$189 = 1
 

 

> sn2
SchemeException: ERROR: undefined variable "sn2"
        at jsint.E.error(E.java:14)
        at jsint.E.error(E.java:19)
        at jsint.DynamicVariable.getDynamicValue(DynamicVariable.java:27)
        at jsint.Evaluator.execute(Evaluator.java:361)
        at jsint.Evaluator.eval(Evaluator.java:283)
        at jsint.Evaluator.eval(Evaluator.java:272)
        at jsint.Evaluator.readEvalWriteLoop(Evaluator.java:129)
        at jsint.Evaluator.runJscheme(Evaluator.java:106)
        at jsint.Scheme.runJscheme(Scheme.java:170)
        at jsint.Scheme.defaultMain(Scheme.java:134)
        at jsint.Scheme.main(Scheme.java:109)
        at jscheme.REPL.main(REPL.java:156)
> (set! sn2 1 2 3 4 5)
** WARNING: wrong number of arguments for syntax:(set! sn2 1 2 3 4 5)
$191 = 1

> sn2
$192 = 1

  

 

 

比较

jscheme用来比较的form有很多,有 (< x y ), (<=x y ), (= x y), (> x y ), (>= x y ), (eq? A B), (equal? x y),(eqv? A B)等。

 

前面几个(< x y ), (<=x y ), (= x y), (> x y ), (>= x y ) 只能用于数字比较,后面几个(eq? A B), (equal? x y),(eqv? A B)可以用于任何类型的比较,但比较的方式有些差异。

equal?

 

 

(equal? x y) returns #t if x and y are both #null or represent the same numbers, or are ".equals" as Java objects, or are lists whose corresponding elements are "equal?", or are arrays whose corresponding elements are "equal?". or are
 

 

 

> (equal? #null #null)
$12 = #t

 

eqv?

 

 

((eqv? A B) ) returns #t if x and y are both #null or represent the same numbers, or are ".equals" as Java objects.
 

 

 

> (eqv? #null #null)
$13 = #t

 

更复杂的一个例子:

> (eqv? (vector-ref #((0 1 ()) #null (10 0 ()) #null (30 0 ()) (100 0 ()) #null) 0) #null)
$217 = #f

> (eqv? (vector-ref #((0 1 ()) #null (10 0 ()) #null (30 0 ()) (100 0 ()) #null) 1) #null)
$218 = #t

 

 

eq?

 

 

((eq? A B) ) returns #t when A and B are both #null or when they are both the same object
 

 

 

> (eq? #null #null)
$14 = #t

 

 

> (= 1 1)
$2 = #t

> (= 1 2)
$3 = #f

 

字符比较

> (char=? #'a' #'b')
$6 = #f

> (char=? #'a' #'a')
$7 = #t

 

 

> (.equals #'a' #null)
$19 = #f

 这个是调用java的equals方法来比较字符串。

 

> (.equals #null #'a')
#({.equals} #(quote #null) #(quote #\a))


  ====================================
java.lang.NullPointerException

 

> (.equals #null #null)
#({.equals} #(quote #null) #(quote #null))


  ====================================
java.lang.NullPointerException

 

 

比较java对象

> (eq? (Object.) (Object.))
$15 = #f

> (equal? (Object.) (Object.))
$16 = #f

> (eqv? (Object.) (Object.))
$17 = #f

  

 eq?

 

> (eq? (lambda (x) x) (lambda (y) y))
$18 = #f

> (eq? (lambda (x) x) (lambda (x) x))
$19 = #f

> (define fx1 (lambda (x) x))
$20 = (lambda ?? (x)...)

> (define fx2 (lambda (y) y))
$21 = (lambda ?? (y)...)

> (eq? fx1 fx2)
$22 = #f

 

if

定义如下:

(if EXPR1 EXPR2 EXPR3) -- this first evaluates EXPR1 to get a value V. If V is equal to the boolean value #f, then EXPR2 is evaluated, otherwise EXPR3 is evaluated.

以上定义是从一种scheme实现的文档而来。从定义来看, if先对EXPR1求值得到V,如果V为#f,将对EXPR2求值, 否则对EXPR3求值。

 

这里有个地方不准确, 应该是:

 

“如果V不为#f,将对EXPR2求值, 否则对EXPR3求值。”

“如果V不为#null,将对EXPR2求值, 否则对EXPR3求值。”

 

或许这样理解更为合适:

“如果V为一个有效的评估值(为#t或者不为#null),将对EXPR2求值, 否则对EXPR3求值。”

 

另一种定义:

(if EXPR1 EXPR2) -- this is implemented as (if EXPR1 EXPR2 #f)

 

 

> (if #null (display "a") (display "b"))
b$180 = "b"

> (if (list 1 2 3) (display "list") (display "not list"))
list$181 = "list"

 

更复杂的一个例子:

> (let ((i -1) (lst (list #'a' #'b' #'c' #'d' #'e'))) (if (and (not (= i -1)) (not (eqv? (list-ref lst i) #null))) (display "test 1") (display "test 2")))
test 2$22 = "test 2"

> (let ((i 1) (lst (list #'a' #null #'c' #'d' #'e'))) (if (and (not (= i -1)) (not (eqv? (list-ref lst i) #null))) (display "test 1") (display "test 2")))
test 2$23 = "test 2"

> (let ((i 0) (lst (list #'a' #null #'c' #'d' #'e'))) (if (and (not (= i -1)) (not (eqv? (list-ref lst i) #null))) (display "test 1") (display "test 2")))
test 1$24 = "test 1"

 

 

 do 循环控制

 

(do ((lst 
      (list 1 2 3 4 5 6)
      )) 
    ((<= (length lst) 0))
    (display (car lst)) 
    (newline)
    (set! lst (cdr lst)))
    
    
(do ((lst 
      (list 1 2 3 4 5 6)
      (set! lst (cdr lst))
      )) 
    ((<= (length lst) 0))
    (display (car lst)) 
    (newline))
    
    
(define lst (list 1 2 3 4 5 6))
(do () 
    ((<= (length lst) 0))
    (display (car lst)) 
    (newline)
    (set! lst (cdr lst)))

 

返回值

 

 

> (define fx
    (lambda
      (e)
      (for-each
        (lambda
          (i)
          (if
            (= (list-ref i 0) e)
            (begin
              (display (string-append "found: " (list-ref i 1)))
              (newline)
              (list-ref i 1))))
        (list (list 1 #'a') (list 2 #'b') (list 3 #'c') (list 4 #'d') (list 5 #'e') (list 6 #'f') (list 7 #'g')))))
$48 = (lambda ?? (e)...)
 以上fx函数返回的是什么?

 

 

> (fx 3)
found: c
$49 = ()
 不管传入什么参数,返回的都是一个空的form:().上面fx函数返回值就是(for-each ...)的返回值。

 

 

> (define v (for-each (lambda (x) x) (list 1 2 3)))
$50 = ()

> v
$51 = ()

 

 以上函数fx如果想要返回输入数字对应的字母, 可以改成这样:

(define fx
    (lambda
      (e)
      (let 
        ((r #null))
        (for-each
          (lambda
            (i)
            (if
              (= (list-ref i 0) e)
              (begin 
                (display (string-append "found: " (list-ref i 1)))
                (newline)
                (set! r (list-ref i 1)))))
          (list (list 1 #'a') (list 2 #'b') (list 3 #'c') (list 4 #'d') (list 5 #'e') (list 6 #'f') (list 7 #'g')))
        r)))

 

> (fx 1)
found: a
$56 = #'a'

> (fx 2)
found: b
$57 = #'b'

> (fx 3)
found: c
$58 = #'c'

> (fx 4)
found: d
$59 = #'d'

> (fx 5)
found: e
$60 = #'e'

> (fx 6)
found: f
$61 = #'f'

> (fx 7)
found: g
$62 = #'g'

> (fx 8)
$63 = #null

scheme def, let and bind

 

 

> (let () ())

$30 = ()

返回一个空的form: ()

 

> (list? (let () ()))

$31 = #t

list?检查返回的()是否是一个列表, 这里认为()是一个空列表。

 

> ()

$32 = ()

 

> (list? ())

$33 = #t

 

 

> (define x

    (let

      ((a "this is a"))

      a))

 

> x

$22 = "this is a"

 

 

0
1
分享到:
评论

相关推荐

    jscheme:Jscheme(方案(在Java中,由Peter Norvig编写))

    Jscheme(方案(在Java中,由Peter Norvig编写)) 这是在找到的代码。 在第一次提交期间,它已准备好在IntelliJ中执行,并略微格式化为更现代的编码标准。 提交为“首次提交”的所有代码均由Peter Norvig编写,并...

    jscheme:用于浏览器和节点的小型简单对象架构库

    基本用法这是一个最简单的示例,用于验证具有一个必须为字符串的属性的对象: // Add a schema.jScheme . add ( 'person' , { name : 'string'} ) ;// Validate a valid object against our first schema.jScheme . ...

    JSchemeMin是一个JVM平台上的Scheme语言实现

    JSchemeMin 是一个JVM平台上的Scheme语言实现。 作为R7RS的实现,JSchemeMin支持Scheme的所有标准特性,包括头等公民地位的过程、尾递归优化、继续、用户定义记录、库(包括R7RS附录A中全部语法和过程,不只base)、...

    The Jscheme Web Programming Project-开源

    在这个项目中,我们旨在开发用于开发各种Web应用程序(尤其是Servlet和基于xml的Web服务)的方案库。 我们的方法是使用jscheme(Java方案的开源实现)作为核心语言,

    zClipse-开源

    zClipse是一个用于构建Eclipse(http://www.eclipse.org)插件的项目。 当前正在开发的插件包括:TabNavigator-编辑器增强; JScheme-方案整合; Insectivore-共享的TeamTasks,与Tasks视图集成。

Global site tag (gtag.js) - Google Analytics