Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Nothing Can Stop The Progressive Revolution
Added: * XOR * WHICHEVER * SWITCH, ESWITCH, CSWItCH * UNIONF, NUNIONF * ALIST-PLIST, PLIST-ALIST * ENSURE-CONS * NAMED-LAMDBA * DEFINE-CONSTANT * STRING-DESIGNATOR Note: Documentation strings of many new operators are sorely lacking, particularly NAMED-LAMBDA and *SWITCH.
- Loading branch information
Showing
8 changed files
with
189 additions
and
8 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,70 @@ | ||
(in-package :alexandria) | ||
|
||
(defmacro switch ((object &key (test 'eql) (key 'identity) (default nil)) | ||
&body clauses) | ||
"Evaluates first matching clause, returning its values, or evaluates and | ||
returns the values of DEFAULT if no keys match." | ||
(with-gensyms (value) | ||
`(let ((,value (,key ,object))) | ||
(cond ,@(mapcar (lambda (clause) | ||
(destructuring-bind (key-form &body forms) clause | ||
`((,test ,value ,key-form) | ||
,@forms))) | ||
clauses) | ||
(t ,default))))) | ||
|
||
(defmacro eswitch ((object &key (test 'eql) (key 'identity)) &body clauses) | ||
"Like SWITCH, but signals an error if no key matches." | ||
(with-gensyms (value) | ||
`(let ((,value (,key ,object))) | ||
(cond ,@(mapcar (lambda (clause) | ||
(destructuring-bind (key-form &body forms) clause | ||
`((,test ,value ,key-form) | ||
,@forms))) | ||
clauses) | ||
(t | ||
(error "No keys match in ESWITCH. Testing against ~S with ~S." | ||
,value ',test)))))) | ||
|
||
(defmacro eswitch ((object &key (test 'eql) (key 'identity)) &body clauses) | ||
"Like SWITCH, but signals a continuable error if no key matches." | ||
(with-gensyms (value) | ||
`(let ((,value (,key ,object))) | ||
(cond ,@(mapcar (lambda (clause) | ||
(destructuring-bind (key-form &body forms) clause | ||
`((,test ,value ,key-form) | ||
,@forms))) | ||
clauses) | ||
(t | ||
(cerror "Return NIL from CSWITCH." | ||
"No keys match in CSWITCH. Testing against ~S with ~S." | ||
,value ',test)))))) | ||
|
||
(defmacro whichever (&rest possibilities) | ||
"Evaluates exactly one of POSSIBILITIES, chosen at random." | ||
`(funcall (the function | ||
(svref (load-time-value | ||
(vector ,@(mapcar (lambda (possibility) | ||
`(lambda () ,possibility)) | ||
possibilities)) | ||
t) | ||
(random ,(length possibilities)))))) | ||
|
||
(defmacro xor (&rest datums) | ||
"Evaluates its argument one at a time, from left to right. If more then one | ||
argument evaluates to a true value no further DATUMS are evaluated, and NIL is | ||
returned as both primary and secondary value. If exactly one argument | ||
evaluates to true, its value is returned as the primary value after all the | ||
arguments have been evaluated, and T is returned as the secondary value. If no | ||
arguments evaluate to true NIL is retuned as primary, and T as secondary | ||
value." | ||
(with-gensyms (xor tmp true) | ||
`(let (,tmp ,true) | ||
(block ,xor | ||
,@(mapcar (lambda (datum) | ||
`(if (setf ,tmp ,datum) | ||
(if ,true | ||
(return-from ,xor (values nil nil)) | ||
(setf ,true ,tmp)))) | ||
datums) | ||
(return-from ,xor (values ,true t)))))) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,34 @@ | ||
(in-package :alexandria) | ||
|
||
(defmacro define-constant (name initial-value &key (test 'eql) documentation) | ||
"Ensures that the global variable named by NAME is a constant with a value | ||
that is equal under TEST to the result of evaluating INITIAL-VALUE. TEST | ||
defaults to EQL, and if given it must be a symbol naming a function. If | ||
DOCUMENTATION is given, it becomes the documentation string of the constant. | ||
Signals an error if NAME is already a bound non-constant variable. | ||
Signals an error if NAME is already a constant variable whose value is not | ||
equal under TEST to result of evaluating INITIAL-VALUE." | ||
`(defconstant ,name | ||
(let ((new ,initial-value)) | ||
(if (boundp ',name) | ||
(let ((old (symbol-value ',name))) | ||
(cond | ||
((constantp ',name) | ||
(cond | ||
((,test old new) | ||
old) | ||
(t | ||
(cerror "Try to redefine the constant." | ||
"~@<~S is an already defined constant whose value ~ | ||
~S is not equal to the provided initial value ~S ~ | ||
under ~S.~:@>" ',name old new ',test) | ||
new))) | ||
(t | ||
(cerror "Try to redefine the variable as a constant." | ||
"~@<~S is an already bound non-constant variable ~ | ||
whose value is ~S.~:@>" ',name old) | ||
new))) | ||
new)) | ||
,@(when documentation `(,documentation)))) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,6 @@ | ||
(in-package :alexandria) | ||
|
||
(deftype string-designator () | ||
"A string designator type. A string designator is either a string, a symbol, | ||
or a character." | ||
`(or symbol string character)) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters