summaryrefslogtreecommitdiff
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
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
-rw-r--r--lambda.lisp57
-rw-r--r--mulkutils.asd2
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 ()