Commit 42fc807b authored by Joerg-Cyril Hoehle's avatar Joerg-Cyril Hoehle
Browse files

fix defmacro-driver example in manual

darcs-hash:bc746991bd3bbb39b86b4249d2bb71bf6d8f9a3e
parent a1753b81
......@@ -1950,32 +1950,40 @@ Here is the macro:
@lisp
(defmacro-clause (FINDING expr MAXIMIZING func &optional INTO var)
(let ((max-val (gensym))
(temp1 (gensym))
(temp2 (gensym))
"Simple FINDING... MAXIMIZING implementation"
(let ((max-val (gensym "MAX-VAL"))
(temp1 (gensym "EL"))
(temp2 (gensym "VAL"))
(winner (or var iterate::*result-var*)))
`(progn
(with ,max-val = nil)
(with ,winner = nil)
(cond
((null ,max-val)
(setq ,winner ,expr)
(setq ,max-val (funcall ,func ,winner))
(t
(let* ((,temp1 ,expr)
(,temp2 (funcall ,func ,temp1)))
(when (> ,temp2 ,max-val)
(setq ,max-val ,temp2)
(setq ,winner ,temp1))))))
(finally (leave ,winner)))))
(let* ((,temp1 ,expr)
(,temp2 (funcall ,func ,temp1)))
(when (or (null ,max-val) (> ,temp2 ,max-val))
(setq ,winner ,temp1 ,max-val ,temp2))))))
@end lisp
@c This example differs from the built-in finder:
@c - The built-in one specifies the clause's value (el so far)
@c (trivial to implement: add ,winner at end of progn)
@c - The built-in one accepts an (el max-val) tuple var spec.
@c - Influence of (the type var) on type declarations
Note that if no @code{into} variable is supplied, we use
@code{iterate::*result-var*}, which contains the internal variable
into which all clauses place their results. If this variable is bound
by some clause, then @iter{} will return its value automatically;
otherwise, @code{nil} will be returned.
@c The original example had four flaws:
@c - ,expr and ,func occured twice in expansion
@c - (finally (leave ,winner)) breaks because FINALLY does not walk
@c its forms, so LEAVE does not work inside FINALLY.
@c - Do not use (finally (return ,winner)) either, as that would
@c always return winner, even in case of ... INTO nil.
@c - Value of clause as form undefined, unlike all built-in clauses
@menu
* Writing Drivers::
* Extensibility Aids::
......
;;; Test cases for Iterate.
;;; Copyright (c) 2003 Andreas Fuchs <asf@boinkor.net>
;;; Copyright (c) 2004-2005 Joerg Hoehle <hoehle@users.sourceforge.net>
;;; Copyright (c) 2004-2007 Joerg Hoehle <hoehle@users.sourceforge.net>
;;; License:
;; Permission is hereby granted, free of charge, to any person
......@@ -673,6 +673,11 @@
(if (next x) (collect i)))
(0 3))
(deftest if.2
(iter (generate x in-vector '#(t nil nil t) with-index i)
(if (next x) (collect i)))
(0 3))
(deftest or.1
(iter (generate x in '(a nil nil 1))
(generate y in-vector '#(2 #\c #\d))
......@@ -984,6 +989,15 @@
(collect i)))
(1 -1 3 -1 5))
(deftest first-time-p.0
(with-output-to-string (*standard-output*)
(iter (for el in '(nil 1 2 nil 3))
(when el
(unless (first-time-p)
(princ ", "))
(princ el))))
"1, 2, 3")
(deftest first-time-p.1
(iter (for i to 5)
(if (first-time-p) (collect -1))
......@@ -1479,7 +1493,7 @@
(sum-of-squares el))
14)
(deftest defmacro-clause
(deftest defmacro-clause.1
(defmacro-clause (multiply.clause expr &optional INTO var)
"from testsuite"
`(reducing ,expr by #'* into ,var initial-value 1))
......@@ -1591,6 +1605,45 @@
(collect (list (next e) e i)))
((a a 0) (b b 1) (c c 2)))
;; The original example had three bugs:
;; - ,expr and ,func occured twice in expansion
;; - (finally (leave ,winner)) breaks because FINALLY does not walk
;; its forms, so LEAVE does not work inside FINALLY.
;; - Do not use (finally (RETURN ,winner)) either, as that would
;; always return accumulated value, even in case of ... INTO nil.
(deftest defmacro-clause.2
(defmacro-clause (FINDING expr MAXING func &optional INTO var)
"Iterate paper demo example"
(let ((max-val (gensym "MAX-VAL"))
(temp1 (gensym "EL"))
(temp2 (gensym "VAL"))
(winner (or var iterate::*result-var*)))
`(progn
(with ,max-val = nil)
(with ,winner = nil)
(let* ((,temp1 ,expr)
(,temp2 (funcall ,func ,temp1)))
(when (or (null ,max-val) (> ,temp2 ,max-val))
(setq ,winner ,temp1 ,max-val ,temp2)))
#|(finally (return ,winner))|# )))
(FINDING expr MAXING func &optional INTO var))
(deftest maxing.1
(iter (for i in-vector #(1 5 3))
(finding i :maxing #'identity))
5)
(deftest maxing.2
(iter (for i in-vector #(1 5 3))
(finding i maxing #'identity into foo))
nil)
(deftest maxing.3
(iter (for i in-vector #(2 5 4))
(finding i maxing #'identity into foo)
(when (evenp i) (sum i)))
6)
(deftest display.1
(let ((*standard-output* (make-broadcast-stream)))
(display-iterate-clauses) t)
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment