Helmut Jarausch
4/13/2015 1:54:00 PM
On Monday, 13 April 2015 15:23:05 UTC+2, informatimago wrote:
> jarausch@skynet.be writes:
>
>
> > meanwhile I've found out that FORMAT can do the conversion.
>
> Stop being an idiot!
Thank you for the complements.
>
>
> > Here is what I was looking for
> >
> > (defun myfct (arg)
> > (+1 arg))
> >
> > (defmacro GenFct (This)
> > (let ((to-let
> > (if (search "VX" (format nil "~a" This)) `(vx (myfct op))
> > nil)))
> > `(defun foo (op)
> > (let (,to-let)
> > ,This))
> > ))
> >
> > (macroexpand-1 '(GenFct (1+ vx)))
> >
> > generates
> >
> > (DEFUN FOO (OP)
> > (LET ((VX (MYFCT OP)))
> > (1+ VX)))
> >
> > Unfortunately, in case the expression does not contain vx
> > it generates the invalid LET form
>
> What does that mean? What is vx? Do:
>
> (+ 1 vx)
>
> (vx 42)
>
> (print "hello vivxen!")
>
> (if (= a h)
> (progn
> (do-something (concatenate 'string viv #\v #\x en))
> 'ha)
> (+ 42 (vx 33)))
>
>
> "contain" vx???
In my case I know there aren't any string constants in the expression,
otherwise parsing it for beeing dependent on a given variable is much harder.
In my case I generate a local variable VX with some initialization iff the expression
depends on VX.
>
>
> > (LET (())
> >
> > Since I have several such variables I have to do more work to generate
> > of leave out the LET form. It would be nicer if I could generate a
> > No-Op LET form, but I don't know how.
>
> You don't know how to generate () when there are no variable, and how to
> generate ((a x) (b y)) when there are two variables???
>
Yes, that poses some problems to me, as can be seen here
(defun myfct (arg)
(+1 arg))
(defmacro GenFct (This)
(let ((to-let))
(if (search "VX" (format nil "~a" This)) (push `(vx (myfct op)) to-let))
WHAT-TO-BE-PUT-HERE )))
`(defun foo (op)
(let (,to-let) ;; s.t. ,to-let expands to the null string, i.e. I get (let () ...
,This))
))
The alternative solution is to initialize the list after LET to nil and push only those variable declarations I'd like to be there - this works.
But what could I assign to TO-LET to make (,TO-LET) "evaluate" to just () ?
Thanks for your patience.
P.S.
One application is the following
(defmacro AD-Fct (Funct Expr DExpr)
(let* ((ClassS (concatenate 'string "C-" (symbol-name Funct)))
(Class (intern ClassS))
(FCTs (concatenate 'string "AD-" (symbol-name Funct)))
(FCT (intern FCTs)))
`(progn
(defclass ,Class (Term) ((Op :initarg :Op)))
(defgeneric ,FCT (Op))
(defmethod ,FCT ((Op Term))
(make-instance ',Class :Op Op))
(defmethod EVL ((This ,Class) Arg)
(with-slots (Op) This
(let ((EOp (EVL Op Arg)))
,Expr)
))
(defmethod DIFF ((This ,Class) Arg)
(with-slots (Op) This
(let ((EOp (EVL Op Arg)) (DOp (DIFF Op Arg)))
;;; (declare (ignore EOp))
,DExpr)
))))
)
which is used as
(AD-BinOp AD* (* EOpL EOpR) (+ (* DOpL EOpR) (* EOpL DOpR)))
E.g. here, I'd like to suppress the local variable EOpL (including the function call)
if the second expression --- here (+ (* DOpL EOpR) (* EOpL DOpR)) ---
did not depend on EOpL