multiple-value-variants

2014-08-26

Gives access to multiple-value variants of operators through one macro: MULTIPLE-VALUE. There are built-in variants for some standard operators; it's easy to create your own variants for other operators. The multiple-value mapping operators are especially useful.

Upstream URL

tarballs.hexstreamsoft.com/libraries/latest/multiple-value-variants_latest.tar.gz

Author

Jean-Philippe Paradis <hexstream@gmail.com>

License

Public Domain
README
Project's home: http://www.hexstreamsoft.com/projects/multiple-value-variants/ multiple-value-variants gives access to multiple-value variants of operators through one macro: MULTIPLE-VALUE. There are built-in variants for some standard operators; it's easy to create your own variants for other operators. The multiple-value mapping operators are especially useful. Examples -------- (multiple-value () (progn 1 2 3)) => 3 (multiple-value () (progn)) => [no values] (multiple-value () (and (values nil 'other 'values) t)) => NIL, OTHER, VALUES (multiple-value () (or (find-symbol "OR" '#:cl) (find-symbol "XOR" '#:cl))) => OR, :EXTERNAL (let ((hash (make-hash-table))) (multiple-value () (cond ((gethash 'key hash)) ((values))))) => [no values] (let ((hash (make-hash-table))) (setf (gethash 'key hash) 'value) (multiple-value () (cond ((gethash 'key hash)) ((values))))) => VALUE, T (multiple-value () (when nil (print "side-effect"))) => [no values] (multiple-value (2) (mapcar #'truncate '(3 5/4 5.5))) => (3 1 5), (0 1/4 0.5) (multiple-value 2 (mapcan (lambda (object) (if (numberp object) (values (list object) nil) (values nil (list object)))) '(0 a 2 3/4 c))) => (0 2 3/4), (A C) (multiple-value 3 (maplist (lambda (tail) (values tail (reverse tail) (list (first tail) (second tail)))) '(a b c d e))) => ((A B C D E) (B C D E) (C D E) (D E) (E)) ((E D C B A) (E D C B) (E D C) (E D) (E)) ((A B) (B C) (C D) (D E) (E NIL)) API --- First of all, in the way of packages there's the MULTIPLE-VALUE-VARIANTS package, which is also nicknamed MULTIPLE-VALUE-VARIANT, MV-VARIANTS and MV-VARIANT. The primary exported symbol is the MULTIPLE-VALUE macro. Explicitly (:import-from #:multiple-value-variants #:multiple-value) for normal usage. Don't (:use)! The MULTIPLE-VALUE-VARIANTS package also exports other symbols related to creation of new multiple-value variants and querying of existing ones (documentation pending, check package.lisp for a list of all exported symbols). The most important of these is DEFINE, which is normally used to define new multiple-value variants. You should normally explicitly package-qualify this symbol. There are 2 recurring features throughout the API: IDENTITY generally indicates the form to evaluate (and values to return) when an implicit (multiple-value progn) has no forms. NTH indicates which value to test for conditionals. The rest of the API documentation introduces the built-in multiple-value variants. Variant PROGN (&key (identity '(values))) (&body forms) Just like PROGN, except if there are no FORMS then the IDENTITY is evaluated instead. Variant PROG1 () (result &body body) This straightforwardly expands to a MULTIPLE-VALUE-PROG1. Variant AND (&key identity (nth 0)) (&rest forms) If IDENTITY is not specified, then there must be at least one FORM. This is like normal AND, except if one of the non-last FORMS' NTH-value is false, returns all values that were returned by that FORM, not just the primary value. Variant OR (&key identity (nth 0)) (&rest forms) If IDENTITY is not specified, then there must be at least one FORM. This is like normal OR, except if one of the non-last FORMS' NTH-value is true, returns all values that were returned by that FORM, not just the primary value. Variant COND (&key (nth 0)) (&rest clauses) This is just like normal COND, except: - If a CLAUSE that has no FORMS succeeds, then all the values that were returned by the TEST-FORM are returned, not just the primary value; - If no CLAUSE succeeds, then no values are returned (instead of NIL). Variant WHEN (&key (else '(values)) (identity '(values))) (test &body forms) If TEST evaluates to true, evaluate FORMS as an implicit (multiple-value progn) with IDENTITY as the identity. Else, evaluate ELSE. Variant UNLESS (&key (else '(values)) (identity '(values))) (test &body forms) If TEST evaluates to false, evaluate FORMS as an implicit (multiple-value progn) with IDENTITY as the identity. Else, evaluate ELSE. Variant CASE () (keyform &body cases) Variant CCASE () (keyplace &body cases) Variant ECASE () (keyform &body cases) Variant TYPECASE () (keyform &body cases) Variant CTYPECASE () (keyplace &body cases) Variant ETYPECASE () (keyform &body cases) These are like their normal counterparts, except the FORMS in each case is an implicit (multiple-value progn), and if no case matches in CASE or TYPECASE, then no values are returned (instead of NIL). Variant MAPCAR (multiple-values-count) (function &rest+ lists) Variant MAPCAN (multiple-values-count) (function &rest+ lists) Variant MAPLIST (multiple-values-count) (function &rest+ lists) Variant MAPCON (multiple-values-count) (function &rest+ lists) These are just like the normal variants, except they can accumulate multiple results at the same time. This is especially useful to "triage" values (ex: split the elements of a list into 2 lists according to some criteria), and to accumulate multiple "layers" of values in one pass for macroexpansions, as an alternative to repeated mapping (sometimes with some readability problems due to reduced "correlation"). MULTIPLE-VALUES-COUNT is not evaluated, and must be a non-negative integer indicating the number of results (values) to accumulate and return. FUNCTION would normally return that many values. If FUNCTION returns less than MULTIPLE-VALUES-COUNT values, then the remaining values are NIL. If FUNCTION returns more than MULTIPLE-VALUES-COUNT values, then the excess values are ignored. This library is in the Public Domain. See the UNLICENSE file for details.

Dependencies (3)

  • enhanced-multiple-value-bind
  • map-bind
  • positional-lambda

Dependents (0)

    • GitHub
    • Quicklisp