cwa*_*ole 10 lisp clisp common-lisp land-of-lisp
我已经阅读了很多关于Land of Lisp的好东西,所以我想我可以通过它来看看有什么可看的.
(defun tweak-text (lst caps lit)
(when lst
(let ((item (car lst))
(rest (cdr lst)))
(cond
; If item = space, then call recursively starting with ret
; Then, prepend the space on to the result.
((eq item #\space) (cons item (tweak-text rest caps lit)))
; if the item is an exclamation point. Make sure that the
; next non-space is capitalized.
((member item '(#\! #\? #\.)) (cons item (tweak-text rest t lit)))
; if item = " then toggle whether we are in literal mode
((eq item #\") (tweak-text rest caps (not lit)))
; if literal mode, just add the item as is and continue
(lit (cons item (tweak-text rest nil lit)))
; if either caps or literal mode = true capitalize it?
((or caps lit) (cons (char-upcase item) (tweak-text rest nil lit)))
; otherwise lower-case it.
(t (cons (char-downcase item) (tweak-text rest nil nil)))))))
Run Code Online (Sandbox Code Playgroud)
(评论是我的)
(仅供参考 - 方法签名(list-of-symbols bool-whether-to-caps bool-whether-to-treat-literally)但作者将这些缩短为(lst caps lit).)
但无论如何,这里有一个问题:
这里面有(cond... (lit ...) ((or caps lit) ...)).我的理解是,这将转换为if(lit){ ... } else if(caps || lit){...}C风格的语法.这个或陈述不是多余的吗?是否存在(or caps lit)如果上限是调用条件的情况nil?
我会把它写成:
(defun tweak-text (list caps lit)
(when list
(destructuring-bind (item . rest) list
(case item
((#\space) (cons item (tweak-text rest caps lit)))
((#\! #\? #\.) (cons item (tweak-text rest t lit)))
((#\") (tweak-text rest caps (not lit)))
(otherwise (cond (lit (cons item (tweak-text rest nil lit)))
(caps (cons (char-upcase item)
(tweak-text rest nil lit)))
(t (cons (char-downcase item)
(tweak-text rest nil nil)))))))))
Run Code Online (Sandbox Code Playgroud)
CASE语句将调度该角色.然后COND声明处理其他条件.CASE与EQL进行比较.这意味着CASE也适用于角色,甚至可以与多个项目进行比较.我也是代码布局样式的粉丝,它排列了相应的表达式 - 这仅适用于等宽字体.这有助于我在代码中直观地检测模式,并帮助检测可以简化的代码.
DESTRUCTURING-BIND将列表分开.
为了好玩,使用LOOP重写:
(defun tweak-text (list)
(loop with caps and lit
for item in list
when (eql item #\space)
collect item
else when (member item '(#\! #\? #\.))
collect item and do (setf caps t)
else when (eql item #\")
do (setf lit (not lit))
else when lit
collect item and do (setf caps nil)
else when caps
collect (char-upcase item) and do (setf caps nil)
else
collect (char-downcase item) and
do (setf caps nil lit nil)))
Run Code Online (Sandbox Code Playgroud)