LOOP宏循环

; 1LOOP;组成部分 
;一个loop中可以做的事情:
;以数值或多种数据结构为步长做循环
;;循环过程中收集,计数,求和,求最大,求最小
;;;执行任意LISP表达式
;;;;决定何时终止循环
;;;;;条件执行上述内容
 
;提供下列事务语法:
;创建用于循环内部的局部变量
;指定任意LISP表达式在循环开始前和结束后执行
 
; 2迭代控制
; 大多数以for或者它的同义词as开始,紧接着一个变量
; 可以多个for子句,其中一个结束,循环就结束
; for子句的迭代:
;数字范围(上下)
;;由单独的项组成的列表
;;;构成列表的点对单元
;;;;向量的元素(字符串,位向量)
;;;;;哈希表的键值对
;;;;;;包中的符号
;;;;;;;对给定形式反复求值得到的结果
 
; 3计数型循环
; for或as 变量 起始介词 起点 终止介词 终点 步长介词by 步长
; 起始介词from,upfrom,downfrom
; 终止介词to,upto,downto,below,above .below,above会提前一次结束循环
; 步长是正数,默认1
; 递增循环起点默认是0,必须至少指定一个介词;递减循环无默认值必须指定,否则报错
(loop for i from 1 to 5 collect i);(1 2 3 4 5)
; (loop for i from 1 to 5)等价于(repeat 5)
(loop for i from 1 below 5 collect i);(1 2 3 4)
(loop for i downfrom 10 above 2 by 2 collect i);(10 8 6 4)
(loop for i upto 4 collect i );(0 1 2 3 4)
 
