summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-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 ()