summaryrefslogtreecommitdiff
path: root/lambda.lisp
diff options
context:
space:
mode:
authorMatthias Benkard <code@mail.matthias.benkard.de>2007-07-12 13:13:36 +0200
committerMatthias Benkard <code@mail.matthias.benkard.de>2007-07-12 13:13:36 +0200
commit5ca4e01082c0eae88a48bf9f24771779e6d0571d (patch)
tree2a1d1ad49130600f50c2ebfaef06a0fbb13d6beb /lambda.lisp
parent84aa8b5a3c9aabf50bb1a39a632f113e794cf139 (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
Diffstat (limited to 'lambda.lisp')
-rw-r--r--lambda.lisp57
1 files changed, 35 insertions, 22 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))))