Avoiding funcall in a Lisp-2
Posted: Fri Jun 17, 2011 10:43 am
Hello!
Today I had an idea to reduce the need for funcall in a Lisp-2: allowing some parameters of a lambda-list to be bound in the function namespace. So you could write, for example:
Here is an implementation for lambda and defun (there are other lambda-list-using forms that would have to be covered, of course):
One problem with this is that it makes it impossible to have an optional parameter named 'function' and specify a default value (since #'foo expands to (function foo)). It could be extended to work with let too (but similarly it might not interact very well with the (let (x y z) ...) form); this would unify let and flet. What do you think?
Today I had an idea to reduce the need for funcall in a Lisp-2: allowing some parameters of a lambda-list to be bound in the function namespace. So you could write, for example:
Code: Select all
(defun map (#'fun ls)
(if (null ls)
nil
(cons (fun (first ls))
(map #'fun (rest ls)))))
Code: Select all
(defpackage :sharpquoteful-lisp
(:use :common-lisp)
(:shadow :lambda :defun)
(:export :lambda :defun))
(in-package :sharpquoteful-lisp)
(cl:defun function-form-p (x)
(and (consp x)
(eq (car x) 'function)))
(defmacro lambda (args &body body)
(let ((args-g (gensym))
(arg-alist (mapcan
(cl:lambda (arg)
(cond ((function-form-p arg)
(list (cons arg (gensym))))
((and (consp arg) (function-form-p (car arg)))
(list (cons (car arg) (gensym))))
(t nil)))
args)))
`(cl:lambda ,(sublis arg-alist args)
(cl:flet (,@(mapcar (cl:lambda (pair)
`(,(cadar pair) (&rest ,args-g)
(apply ,(cdr pair) ,args-g)))
arg-alist))
,@body))))
(cl:defmacro defun (name args &rest body)
`(setf (symbol-function ',name) (lambda ,args ,@body)))
;; Examples.
(shadow 'map)
(defun map (#'fun ls)
(if (null ls)
nil
(cons (fun (first ls))
(map #'fun (rest ls)))))
(defun hack (ls &optional (#'act #'print))
(dolist (i ls)
(act i)))
(print (map #'sqrt '(1 2 3 4 5)))
(hack '(1 2 3 4 5))
(hack '(1 2 3 4 5) #'princ)