Consider this question. Here the basic problem is the code:
(progv '(op arg) '(1+ 1)
(eval '(op arg)))
The problem here is that progv
binds the value to the variable as variable's symbol-value
not symbol-function
. But, that's obvious because we didn't explicitly suggest which values are functions.
The Plan
So, in order to solve this problem, I thought of manually dynamically binding the variables, to their values based on the type of values. If the values are fboundp
then they should be bound to the symbol-function
of the variable. A restriction, is that match-if
can't be a macro
. It has to be a function
, because it is called by a funcall
.
Macro : functioner
:
(defmacro functioner (var val)
`(if (and (symbolp ',val)
(fboundp ',val))
(setf (symbol-function ',var) #',val)
(setf ,var ,val)))
Function: match-if
:
(defun match-if (pattern input bindings)
(eval `(and (let ,(mapcar #'(lambda (x) (list (car x))) bindings)
(declare (special ,@ (mapcar #'car bindings)))
(loop for i in ',bindings
do (eval `(functioner ,(first i) ,(rest i))))
(eval (second (first ,pattern))))
(pat-match (rest ,pattern) ,input ,bindings))))
Here, the let
part declares all the variables lexically (supposedly). Then declare
declares them special
. Then functioner
binds the variables and their values aptly. Then the code in the pattern is evaluated. If the code part is true, then only the pattern-matcher function pat-match
is invoked.
The Problem
The problem is that in the function, all it's arguments are evaluated. Thus bindings
in the let
and declare
parts will be replaced by something like :
((v1 . val1)(v2 . val2)(v3 . val3))
not
'((v1 . val1)(v2 . val2)(v3 . val3))
So, it's treated as code, not a list.
So, I'm stuck here. And macros won't help me on this one.
Any help appreciated.