hey /prog/, I'm trying to do something simple and failing hard. I seem to be missing something obvious, but I'm not sure what. Using DrScheme here.
Suppose I have a list that represents infix notation, e.g.,
(1 + 2)
and I want to evaluate it. I can create a list that is in prefix notation assuming a simple list in this form: (define infix->prefix (lambda (x)
(list (cadr x)
(car x)
(caddr x))))
And then > (infix->prefix '(2 + 3))
(list '+ 2 3)
>
But, er, how would I evaluate this? That is, what am I missing so that > (infix->prefix '(2 + 3))
5
>
>>2
yeah fucking DrScheme's "easing into Scheme" method doesn't allow eval unless I turn on GOD MODE.
Name:
Anonymous2009-05-23 12:46
>>3
apply: expects type <procedure> as 1st argument
fail. Nice bbcode tho.
Name:
Anonymous2009-05-23 12:57
If you use eval, you are doing it wrong.
You probably want a macro, but it would be better if you learned some more first. You don't give a toddler a scalpel.
Name:
Anonymous2009-05-23 13:12
>>8
I thought we were singing the song.
I feel kind of bad about it . : (
Name:
Anonymous2009-05-23 15:34
common lisp, the macro is not safe to use with expressions that have side effects. (defmacro doit (x &optional y &rest z) (if y `(,y ,x (doit ,@z)) x))
>>9
::whips out chainsaw::
I think I've got it, but it seems messy. Maybe there's a cleaner way I'm not seeing? I've tried some complicated expressions and it seems to evaluate everything correctly. The trick was getting division and multiplication to work themselves out safely before giving add a chance.
(define-syntax infix
(syntax-rules (*)
((infix a op b)
(op a b))
((infix a op b * c)
(op a (* b c)))
((infix a op1 b * c op2 ...)
(infix a op1 (* b c) op2 ...))
((infix a op1 b op2 c * d)
(infix a op1 b op2 (* c d)))
((infix a op1 b op2 c * d op ...)
(infix a op1 b op2 (* c d) op ...))
((infix a * b op ...)
(infix (* a b) op ...))
((infix exp ...)
(m_div exp ...))))
(define-syntax m_div
(syntax-rules (* /)
((a op b)
(op a b))
((div a op b / c)
(m_add a op (/ b c)))
((m_div a / b * c)
(/ a (* b c)))
((div a / b op c)
(op (/ a b) c))
((div a op1 b / c op2 ...)
(infix a op1 (/ b c) op2 ...))
((div a / b op c ...)
(infix (/ a b) op c ...))
((div exp ...)
(m_add exp ...))))
(define-syntax m_add
(syntax-rules (* /)
((m_add a op b)
(op a b))
((m_add a op1 b op2 ...)
(infix (op1 a b) op2 ...))
((m_add exp ...)
(infix exp ...))))
Name:
Anonymous2009-05-27 19:32
It would be trivial in Haskell.
I pray the Sussman will someday awake from His slumber and write a new Scheme standard called IPv7¹ to unite our minds and spirits of computer into the universal spiritual network of infinite Satori.
Improved. (define-syntax infix
(syntax-rules (* / i)
((infix i op b)
(infix 0+1i op b))
((infix a op i)
(infix a op 0+1i))
((infix a op1 i op2 ...)
(infix a op1 0+1i op2 ...))
((infix a op b)
(op a b))
((infix a / b * c)
(* (/ a b) c))
((infix a / b * c ...)
(infix (/ a b) * c ...))
((infix a op b * c)
(op a (* b c)))
((infix a * b op ...)
(infix (* a b) op ...))
((infix a op b / c)
(infix a op (/ b c)))
((infix a op1 b / c op2 ...)
(infix a op1 (/ b c) op2 ...))
((infix a op1 b * c op2 ...)
(infix a op1 (* b c) op2 ...))
((infix a op1 b op2 ...)
(infix (op1 a b) op2 ...))))
M&D have the same precedence, transformed left-to-right.
Fuck yeah improved (define-syntax infix
(syntax-rules (^ * / i)
((infix i op b) (infix 0+1i op b))
((infix a op i) (infix a op 0+1i))
((infix a op1 i op2 ...) (infix a op1 0+1i op2 ...))
((infix a op b) (op a b))
((infix a ^ b ^ c) (infix a ^ (* b c)))
((infix a ^ b ^ c op ...) (infix a ^ (* b c) op ...))
((infix a ^ b op ...) (infix (^ a b) op ...))
((infix a op b ^ c ^ d) (infix a op b ^ (* c d)))
((infix a op1 b ^ c ^ d op2 ...) (infix a op1 b ^ (* c d) op2 ...))
((infix a op b ^ c) (infix a op (^ b c)))
((infix a op1 b ^ c op2 ...) (infix a op1 (^ b c) op2 ...))
((infix a op1 b op2 c ^ d) (infix a op1 b op2 (^ c d)))
((infix a op1 b op2 c ^ d ^ e) (infix a op1 b op2 c ^ (* d e)))
((infix a op1 b op2 c ^ d ^ e op3 ...) (infix a op1 b op2 c ^ (* d e) op3 ...))
((infix a op1 b op2 c ^ d op3 ...) (infix a op1 b op2 (^ c d) op3 ...))
((infix a / b * c) (* (/ a b) c))
((infix a / b * c ...) (infix (/ a b) * c ...))
((infix a op b * c) (op a (* b c)))
((infix a * b op ...) (infix (* a b) op ...))
((infix a op b / c) (infix a op (/ b c)))
((infix a op1 b / c op2 ...) (infix a op1 (/ b c) op2 ...))
((infix a op1 b * c op2 ...) (infix a op1 (* b c) op2 ...))
((infix a op1 b op2 ...) (infix (op1 a b) op2 ...))))
Requires the operator ^ to be defined. (define ^
(λ(a to-the-b)
(if (integer? to-the-b)
(letrec ((iterate
(λ(ac x y)
(if (zero? y)
ac
(iterate (* ac x) x (- y 1))))))
(iterate 1 a to-the-b))
(exp (infix to-the-b * (log a))))))