简介
#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"
相关推荐
Jscheme(方案(在Java中,由Peter Norvig编写)) 这是在找到的代码。 在第一次提交期间,它已准备好在IntelliJ中执行,并略微格式化为更现代的编码标准。 提交为“首次提交”的所有代码均由Peter Norvig编写,并...
基本用法这是一个最简单的示例,用于验证具有一个必须为字符串的属性的对象: // Add a schema.jScheme . add ( 'person' , { name : 'string'} ) ;// Validate a valid object against our first schema.jScheme . ...
JSchemeMin 是一个JVM平台上的Scheme语言实现。 作为R7RS的实现,JSchemeMin支持Scheme的所有标准特性,包括头等公民地位的过程、尾递归优化、继续、用户定义记录、库(包括R7RS附录A中全部语法和过程,不只base)、...
在这个项目中,我们旨在开发用于开发各种Web应用程序(尤其是Servlet和基于xml的Web服务)的方案库。 我们的方法是使用jscheme(Java方案的开源实现)作为核心语言,
zClipse是一个用于构建Eclipse(http://www.eclipse.org)插件的项目。 当前正在开发的插件包括:TabNavigator-编辑器增强; JScheme-方案整合; Insectivore-共享的TeamTasks,与Tasks视图集成。
Java 平台的影响,包括 Hecl、Jacl、Clojure、Ync/Javascript、Joy、Jv-language、CAL、Aardappel、Funnel、MiniPLAN、SixxBDC Scheme、ABCL、Lisp、PS3i、HotScheme、webLISP、Jaja、JScheme、Skij、Kawauts、...