Changeset 3200

Show
Ignore:
Timestamp:
05/28/08 13:26:38 (8 months ago)
Author:
hans
Message:

pull alexandria from darcs repository

Files:

Legend:

Unmodified
Added
Removed
Modified
Copied
Moved
  • trunk/thirdparty/alexandria/_darcs/inventory

    r2190 r3200  
    9999]  
    100100[Small fix to REQUIRED-ARGUMENT's control string. 
    101 Luis Oliveira <loliveira@common-lisp.net>**20070823040500]  
     101Luis Oliveira <loliveira@common-lisp.net>**20070823040500] [New macro: COERCEF 
     102Luis Oliveira <loliveira@common-lisp.net>**20070720003607 
     103  
     104 Added respective documentation to the manual. 
     105]  
     106[New function: FEATUREP 
     107Luis Oliveira <loliveira@common-lisp.net>**20070720003420 
     108  
     109 Added respective documentation in manual as well. 
     110]  
     111[New macro: NCONCF 
     112Luis Oliveira <loliveira@common-lisp.net>**20070720003523 
     113  
     114 - Added respective documentation to the manual. 
     115 - New test: NCONCF.1 
     116]  
     117[New macro: IGNORE-SOME-CONDITIONS 
     118Luis Oliveira <loliveira@common-lisp.net>**20070726171110]  
     119[Simplify IGNORE-SOME-CONDITIONS's docstring. 
     120Luis Oliveira <loliveira@common-lisp.net>**20070823040556]  
     121[Merge conflicts around the conditions 
     122attila.lendvai@gmail.com**20071001122707]  
     123[fix: darcs merge conflict was recorded into package.lisp 
     124attila.lendvai@gmail.com**20071031173831]  
     125[Fix map-permutations typo. 
     126levente.meszaros@gmail.com**20071102163851]  
     127[Switch the argument order of STARTS/ENDS-WITH-SUBSEQ to that it matches STARTS/ENDS-WITH. 
     128attila.lendvai@gmail.com**20071126135259]  
     129[fixed and robustified tests 
     130Nikodemus Siivola <nikodemus@random-state.net>**20071219125512]  
     131[ENSURE-GETHASH 
     132Nikodemus Siivola <nikodemus@random-state.net>**20071219125800 
     133  
     134  * new function: like GETHASH, but saves the default value in table if 
     135    key is not found.*  
     136  
     137]  
     138[better SHUFFLE 
     139Nikodemus Siivola <nikodemus@random-state.net>**20071219125911 
     140  
     141  * Thanks to Sean Ross: implement the Fisher/Yates/Knuth algorithm 
     142    correctly. 
     143  
     144  * As penance, specialize for lists as well: travel along the list, 
     145    swapping towards the end -- marginally more efficient then swapping 
     146    along the whole length. 
     147  
     148]  
     149[fix MAKE-GENSYM-LIST when called without the second argument 
     150Nikodemus Siivola <nikodemus@random-state.net>**20071219130559 
     151  
     152  * plus a test-case 
     153  
     154]  
     155[fix SANS -> REMOVE-FROM-PLIST in tests 
     156Nikodemus Siivola <nikodemus@random-state.net>**20071219130641 
     157  
     158  * So SANS is now REMOVE-FROM-PLIST. 
     159  
     160    ...I have to say that I'm still not sure I like this: 
     161  
     162      (remove-from-plist x y) ; which is the plist? 
     163  
     164    The common usage in REMOVE &co is to put the element designators 
     165    first. This is confusing. 
     166  
     167    Maybe we really want both: 
     168  
     169     function SANS plist &rest keys 
     170     function REMOVE-FROM-PLIST keys plist 
     171  
     172]  
     173[NTH-VALUE-OR 
     174Nikodemus Siivola <nikodemus@random-state.net>**20071219132132 
     175  
     176  * Thanks to Andreas Fuchs -- I only took the liberty of changing the name from 
     177    MULTIPLE-VALUE-OR to NTH-VALUE-OR. 
     178  
     179]  
     180[fix dependency: macros.lisp is using MAKE-GENSYM-LIST from symbols.lisp 
     181attila.lendvai@gmail.com**20071221100634]  
     182[Extract the function name of KEY too, not just TEST in GENERATE-SWITCH-BODY. 
     183attila.lendvai@gmail.com**20080209201446 
     184 Patch by Stelian Ionescu. 
     185]  
     186[fix tests: DELETEF.1 modified constant data 
     187Nikodemus Siivola <nikodemus@random-state.net>**20080217070803 
     188  
     189  * ...so that running tests multiple times caused unrelated tests to fail 
     190    due to coalesced constants being frobbed. Gah. 
     191  
     192]  
     193[new macro: DOPLIST 
     194Nikodemus Siivola <nikodemus@random-state.net>**20080217071024 
     195  
     196  * Like DOLIST, but iterates over plists. 
     197  
     198]  
     199[extended ONCE-ONLY 
     200Nikodemus Siivola <nikodemus@random-state.net>**20080217071829 
     201  
     202  * Support (once-only ((nx x)) ...) style also. 
     203  
     204]  
     205[fix WHICHEVER 
     206Nikodemus Siivola <nikodemus@random-state.net>**20080217071955 
     207  
     208  * More efficient with constant arguments. 
     209  
     210  * Respect lexical environment with non-constant arguments. 
     211  
     212]  
     213[fix removef and deletef not to use an inline lambda 
     214nikodemus@random-state.net**20080223171025 
     215  
     216  CLHS says the third argument to DEFINE-MODIFY-MACRO must be a symbol. 
     217  Reported by Chun Tian. 
     218  
     219]  
     220[Added an almost full implementation of CDR5 
     221attila.lendvai@gmail.com**20080301100637]  
     222[Fix file dependencies in the .asd 
     223attila.lendvai@gmail.com**20080301105628]  
     224[FEATUREP accept any compound test specifier, not just the keywords :AND, :OR and :NOT. 
     225attila.lendvai@gmail.com**20080301105651 
     226 Patch by Stelian Ionescu. 
     227]  
     228[Fix autodoc argument list of remove-from-plistf and delete-from-plistf. 
     229attila.lendvai@gmail.com**20080301111034 
     230 Patch by Michael Weber. 
     231]  
     232[Extract the body of define-constant macro into a function to avoid some warnings. 
     233attila.lendvai@gmail.com**20080310134214 
     234 (Based on patch by Tobias C. Rittweiler) 
     235]  
     236[Fix define-constant thinko, thanks for Tobias C. Rittweiler for pointing it out. 
     237attila.lendvai@gmail.com**20080310141844]  
     238[fix docstring typos in numbers.lisp (patch by Tobias C. Rittweiler) 
     239attila.lendvai@gmail.com**20080310180012]  
     240[Optimize sequence-of-length-p, make it inlinable 
     241attila.lendvai@gmail.com**20080310181353]  
     242[alexandria-define-constant-testcase.diff 
     243Tobias C. Rittweiler <tcr@freebits.de>**20080311151906 
     244  
     245        * tests.lisp (define-constant.1): Adapted to latest changes; 
     246        argument to :KEY is now evaluated. 
     247]  
     248[More elegant implementation for remove-from-plist by Michael Weber. 
     249attila.lendvai@gmail.com**20080312091456]  
     250[alexandria-copy-hashtable.diff 
     251Tobias C. Rittweiler <tcr@freebits.de>**20080311143832 
     252  
     253        * hash-tables.lisp (copy-hash-table): Added new &key arg :KEY; 
     254        it's run on each element before it's stored in the new HT. 
     255        Additionally, make all &key args get their default even when 
     256        NIL was passed for them. 
     257  
     258        * tests.lisp (copy-hash-table.2): New test case. 
     259         
     260]  
     261[alexandria-parse-body.diff 
     262Tobias C. Rittweiler <tcr@freebits.de>**20080311093924 
     263  
     264 * macros.lisp (parse-body): Don't use ALEXANDRIA:STARTS-WITH. 
     265  
     266     The reason is that this way PARSE-BODY is a completely  
     267     standalone definition, and can hence be used in consequent 
     268     macro definitions within the Alexandria project without 
     269     having to worrying if `sequences.lisp' has already been 
     270     loaded (where STARTS-WITH is defined.) 
     271  
     272]  
     273[One level less quote in the implementation of the CDR5 types macro 
     274attila.lendvai@gmail.com**20080313160255]  
     275[alexandria-cdr5-types.diff 
     276Tobias C. Rittweiler <tcr@freebits.de>**20080313203602 
     277  
     278        * types.lisp: Fix quoting problem introduced by Attila's last 
     279        patch; additionally add automatically generated docstrings to all 
     280        the types defined. 
     281  
     282        * tests.lisp (cdr5.*): New test cases. 
     283]  
     284[Fix dependency: previous patch to CDR5 in types.lisp uses ensure-car from lists.lisp 
     285attila.lendvai@gmail.com**20080314115151]  
     286[alexandria-unwind-protect-case.diff 
     287Tobias C. Rittweiler <tcr@freebits.de>**20080311154836 
     288  
     289        * conditions.lisp (unwind-protect-case): New macro. Similiar to 
     290        CL:UNWIND-PROTECT except that it's possible to explicitly specify 
     291        under which circumstances cleanup operations are run. 
     292  
     293        * tests.lisp (unwind-protect-case.1-5): New test cases. 
     294]  
     295[alexandria-export-unwind-protect-case.diff 
     296Tobias C. Rittweiler <tcr@freebits.de>**20080311195448 
     297  
     298        * package.lisp: Export UNWIND-PROTECT-CASE. 
     299]  
     300[Added simple-reader-error 
     301attila.lendvai@gmail.com**20080327192821]  
     302[Fix some glitches with simple-reader-error and add comment why there's no :report for it. 
     303attila.lendvai@gmail.com**20080401110518]  
     304[Added length= 
     305attila.lendvai@gmail.com**20080410172801]  
     306[added simple-parse-error 
     307attila.lendvai@gmail.com**20080427205301]  
  • trunk/thirdparty/alexandria/_darcs/pristine/alexandria.asd

    r2190 r3200  
    1010   (:file "conditions" :depends-on ("package")) 
    1111   (:file "hash-tables" :depends-on ("package")) 
    12    (:file "macros" :depends-on ("package" "strings")) 
    13    (:file "control-flow" :depends-on ("package" "macros")) 
     12   (:file "macros" :depends-on ("package" "strings" "symbols")) 
     13   (:file "control-flow" :depends-on ("package" "definitions" "macros")) 
    1414   (:file "symbols" :depends-on ("package")) 
    15    (:file "arrays" :depends-on ("package")) 
    16    (:file "types" :depends-on ("package")) 
     15   (:file "arrays" :depends-on ("package" "types")) 
     16   (:file "types" :depends-on ("package" "symbols" "lists")) 
    1717   (:file "binding" :depends-on ("package")) 
    1818   (:file "functions" :depends-on ("package" "symbols" "macros")) 
    1919   (:file "lists" :depends-on ("package" "functions")) 
    2020   (:file "sequences" :depends-on ("package" "lists")) 
    21    (:file "numbers" :depends-on ("package" "sequences")))) 
     21   (:file "numbers" :depends-on ("package" "sequences")) 
     22   (:file "features" :depends-on ("package" "control-flow")))) 
  • trunk/thirdparty/alexandria/_darcs/pristine/arrays.lisp

    r2190 r3200  
    11(in-package :alexandria) 
    2  
    3 (deftype array-index (&optional (length array-dimension-limit)) 
    4   "Type designator for an index into array of LENGTH: an integer between 
    5 0 (inclusive) and LENGTH (exclusive). LENGTH defaults to 
    6 ARRAY-DIMENSION-LIMIT." 
    7   `(integer 0 (,length))) 
    8  
    9 (deftype array-length (&optional (length array-dimension-limit)) 
    10   "Type designator for a dimension of an array of LENGTH: an integer between 
    11 0 (inclusive) and LENGTH (inclusive). LENGTH defaults to 
    12 ARRAY-DIMENSION-LIMIT." 
    13   `(integer 0 ,length)) 
    142 
    153(defun copy-array (array &key 
  • trunk/thirdparty/alexandria/_darcs/pristine/conditions.lisp

    r2190 r3200  
    1313  (warn 'simple-style-warning :format-control message :format-arguments args)) 
    1414 
     15;; We don't specify a :report for simple-reader-error to let the underlying 
     16;; implementation report the line and column position for us. Unfortunately 
     17;; this way the message from simple-error is not displayed, but it's still 
     18;; inspectable from the debugger. 
     19(define-condition simple-reader-error (reader-error simple-error) 
     20  ()) 
     21 
     22(defun simple-reader-error (stream message &rest args) 
     23  (error 'simple-reader-error 
     24         :stream stream 
     25         :format-control message 
     26         :format-arguments args)) 
     27 
     28(define-condition simple-parse-error (simple-error parse-error) 
     29  ()) 
     30 
     31(defun simple-parse-error (message &rest args) 
     32  (error 'simple-parse-error 
     33         :format-control message 
     34         :format-arguments args)) 
     35 
     36(defmacro ignore-some-conditions ((&rest conditions) &body body) 
     37  "Similar to CL:IGNORE-ERRORS but the (unevaluated) CONDITIONS 
     38list determines which specific conditions are to be ignored." 
     39  `(handler-case 
     40       (progn ,@body) 
     41     ,@(loop for condition in conditions collect 
     42             `(,condition (c) (values nil c))))) 
     43 
     44(defmacro unwind-protect-case ((&optional abort-flag) protected-form &body clauses) 
     45  "Like CL:UNWIND-PROTECT, but you can specify the circumstances that 
     46the cleanup CLAUSES are run. 
     47 
     48ABORT-FLAG is the name of a variable that will be bound to T in 
     49CLAUSES if the PROTECTED-FORM aborted preemptively, and to NIL 
     50otherwise. 
     51 
     52Examples: 
     53 
     54  (unwind-protect-case () 
     55       (protected-form) 
     56     (:normal (format t \"This is only evaluated if PROTECTED-FORM executed normally.~%\")) 
     57     (:abort  (format t \"This is only evaluated if PROTECTED-FORM aborted preemptively.~%\")) 
     58     (:always (format t \"This is evaluated in either case.~%\"))) 
     59 
     60  (unwind-protect-case (aborted-p) 
     61       (protected-form) 
     62     (:always (perform-cleanup-if aborted-p))) 
     63" 
     64  (check-type abort-flag (or null symbol)) 
     65  (let ((gflag (gensym "FLAG+"))) 
     66    `(let ((,gflag t)) 
     67       (unwind-protect (multiple-value-prog1 ,protected-form (setf ,gflag nil)) 
     68         (let ,(and abort-flag `((,abort-flag ,gflag))) 
     69           ,@(loop for (cleanup-kind . forms) in clauses 
     70                   collect (ecase cleanup-kind 
     71                             (:normal `(when (not ,gflag) ,@forms)) 
     72                             (:abort  `(when ,gflag ,@forms)) 
     73                             (:always `(progn ,@forms))))))))) 
  • trunk/thirdparty/alexandria/_darcs/pristine/control-flow.lisp

    r2190 r3200  
    44  (with-gensyms (value) 
    55    (setf test (extract-function-name test)) 
     6    (setf key (extract-function-name key)) 
    67    (when (and (consp default) 
    78               (member (first default) '(error cerror))) 
     
    3940  (generate-switch-body whole object clauses test key '(cerror "Return NIL from CSWITCH."))) 
    4041 
    41 (defmacro whichever (&rest possibilities
     42(defmacro whichever (&rest possibilities &environment env
    4243  "Evaluates exactly one of POSSIBILITIES, chosen at random." 
    43   `(funcall (the function 
    44               (svref (load-time-value 
    45                       (vector ,@(mapcar (lambda (possibility) 
    46                                           `(lambda () ,possibility)) 
    47                                         possibilities)) 
    48                       t) 
    49                      (random ,(length possibilities)))))) 
     44  (setf possibilities (mapcar (lambda (p) (macroexpand p env)) possibilities)) 
     45  (if (every (lambda (p) (constantp p)) possibilities) 
     46      `(svref (load-time-value (vector ,@possibilities)) (random ,(length possibilities))) 
     47      (with-gensyms (function) 
     48        `(let ((,function (lambda () ,(pop possibilities)))) 
     49           (declare (function ,function)) 
     50           ,@(let ((p 1)) 
     51               (mapcar (lambda (possibility) 
     52                         `(when (zerop (random ,(incf p))) 
     53                            (setf ,function (lambda () ,possibility)))) 
     54                       possibilities)) 
     55           (funcall ,function))))) 
    5056 
    5157(defmacro xor (&rest datums) 
     
    6773                   datums) 
    6874         (return-from ,xor (values ,true t)))))) 
     75 
     76(defmacro nth-value-or (nth-value &body forms) 
     77  "Evaluates FORM arguments one at a time, until the NTH-VALUE returned by one 
     78of the forms is non-NIL. It then returns all the values returned by evaluating 
     79that form. If none of the forms return a non-nil nth value, this form returns 
     80NIL." 
     81  (once-only (nth-value) 
     82    (with-gensyms (values) 
     83      `(let ((,values (multiple-value-list ,(first forms)))) 
     84         (if (nth ,nth-value ,values) 
     85             (values-list ,values) 
     86             ,(if (rest forms) 
     87                  `(nth-value-or ,nth-value ,@(rest forms)) 
     88                  nil)))))) 
  • trunk/thirdparty/alexandria/_darcs/pristine/definitions.lisp

    r2190 r3200  
    22 
    33(defun extract-function-name (spec) 
    4   "Useful for macros that want to emulate the functional interface for functions 
     4  "Useful for macros that want to mimic the functional interface for functions 
    55like #'eq and 'eq." 
    66  (if (and (consp spec) 
     
    99      spec)) 
    1010 
    11 (defmacro define-constant (name initial-value &key (test 'eql) documentation) 
    12   "Ensures that the global variable named by NAME is a constant with a value 
    13 that is equal under TEST to the result of evaluating INITIAL-VALUE. TEST 
    14 defaults to EQL, and if given it must be a symbol naming a function. If 
    15 DOCUMENTATION is given, it becomes the documentation string of the constant. 
     11(defun %reevaluate-constant (name value &key (test 'eql)) 
     12  (if (not (boundp name)) 
     13      value 
     14      (let ((old (symbol-value name)) 
     15            (new value)) 
     16        (if (not (constantp name)) 
     17            (prog1 new 
     18              (cerror "Try to redefine the variable as a constant." 
     19                      "~@<~S is an already bound non-constant variable ~ 
     20                       whose value is ~S.~:@>" name old)) 
     21            (if (funcall test old new) 
     22                old 
     23                (prog1 new 
     24                  (cerror "Try to redefine the constant." 
     25                          "~@<~S is an already defined constant whose value ~ 
     26                           ~S is not equal to the provided initial value ~S ~ 
     27                           under ~S.~:@>" name old new test))))))) 
     28 
     29(defmacro define-constant (name initial-value &key (test ''eql) documentation) 
     30  "Ensures that the global variable named by NAME is a constant with a 
     31value that is equal under TEST to the result of evaluating 
     32INITIAL-VALUE. TEST is a /function designator/ that defaults to 
     33EQL. If DOCUMENTATION is given, it becomes the documentation string of 
     34the constant. 
    1635 
    1736Signals an error if NAME is already a bound non-constant variable. 
     
    1938Signals an error if NAME is already a constant variable whose value is not 
    2039equal under TEST to result of evaluating INITIAL-VALUE." 
    21   (setf test (extract-function-name test)) 
    22   `(defconstant ,name 
    23      (let ((new ,initial-value)) 
    24        (if (boundp ',name) 
    25            (let ((old (symbol-value ',name))) 
    26              (cond 
    27                ((constantp ',name) 
    28                 (cond 
    29                   ((,test old new) 
    30                    old) 
    31                   (t 
    32                    (cerror "Try to redefine the constant." 
    33                            "~@<~S is an already defined constant whose value ~ 
    34                             ~S is not equal to the provided initial value ~S ~ 
    35                             under ~S.~:@>" ',name old new ',test) 
    36                    new))) 
    37                (t 
    38                 (cerror "Try to redefine the variable as a constant." 
    39                         "~@<~S is an already bound non-constant variable ~ 
    40                          whose value is ~S.~:@>" ',name old) 
    41                 new))) 
    42            new)) 
     40  `(defconstant ,name (%reevaluate-constant ',name 
     41                                            ,initial-value 
     42                                            :test ,test) 
    4343     ,@(when documentation `(,documentation)))) 
  • trunk/thirdparty/alexandria/_darcs/pristine/doc/alexandria.texinfo

    r2190 r3200  
    8181* Type Designator Manipulation::   
    8282* Mathematical Utilities::       
     83* Features::                     
    8384@end menu 
    8485 
     
    126127@include include/type-alexandria-circular-list.texinfo 
    127128@include include/macro-alexandria-appendf.texinfo 
     129@include include/macro-alexandria-nconcf.texinfo 
    128130@include include/fun-alexandria-circular-list.texinfo 
    129131@include include/fun-alexandria-circular-list-p.texinfo 
     
    192194@include include/fun-alexandria-of-type.texinfo 
    193195@include include/fun-alexandria-type-equal.texinfo 
     196@include include/macro-alexandria-coercef.texinfo 
    194197 
    195198@node Mathematical Utilities 
     
    209212@include include/fun-alexandria-standard-deviation.texinfo 
    210213 
     214@c FIXME: get a better section name 
     215@node Features 
     216@comment  node-name,  next,  previous,  up 
     217@section Features 
     218 
     219@include include/fun-alexandria-featurep.texinfo 
     220 
    211221@bye 
  • trunk/thirdparty/alexandria/_darcs/pristine/hash-tables.lisp

    r2190 r3200  
    11(in-package :alexandria) 
    22 
    3 (defun copy-hash-table (table &key 
    4                         (test (hash-table-test table)) 
    5                         (size (hash-table-size table)) 
    6                         (rehash-size (hash-table-size table)) 
    7                         (rehash-threshold (hash-table-rehash-threshold table))) 
    8   "Returns a shallow copy of hash table TABLE, with the same keys and values 
     3(defun copy-hash-table (table &key key test size 
     4                                   rehash-size rehash-threshold) 
     5  "Returns a copy of hash table TABLE, with the same keys and values 
    96as the TABLE. The copy has the same properties as the original, unless 
    10 overridden by the keyword arguments." 
     7overridden by the keyword arguments. 
     8 
     9Before each of the original values is set into the new hash-table, KEY 
     10is invoked on the value. As KEY defaults to CL:IDENTITY, a shallow 
     11copy is returned by default." 
     12  (setf key (or key 'identity)) 
     13  (setf test (or test (hash-table-test table))) 
     14  (setf size (or size (hash-table-size table))) 
     15  (setf rehash-size (or rehash-size (hash-table-size table))) 
     16  (setf rehash-threshold (or rehash-threshold (hash-table-rehash-threshold table))) 
    1117  (let ((copy (make-hash-table :test test :size size 
    1218                               :rehash-size rehash-size 
    1319                               :rehash-threshold rehash-threshold))) 
    1420    (maphash (lambda (k v) 
    15                (setf (gethash k copy) v)) 
     21               (setf (gethash k copy) (funcall key v))) 
    1622             table) 
    1723    copy)) 
     
    8490    table)) 
    8591 
     92(defun ensure-gethash (key hash-table &optional default) 
     93  "Like GETHASH, but if KEY is not found in the HASH-TABLE saves the DEFAULT 
     94under key before returning it. Secondary return value is true if key was 
     95already in the table." 
     96  (multiple-value-bind (value ok) (gethash key hash-table) 
     97    (if ok 
     98        (values value ok) 
     99        (values (setf (gethash key hash-table) default) nil)))) 
  • trunk/thirdparty/alexandria/_darcs/pristine/lists.lisp

    r2190 r3200  
    1818      (push (cons (car tail) (cadr tail)) alist)))) 
    1919 
     20(defun malformed-plist (plist) 
     21  (error "Malformed plist: ~S" plist)) 
     22 
     23(defmacro doplist ((key val plist &optional values) &body body) 
     24  "Iterates over elements of PLIST. BODY can be preceded by 
     25declarations, and is like a TAGBODY. RETURN may be used to terminate 
     26the iteration early. If RETURN is not used, returns VALUES." 
     27  (multiple-value-bind (forms declarations) (parse-body body) 
     28    (with-gensyms (tail loop results) 
     29      `(block nil 
     30         (flet ((,results () 
     31                  (let (,key ,val) 
     32                    (declare (ignorable ,key ,val)) 
     33                    (return ,values)))) 
     34           (let* ((,tail ,plist) 
     35                  (,key (if ,tail 
     36                            (pop ,tail) 
     37                            (,results))) 
     38                 (,val (if ,tail 
     39                           (pop ,tail) 
     40                           (malformed-plist ',plist)))) 
     41            (declare (ignorable ,key ,val)) 
     42            ,@declarations 
     43            (tagbody 
     44               ,loop 
     45               ,@forms 
     46               (setf ,key (if ,tail 
     47                              (pop ,tail) 
     48                              (,results)) 
     49                     ,val (if ,tail 
     50                              (pop ,tail) 
     51                              (malformed-plist ',plist))) 
     52               (go ,loop)))))))) 
     53 
    2054(define-modify-macro appendf (&rest lists) append 
    2155  "Modify-macro for APPEND. Appends LISTS to the place designated by the first 
     56argument.") 
     57 
     58(define-modify-macro nconcf (&rest lists) nconc 
     59  "Modify-macro for NCONC. Concatenates LISTS to place designated by the first 
    2260argument.") 
    2361 
     
    152190not destructively modified. Keys are compared using EQ." 
    153191  (declare (optimize (speed 3))) 
    154   ;; FIXME: unoptimal: (sans '(:a 1 :b 2) :a) has no need to copy the 
    155   ;; tail. 
    156   (loop for cell = plist :then (cddr cell) 
    157         for key = (car cell) 
    158         while cell 
     192  ;; FIXME: possible optimization: (remove-from-plist '(:x 0 :a 1 :b 2) :a) 
     193  ;; could return the tail without consing up a new list. 
     194  (loop for (key . rest) on plist by #'cddr 
     195        do (assert rest () "Expected a proper plist, got ~S" plist) 
    159196        unless (member key keys :test #'eq) 
    160         collect key 
    161         and do (assert (cdr cell) () "Not a proper plist") 
    162         and collect (cadr cell))) 
     197        collect key and collect (first rest))) 
    163198 
    164199(defun delete-from-plist (plist &rest keys) 
    165200  "Just like REMOVE-FROM-PLIST, but this version may destructively modify the 
    166201provided plist." 
    167   ;; FIXME unoptimal 
     202  ;; FIXME: should not cons 
    168203  (apply 'remove-from-plist plist keys)) 
    169204 
    170 (define-modify-macro remove-from-plistf (plist &rest keys) remove-from-plist) 
    171 (define-modify-macro delete-from-plistf (plist &rest keys) delete-from-plist) 
     205(define-modify-macro remove-from-plistf (&rest keys) remove-from-plist) 
     206(define-modify-macro delete-from-plistf (&rest keys) delete-from-plist) 
    172207 
    173208(declaim (inline sans)) 
  • trunk/thirdparty/alexandria/_darcs/pristine/macros.lisp

    r2190 r3200  
    1818    `(with-gensyms ,names ,@forms)) 
    1919 
    20 (defmacro once-only (names &body forms) 
    21   "Evaluates FORMS with NAMES rebound to temporary variables, 
    22 ensuring that each is evaluated only once. 
     20(defmacro once-only (specs &body forms) 
     21  "Each SPEC must be either a NAME, or a (NAME INITFORM), with plain 
     22NAME using the named variable as initform. 
     23 
     24Evaluates FORMS with names rebound to temporary variables, ensuring 
     25that each is evaluated only once. 
    2326 
    2427Example: 
    2528  (defmacro cons1 (x) (once-only (x) `(cons ,x ,x))) 
    2629  (let ((y 0)) (cons1 (incf y))) => (1 . 1)" 
    27   (let ((gensyms (make-gensym-list (length names) "ONCE-ONLY"))) 
     30  (let ((gensyms (make-gensym-list (length specs) "ONCE-ONLY")) 
     31        (names-and-forms (mapcar (lambda (spec) 
     32                                   (etypecase spec 
     33                                     (list 
     34                                      (destructuring-bind (name form) spec 
     35                                        (cons name form))) 
     36                                     (symbol 
     37                                      (cons spec spec)))) 
     38                                 specs))) 
    2839    ;; bind in user-macro 
    29     `(let ,(mapcar (lambda (g n) (list g `(gensym ,(string n)))) 
    30                    gensyms names
     40    `(let ,(mapcar (lambda (g n) (list g `(gensym ,(string (car n))))) 
     41                   gensyms names-and-forms
    3142       ;; bind in final expansion 
    32        `(let (,,@(mapcar (lambda (g n) ``(,,g ,,n)) gensyms names)) 
     43       `(let (,,@(mapcar (lambda (g n) 
     44                           ``(,,g ,,(cdr n))) 
     45                         gensyms names-and-forms)) 
    3346          ;; bind in user-macro 
    34           ,(let ,(mapcar #'list names gensyms) 
     47          ,(let ,(mapcar (lambda (n g) (list (car n) g)) 
     48                         names-and-forms gensyms) 
    3549             ,@forms))))) 
    3650 
     
    5165             (setf doc (pop body))) 
    5266         (go :declarations)) 
    53        (when (starts-with 'declare current
     67       (when (and (listp current) (eql (first current) 'declare)
    5468         (push (pop body) decls) 
    5569         (go :declarations))) 
  • trunk/thirdparty/alexandria/_darcs/pristine/numbers.lisp

    r2190 r3200  
    4545  "Return a list of n numbers, starting from START (with numeric contagion 
    4646from STEP applied), each consequtive number being the sum of the previous one 
    47 and STEP. START defaults to 0 and STEP to 0
     47and STEP. START defaults to 0 and STEP to 1
    4848 
    4949Examples: 
     
    6363  "Calls FUNCTION with N numbers, starting from START (with numeric contagion 
    6464from STEP applied), each consequtive number being the sum of the previous one 
    65 and STEP. START defaults to 0 and STEP to 0. Returns N. 
     65and STEP. START defaults to 0 and STEP to 1. Returns N. 
    6666 
    6767Examples: 
    6868 
    69   (iota 4)                      => (0 1 2 3 4) 
    70   (iota 3 :start 1 :step 1.0)   => (1.0 2.0 3.0) 
    71   (iota 3 :start -1 :step -1/2) => (-1 -3/2 -2) 
     69  (map-iota #'print 3 :start 1 :step 1.0) => 3 
     70    ;;; 1.0 
     71    ;;; 2.0 
     72    ;;; 3.0 
    7273" 
    7374  (declare (type (integer 0) n) (number start step)) 
  • trunk/thirdparty/alexandria/_darcs/pristine/package.lisp

    r2190 r3200  
    1313   #:cswitch 
    1414   #:eswitch 
     15   #:nth-value-or 
    1516   #:switch 
    1617   #:whichever 
     
    1920   #:alist-hash-table 
    2021   #:copy-hash-table 
     22   #:ensure-gethash 
    2123   #:hash-table-alist 
    2224   #:hash-table-keys 
     
    3840   #:alist-plist 
    3941   #:appendf 
     42   #:nconcf 
    4043   #:circular-list 
    4144   #:circular-list-p 
    4245   #:circular-tree-p 
     46   #:doplist 
    4347   #:ensure-car 
    4448   #:ensure-cons 
     
    9094   #:map-combinations 
    9195   #:map-derangements 
    92    #:map-permuations 
     96   #:map-permutations 
    9397   #:proper-sequence 
    9498   #:random-elt 
     
    96100   #:rotate 
    97101   #:sequence-of-length-p 
     102   #:length= 
    98103   #:shuffle 
    99104   #:starts-with 
     
    114119   #:of-type 
    115120   #:type= 
    116    ;; Errors 
     121   #:coercef 
     122   ;; Conditions 
    117123   #:required-argument 
     124   #:ignore-some-conditions 
    118125   #:simple-style-warning 
     126   #:simple-reader-error 
     127   #:simple-parse-error 
     128   #:unwind-protect-case 
     129   ;; Features 
     130   #:featurep 
    119131   )) 
  • trunk/thirdparty/alexandria/_darcs/pristine/sequences.lisp

    r2190 r3200  
    11(in-package :alexandria) 
     2 
     3;; Make these inlinable by declaiming them INLINE here and some of them 
     4;; NOTINLINE at the end of the file. Exclude functions that have a compiler 
     5;; macro, because inlining seems to cancel compiler macros (at least on SBCL). 
     6(declaim (inline copy-sequence sequence-of-length-p)) 
    27 
    38(defun rotate-tail-to-head (sequence n) 
     
    5257(defun shuffle (sequence &key (start 0) end) 
    5358  "Returns a random permutation of SEQUENCE bounded by START and END. 
    54 Permuted sequence may share storage with the original one. Signals 
    55 an error if SEQUENCE is not a proper sequence." 
     59Permuted sequence may share storage with the original one. Signals an 
     60error if SEQUENCE is not a proper sequence." 
    5661  (declare (fixnum start) (type (or fixnum null) end)) 
    57   (let ((end (or end (if (listp sequence) (list-length sequence) (length sequence))))) 
    58     (loop for i from start below end 
    59        do (rotatef (elt sequence i) (elt sequence (random end))))) 
     62  (typecase sequence 
     63    (list 
     64     (let* ((end (or end (list-length sequence))) 
     65            (n (- end start))) 
     66       (do ((tail (nthcdr start sequence) (cdr tail))) 
     67           ((zerop n)) 
     68         (rotatef (car tail) (car (nthcdr (random n) tail))) 
     69         (decf n)))) 
     70    (vector 
     71     (let ((end (or end (length sequence)))) 
     72       (loop for i from (- end 1) downto start 
     73             do (rotatef (aref sequence i) (aref sequence (random (+ i 1))))))) 
     74    (sequence 
     75     (let ((end (or end (length sequence)))) 
     76       (loop for i from (- end 1) downto start 
     77             do (rotatef (elt sequence i) (elt sequence (random (+ i 1)))))))) 
    6078  sequence) 
    6179 
     
    7088    (elt sequence i))) 
    7189 
     90(declaim (inline remove/swapped-arguments)) 
     91(defun remove/swapped-arguments (sequence item &rest keyword-arguments) 
     92  (apply #'remove item sequence keyword-arguments)) 
     93 
    7294(define-modify-macro removef (item &rest remove-keywords) 
    73   (lambda (seq item &rest keyword-arguments) 
    74     (apply #'remove item seq keyword-arguments)) 
     95  remove/swapped-arguments 
    7596  "Modify-macro for REMOVE. Sets place designated by the first argument to 
    7697the result of calling REMOVE with ITEM, place, and the REMOVE-KEYWORDS.") 
    7798 
     99(declaim (inline delete/swapped-arguments)) 
     100(defun delete/swapped-arguments (sequence item &rest keyword-arguments) 
     101  (apply #'delete item sequence keyword-arguments)) 
     102 
    78103(define-modify-macro deletef (item &rest remove-keywords) 
    79   (lambda (seq item &rest keyword-arguments) 
    80     (apply #'delete item seq keyword-arguments)) 
     104  delete/swapped-arguments 
    81105  "Modify-macro for DELETE. Sets place designated by the first argument to 
    82106the result of calling DELETE with ITEM, place, and the REMOVE-KEYWORDS.") 
     
    95119    (sequence (zerop (length sequence))))) 
    96120 
     121(defun length= (&rest sequences) 
     122  "Takes any number of sequences or integers in any order. Returns true iff 
     123the length of all the sequences and the integers are equal. Hint: there's a 
     124compiler macro that expands into more efficient code if the first argument 
     125is a literal integer." 
     126  (declare (dynamic-extent sequences) 
     127           (inline sequence-of-length-p) 
     128           (optimize speed)) 
     129  (unless (cdr sequences) 
     130    (error "You must call LENGTH= with at least two arguments")) 
     131  ;; There's room for optimization here: multiple list arguments could be 
     132  ;; traversed in parallel. 
     133  (let* ((first (pop sequences)) 
     134         (current (if (integerp first) 
     135                      first 
     136                      (length first)))) 
     137    (declare (type array-index current)) 
     138    (dolist (el sequences) 
     139      (if (integerp el) 
     140          (unless (= el current) 
     141            (return-from length= nil)) 
     142          (unless (sequence-of-length-p el current) 
     143            (return-from length= nil))))) 
     144  t) 
     145 
     146(define-compiler-macro length= (&whole form length &rest sequences) 
     147  (cond 
     148    ((zerop (length sequences)) 
     149     form) 
     150    (t 
     151     (let ((optimizedp (integerp length))) 
     152       (with-unique-names (tmp current) 
     153         (declare (ignorable current)) 
     154         `(locally 
     155              (declare (inline sequence-of-length-p)) 
     156            (let ((,tmp) 
     157                  ,@(unless optimizedp 
     158                     `((,current ,length)))) 
     159              ,@(unless optimizedp 
     160                  `((unless (integerp ,current) 
     161                      (setf ,current (length ,current))))) 
     162              (and 
     163               ,@(loop 
     164                    :for sequence :in sequences 
     165                    :collect `(progn 
     166                                (setf ,tmp ,sequence) 
     167                                (if (integerp ,tmp) 
     168                                    (= ,tmp ,(if optimizedp 
     169                                                 length 
     170                                                 current)) 
     171                                    (sequence-of-length-p ,tmp ,(if optimizedp 
     172                                                                    length 
     173                                                                    current))))))))))))) 
     174 
    97175(defun sequence-of-length-p (sequence length) 
    98176  "Return true if SEQUENCE is a sequence of length LENGTH. Signals an error if 
    99177SEQUENCE is not a sequence. Returns FALSE for circular lists." 
     178  (declare (type array-index length) 
     179           (inline length) 
     180           (optimize speed)) 
    100181  (etypecase sequence 
    101182    (null 
     
    105186       (unless (minusp n) 
    106187         (let ((tail (nthcdr n sequence))) 
    107            (and tail (null (cdr tail))))))) 
     188           (and tail 
     189                (null (cdr tail))))))) 
     190    (vector 
     191     (= length (length sequence))) 
    108192    (sequence 
    109193     (= length (length sequence))))) 
    110194 
    111 (declaim (inline copy-sequence)) 
    112195(defun copy-sequence (type sequence) 
    113196  "Returns a fresh sequence of TYPE, which has the same elements as 
     
    174257                  :expected-type '(and proper-sequence (not (satisfies emptyp)))))))) 
    175258 
    176 (defun starts-with-subseq (sequence prefix &rest args &key (return-suffix nil) &allow-other-keys) 
     259(defun starts-with-subseq (prefix sequence &rest args &key (return-suffix nil) &allow-other-keys) 
    177260  "Test whether the first elements of SEQUENCE are the same (as per TEST) as the elements of PREFIX. 
    178261