; 4循环集合和包
; for子句循环列表的介词只有on in
; in在列表元素上推进var
; for var in list-from
(loop for var in (list 1 2 3) collect var);(1 2 3)
; by默认值cdr,也可以是接受一个列表返回其子列表的函数
; 收集相隔元素
(loop for var in (list 1 2 3) by #'cddr collect var);(1 3)
; on在构成列表的点对单元上推进var
; for var on list-from
(loop for var on (list 1 2 3) collect var);((1 2 3) (2 3) (3))
(loop for var on (list 1 2 3 4) by #'cddr collect var);((1 2 3 4) (3 4))
 
; 以上针对列表,针对向量(字符串和位向量)介词是across
(loop for var across "abc" collect var);(#\a #\b #\c)
 
; 迭代哈希表和包,模式如下:
(loop for var being the things in hash-or-package ...)
; 对于哈希表来说,things可以是hash-key hash-value hash-keys hash-values
; 对于包来说things可以是symbols present-symbols external-symbols symbol present-symbol external-symbol
; symbols可访问的
; present-symbols当前存在的(包里的和导入进来的)
; external-symbols从该包导出的
 
; the 同义词 each 
; in 同义词 of
 
; 同时迭代2个元素,using子句必须是单数形式
(loop for k being the hash-key of *h* using (hash-value v)...)
(loop for v being each hash-value in *h* using (hash-key k)...)
 
; 5等价然后迭代
(loop for var = initial-value-form [then step-form])
; var在首次迭代之前求值initial-value-form得到。
; 后续迭代var的通过step-form求值得到,如果没有step-form求值initial-value-form
(loop repeat 5
            for x = 0 then y
            for y = 1 then (+ x y)
            collect y);(1 2 4 8 16)
(loop repeat 5
            for y = 1 then (+ x y)
            for x = 0 then y
            collect y);(1 1 2 4 8)
(loop repeat 5
            for x = 0 then y
            and y = 1 then (+ x y)
            collect y);(1 1 2 3 5)菲波尼奇序列,步长在赋值之前计算完毕
 
; 局部变量with [var = value-form] 
; 结构变量
(loop for (a b) in '((1 2) (3 4) (5 6))
    do (format t "a:~a;b~a%%" a b))
(loop for (a nil) in '((1 2) (3 4) (5 6)) collect a);忽略其他元素
 
(loop for c on list
    do (format t "~a" (car c))
    when (cdr c) do (format t ", "))
 
(loop for (item . rest) on list
    do (format t "~a" item)
    when rest do (format t ", "))
 
; 8值汇聚
; verb form [into var]
; 没有into子句,结果作为循环的结果返回。
; verb有collect append nconc count sum maximize minimize
; 同义词是collecting appending nconcing counting summing maximizing minimizing
; append nconc所汇聚的值本身也是列表
(defparameter *rand* (loop repeat 100 collect (random 10000)))
(loop for i in *rand*
    counting (evenp i) into envens
    counting (oddp i) into odds
    summing i into total
    maximizing i into max
    minimizing i into min
    finally (return (list envens odds total max min)))
 
; 9无条件执行(do和return子句)
; do 或者doing子句
(loop for i from 1 to 10 do (print i))
; do后面可以接多个lisp表达式,在1次循环里逐个被求值
; 结束于loop闭括号或者下一个关键字
 
; return 子句
; return后面接单个lisp表达式,作为当前整个循环的结果返回
; 区别于常规操作符return return-from,do子句中使用这些常规操作符
; 可以从任意封闭中返回
(block outer
    (loop for i upto 100 return 100);return from loop
    (print "this will printed")
    200);200
 
(block outer
    (loop for i upto 100 do (return-from outer 100));return from block
    (print "this will not printed")
    200);100
 
; 10条件执行
; 以前的方法,do子句里面使用if when
(loop for i upto 10 (when (evenp i) (print i)))
; 循环子句层面conditional test-form loop-clause
; conditional 是if when unless
; loop-clause 是值汇聚子句或者无条件执行或者另一个条件执行子句
; 多个循环子句可用and 连接起来
(loop for i upto 10 when (evenp i) sum i)
; 在第一个循环子句里,测试子句后,可以用it指代测试子句的返回值
(loop for key in som-list when (gethash key some-hash) collect it)
; 测试子句每次循环都计算,if when 当真时执行,unless 当nil时执行
(loop for i from 1 to 100
            if (evenp)
                minimize i into min-even and
                maximize i into max-even and
                unless (zerop (mod i 4))
                    sum i into even-not-fours-total
                end
                and sum i into even-total
            else
                minimize i into min-odd and
                maximize i into max-odd and
                unless (zerop (mod i 5))
                    sum i into odd-not-fives-total
                end
                and sum i into odd-total
            do (update-analysis min-even
                                                    max-even
                                                    even-not-fours-total
                                                    even-total
                                                    min-odd
                                                    max-odd
                                                    odd-not-fives-total
                                                    odd-total))
 
; 11设置和拆除
; 其他语言:循环前初始化 序言
; 循环
; 循环后扫尾 尾声
; initially子句,循环开始前执行
; finally子句,循环结束后执行
; 都可以引用局部循环遍历,循环迭代了0次,序言也执行
; 不执行尾声的情况:
; 1执行了return子句
; 2return return-from语句
; 3循环被一个always thereis never终止
; 在尾声部分可以用return return-from提供显式的返回值,
; 这个值比其他值汇聚活终止子句的值优先级高
; 带名称的循环,loop第一个子句named
(loop named outer for list in lists do
    (loop for item in list do
        (if (what-i-find-item item)
            (return-from outer item))))
 
; 12终止测试
; 终止子句until while always never thereis
; 使用方式loop-keyword test-form
; while until 是温和的,他们终止循环,将控制权交给finally
; 另外一个温和的终止形式是loop-finish宏,不是loop子句
; 可以用在do出现的地方,立即调到循环的尾声部分
 
; always never thereis很极端,结束循环,跳过尾声,她为整个循环提供默认返回值
; 于有自己的返回值,不能跟汇聚子句同用,除非汇聚子句用into
(if (loop for i in numbers always (evenp i))
    (format t "all numbers are even"))
(if (loop for i in numbers never (oddp i))
    (format t "all numbers are even"))
 
; thereis测试子句曾经为真,一旦非nil返回该值结束循环
(loop for char across "abc1230" thereis (digit-char-p char));1
(loop for char across "abcdddd" thereis (digit-char-p char));nil
 
 
; loop总结
; 1如果有named子句,必须第一个
; 2named后面是initially with for repeat
; 3然后是主体子句:有条件无条件执行,汇聚,终止测试
; 4finally结束
 




posted @ 2012-04-20 16:25  舜耕山翁  阅读(576)  评论(0编辑  收藏  举报