diff options
author | Matthias Benkard <code@mail.matthias.benkard.de> | 2007-07-12 13:13:36 +0200 |
---|---|---|
committer | Matthias Benkard <code@mail.matthias.benkard.de> | 2007-07-12 13:13:36 +0200 |
commit | 5ca4e01082c0eae88a48bf9f24771779e6d0571d (patch) | |
tree | 2a1d1ad49130600f50c2ebfaef06a0fbb13d6beb | |
parent | 84aa8b5a3c9aabf50bb1a39a632f113e794cf139 (diff) |
Change the FN syntax from (FN FUNCTION-NAME ...) to (FN FUNCTION ...).
Where you previously wrote (FN + _ 10), you must now write (FN #'+ _
10). This makes FN forms both easier to read and more useful in the
presence of function objects.
This change also applies to the macros FN1, EFN and EFN1.
darcs-hash:eb87a513719bff03d185a022875f048f062eb6c4
-rw-r--r-- | lambda.lisp | 57 | ||||
-rw-r--r-- | mulkutils.asd | 2 |
2 files changed, 36 insertions, 23 deletions
diff --git a/lambda.lisp b/lambda.lisp index 29dfb66..be45865 100644 --- a/lambda.lisp +++ b/lambda.lisp @@ -4,12 +4,13 @@ #| Basic usage | =========== | - | (fn + _ 10) + | (fn #'+ _ 10) | (fn (+ _ 10)) - | (fn + _0 _1) - | (fn + _ _1) - | (mapcar (fn (cons _ _)) '(1 2 3)) ;=> ((1 . 1) (2 . 2) (3 . 3)) - | (funcall (fn + _ 10 _3) 20 30 40 50) ;=> 80 + | (fn #'+ _0 _1) + | (fn #'+ _ _1) + | (fn #'+ _ (/ _1 2)) + | (mapcar (fn (cons _ _)) '(1 2 3)) ;=> ((1 . 1) (2 . 2) (3 . 3)) + | (funcall (fn (+ _ 10 _3)) 20 30 40 50) ;=> 80 | | | Simple variant FN1 @@ -18,8 +19,10 @@ | (funcall (fn () _) 42) ;=> 42 | (funcall (fn _) 42) ;=> error (usually) | (funcall (fn1 _) 42) ;=> 42 - | (funcall (fn +)) ;=> 0 + | (funcall (fn +)) ;=> error (usually) | (funcall (fn1 +)) ;=> value of + + | (funcall (fn #'+)) ;=> 0 + | (funcall (fn1 #'+)) ;=> #<FUNCTION +> | | | Argument-number-safe variant EFN @@ -78,7 +81,7 @@ (t arglist)))) -(defmacro efn (&body args) +(defmacro efn (function-or-form &rest args) "A convenience wrapper for LAMBDA. Positional arguments are numbered from 0 and follow the pattern given by the @@ -96,10 +99,13 @@ FN as an argument, making the latter expect an argument where none is given: (funcall (efn (efn () _)))" - (cond ((null args) `#'(lambda ())) - ((not (listp (first args))) `(efn ,args)) + (cond ((or (not (listp function-or-form)) + (eq 'function (first function-or-form))) + `(efn (funcall ,function-or-form ,@args))) (t - (let* ((lambda-args (find-lambda-args `(progn ,@args))) + (let* ((lambda-args (find-lambda-args `(progn + ,function-or-form + ,@args))) (real-lambda-args (remove "_" lambda-args :key #'symbol-name :test #'string=)) @@ -111,20 +117,24 @@ given: nil) (function (lambda ,real-lambda-args (declare (ignorable ,@real-lambda-args)) + ,function-or-form ,@args))))))) -(defmacro fn (&body args) +(defmacro fn (function-or-form &rest args) "A less safe but recursively callable variant of EFN. This macro is like EFN save the fact that the anonymous functions it produces do not check the number of their arguments, thereby circumventing lambda argument misidentification errors in COLLECT-LAMBDA-ARGS." - (cond ((null args) `#'(lambda ())) - ((not (listp (first args))) `(fn ,args)) + (cond ((or (not (listp function-or-form)) + (eq 'function (first function-or-form))) + `(fn (funcall ,function-or-form ,@args))) (t - (let* ((lambda-args (find-lambda-args `(progn ,@args))) + (let* ((lambda-args (find-lambda-args `(progn + ,function-or-form + ,@args))) (real-lambda-args (remove "_" lambda-args :key #'symbol-name :test #'string=)) @@ -141,28 +151,31 @@ COLLECT-LAMBDA-ARGS." (nth ,i ,args-sym)))) (function (lambda (&rest ,args-sym) (declare (ignorable ,args-sym)) + ,function-or-form ,@args))))))) -(defmacro efn1 (&body args) +(defmacro efn1 (value-or-form &rest forms) "A variant of EFN that does not try to interpret its first argument as a function name. Useful for stuff like (EFN1 _3). (EFN1 a b c ...) is semantically equivalent to (EFN () a b c ...)." - (cond ((null args) `(efn)) - ((not (listp (first args))) `(efn () ,@args)) - (t `(efn ,@args)))) + (cond ((or (not (listp value-or-form)) + (eq 'function (first value-or-form))) + `(efn () ,value-or-form ,@forms)) + (t `(efn ,value-or-form ,@forms)))) -(defmacro fn1 (&body args) +(defmacro fn1 (value-or-form &rest forms) "A variant of FN that does not try to interpret its first argument as a function name. Useful for stuff like (FN1 _3). (FN1 a b c ...) is semantically equivalent to (FN () a b c ...)." - (cond ((null args) `(fn)) - ((not (listp (first args))) `(fn () ,@args)) - (t `(fn ,@args)))) + (cond ((or (not (listp value-or-form)) + (eq 'function (first value-or-form))) + `(fn () ,value-or-form ,@forms)) + (t `(fn ,value-or-form ,@forms)))) diff --git a/mulkutils.asd b/mulkutils.asd index 84a767f..696584f 100644 --- a/mulkutils.asd +++ b/mulkutils.asd @@ -1,6 +1,6 @@ (defsystem "mulkutils" :description "Random utilities by Matthias Benkard." - :version "0.0.1" + :version "0.0.2" :author "Matthias Benkard <matthias@benkard.de>" :licence "GNU General Public License, version 2 or higher" :depends-on () |