I'm trying to create a shorthand for lambda using underbar (_), per:
(defmacro _ (&rest body)
`(lambda (&rest _) ,@(expand_s body)))
(defun expand_s (s)
(cond ((null s) nil)
((atom s)
(if (eq '_ s) '(nth 0 _)
(let ((s_string (format nil "~a" s)))
(if (char-equal #\_ (aref s_string 0))
`(nth ,(1- (parse-integer (subseq s_string 1))) _)
s))))
(t (cons (expand_s (car s)) (expand_s (cdr s))))))
(print (macroexpand '(_ (+ _1 _2))))
(print (mapcar (_ (+ (* _1 _2) (expt _2 _1))) '(1 2 3) '(10 20 30)))
Ugly as it is, it works fine compiled in SBCL:
* (load "shlambda.fasl")
#'(LAMBDA (&REST _) (+ (NTH 0 _) (NTH 1 _)))
(20 440 27090)
But the SBCL compiler really doesn't like it:
; compiling (PRINT (MAPCAR # ...))
; file: shlambda.lisp
; in:
; PRINT (MAPCAR (_ (+ (* |_1| |_2|) (EXPT |_2| |_1|))) '(1 2 3) '(10 20 30))
; (_ (+ (* |_1| |_2|) (EXPT |_2| |_1|)))
; --> FUNCTION + * NTH SB-C::%REST-REF AND IF
; ==>
; NIL
;
; caught STYLE-WARNING:
; This is not a NUMBER:
; NIL
; See also:
; The SBCL Manual, Node "Handling of Types"
;
; caught STYLE-WARNING:
; This is not a NUMBER:
; NIL
; See also:
; The SBCL Manual, Node "Handling of Types"
; --> FUNCTION + EXPT NTH SB-C::%REST-REF AND IF
; ==>
; NIL
;
; caught STYLE-WARNING:
; This is not a NUMBER:
; NIL
; See also:
; The SBCL Manual, Node "Handling of Types"
;
; caught STYLE-WARNING:
; This is not a NUMBER:
; NIL
; See also:
; The SBCL Manual, Node "Handling of Types"
;
; compilation unit finished
; caught 4 STYLE-WARNING conditions
I guess type inference can't figure out the types of an &rest in a lambda (which, I admit, I'm amazed that it even accepts an &rest in a lambda!) But you can pretty much never figure out the types in an &rest, so ... ???
Thanks in advance for your guidance.
The following compiles entirely silently for me, in a cold SBCL 2.2.7:
And I can't see why it should not. Barmar is right that the
&rest
in the macro should probably be&body
but that's stylistic.My guess is that you might not be defining
expand_s
early enough (see myeval-when
), but actually I have no idea.