Hi,
is it possible to transform the infix.lsp to a "true" macro i.e. doing the work at compile time ?
Or do i miss a critical point there ?
Calling "eval" during runtime is supposed to be expensive (at least in other lisps). Not sure how newlisp handles eval.
Reason for asking is that i redo some of the quaternion calculus as well as geographic math scripts.
i.e.
(INFIX:xlate "εk2 = aekb1  aejbi + aeibj + aebk + akbe  ajbei + aibej + a1bek")
> (setq εk2 (add (add (sub (add (add (add (sub aekb1 aejbi) aeibj) aebk) akbe) ajbei)
aibej) a1bek))
(INFIX:xlate "e3Xe4_x = sin(y3  y4) * sin((x3 + x4) / 2) * cos((x3  x4) / 2)  sin(y3 + y4) * cos((x3 + x4) / 2) * sin((x3  x4) / 2)")
> (setq e3Xe4_x (sub (mul (mul (sin (sub y3 y4)) (sin (div (add x3 x4) 2))) (cos (div (sub x3 x4) 2)))
I still can't wrap my mind around the lisp math syntax ... old school i fear ...
Infix.lsp as macro

 Posts: 216
 Joined: Mon Jun 02, 2014 1:40 am
 Location: Melbourne, Australia
Re: Infix.lsp as macro
You may do this kind of thing in two steps. Firstly, you define a macro, e.g. Thereafter you redefine it to perform the "xlate" call the way you want it, e.g.
Now you can use this in new definitions and expressions with "readtime" xlateion. E.g.,
Of course, you might want to name it something else than 'mix.
Code: Select all
> (macro (mix) nil)
(lambdamacro () (expand 'nil))
Code: Select all
> (constant 'mix (lambdamacro () (INFIX:xlate (join (map string (args)) " "))))
(lambdamacro () (INFIX:xlate (join (map string (args)) " ")))
Code: Select all
> (define (foo a b) (mix a + b))
(lambda (a b) (add a b))
> '(mix 4 * 5 + sin(34) * 8 )
(add (mul 4 5) (mul (sin 34) 8))
> (mix 4 * 5 + sin(34) * 8 )
24.23266148896019
Re: Infix.lsp as macro
thanks a ton. I must admit that i would never ever thought of a redefiniton.
Can you explain why the macro becomes "executable" due to the redefiniton ?
Can you explain why the macro becomes "executable" due to the redefiniton ?

 Posts: 216
 Joined: Mon Jun 02, 2014 1:40 am
 Location: Melbourne, Australia
Re: Infix.lsp as macro
Well, being or not being a macro is, I believe, some flag attached to the symbol, which is set by the "(macro ..)" term. That term also wraps the given "body" into an "expand" term, as is typically useful for these kinds of macros. But not in this case, where you want the xlateion to be invoked at read time.
The "(constant ...)" term simply attaches a new definition to the symbol without messing with the flag, and thus redefines it. The manual has some discussion about this point.
The "(constant ...)" term simply attaches a new definition to the symbol without messing with the flag, and thus redefines it. The manual has some discussion about this point.
Re: Infix.lsp as macro
Exactly what is needed. Thx.
A minor setback is that infix.lsp does not handle "" with one argument.
Math code is much clearer now.
Proof of expansion during read time attached.
A minor setback is that infix.lsp does not handle "" with one argument.
Math code is much clearer now.
Proof of expansion during read time attached.
Code: Select all
(load "infix.lsp")
(macro (mix) nil)
(constant 'mix (lambdamacro ()
(INFIX:xlate (join (map string (args)) " "))))
(define (quatmul q1 q2)
(let ((x1 (nth 0 q1)) (y1 (nth 1 q1)) (z1 (nth 2 q1)) (w1 (nth 3 q1))
(x2 (nth 0 q2)) (y2 (nth 1 q2)) (z2 (nth 2 q2)) (w2 (nth 3 q2)))
(mix w = 0  x1 * x2  y1 * y2  z1 * z2 + w1 * w2)
(mix x = x1 * w2 + y1 * z2  z1 * y2 + w1 * x2)
(mix y = 0  x1 * z2 + y1 * w2 + z1 * x2 + w1 * y2)
(mix z = x1 * y2  y1 * x2 + z1 * w2 + w1 * z2)))
(quatmul '(1 2 3 4) '(9 4 4 4)) > Should be 42
(string (source 'quatmul))
==>
(define (quatmul q1 q2)
(let ((x1 (nth 0 q1)) (y1 (nth 1 q1)) (z1 (nth 2 q1)) (w1 (nth 3 q1))
(x2 (nth 0 q2)) (y2 (nth 1 q2)) (z2 (nth 2 q2)) (w2 (nth 3 q2)))
(setq w (add (sub (sub (sub 0 (mul x1 x2)) (mul y1 y2)) (mul z1 z2)) (mul w1 w2)))
(setq x (add (sub (add (mul x1 w2) (mul y1 z2)) (mul z1 y2)) (mul w1 x2)))
(setq y (add (add (add (mul (sub 0 x1) z2) (mul y1 w2)) (mul z1 x2)) (mul w1 y2)))
(setq z (add (add (sub (mul x1 y2) (mul y1 x2)) (mul z1 w2)) (mul w1 z2)))))