;;;; provided with absolutely no warranty. See the COPYING and CREDITS
;;;; files for more information.
-(in-package "SB!EXT")
+(in-package "SB!IMPL")
;;; Lots of code wants to get to the KEYWORD package or the
;;; COMMON-LISP package without a lot of fuss, so we cache them in
macros))))
`(macrolet ,macros (let* ,(nreverse binds) ,@body))))
\f
+;;; This function can be used as the default value for keyword
+;;; arguments that must be always be supplied. Since it is known by
+;;; the compiler to never return, it will avoid any compile-time type
+;;; warnings that would result from a default value inconsistent with
+;;; the declared type. When this function is called, it signals an
+;;; error indicating that a required &KEY argument was not supplied.
+;;; This function is also useful for DEFSTRUCT slot defaults
+;;; corresponding to required arguments.
(declaim (ftype (function () nil) required-argument))
(defun required-argument ()
#!+sb-doc
- "This function can be used as the default value for keyword arguments that
- must be always be supplied. Since it is known by the compiler to never
- return, it will avoid any compile-time type warnings that would result from a
- default value inconsistent with the declared type. When this function is
- called, it signals an error indicating that a required keyword argument was
- not supplied. This function is also useful for DEFSTRUCT slot defaults
- corresponding to required arguments."
(/show0 "entering REQUIRED-ARGUMENT")
- (error "A required keyword argument was not supplied."))
+ (error "A required &KEY argument was not supplied."))
\f
-;;; "the ultimate iteration macro"
+;;; "the ultimate iteration macro"
;;;
;;; note for Schemers: This seems to be identical to Scheme's "named LET".
-(defmacro iterate (name binds &body body)
+(defmacro named-let (name binds &body body)
#!+sb-doc
- "Iterate Name ({(Var Initial-Value)}*) Declaration* Form*
- This is syntactic sugar for Labels. It creates a local function Name with
- the specified Vars as its arguments and the Declarations and Forms as its
- body. This function is then called with the Initial-Values, and the result
- of the call is returned from the macro."
(dolist (x binds)
(unless (proper-list-of-length-p x 2)
(error "Malformed ITERATE variable spec: ~S." x)))
`(labels ((,name ,(mapcar #'first binds) ,@body))
(,name ,@(mapcar #'second binds))))
-\f
+
;;; ONCE-ONLY is a utility useful in writing source transforms and
;;; macros. It provides a concise way to wrap a LET around some code
;;; to ensure that some forms are only evaluated once.
+;;;
+;;; Create a LET* which evaluates each value expression, binding a
+;;; temporary variable to the result, and wrapping the LET* around the
+;;; result of the evaluation of BODY. Within the body, each VAR is
+;;; bound to the corresponding temporary variable.
(defmacro once-only (specs &body body)
- #!+sb-doc
- "Once-Only ({(Var Value-Expression)}*) Form*
- Create a Let* which evaluates each Value-Expression, binding a temporary
- variable to the result, and wrapping the Let* around the result of the
- evaluation of Body. Within the body, each Var is bound to the corresponding
- temporary variable."
- (iterate frob
- ((specs specs)
- (body body))
+ (named-let frob ((specs specs)
+ (body body))
(if (null specs)
`(progn ,@body)
(let ((spec (first specs)))
(let* ((name (first spec))
(exp-temp (gensym (symbol-name name))))
`(let ((,exp-temp ,(second spec))
- (,name (gensym "OO-")))
+ (,name (gensym "ONCE-ONLY-")))
`(let ((,,name ,,exp-temp))
,,(frob (rest specs) body))))))))
\f
(setq list (cdr x))
(rplacd splice (cdr x))))
(t (setq splice x)))))) ; Move splice along to include element.
+
+
+;; (defmacro posq (item list) `(position ,item ,list :test #'eq))
+(defun posq (item list)
+ #!+sb-doc
+ "Returns the position of the first element EQ to ITEM."
+ (do ((i list (cdr i))
+ (j 0 (1+ j)))
+ ((null i))
+ (when (eq (car i) item)
+ (return j))))
+
+;; (defmacro neq (x y) `(not (eq ,x ,y)))
+(defun neq (x y) (not (eq x y)))