Arc Forumnew | comments | leaders | submitlogin
2 points by cadaver 6114 days ago | link | parent

Example, redefining +:

  (def + args
    (infix-eval
      (cons (car args)
            (cons + (cdr args)))))


1 point by eds 6114 days ago | link

Ok, I see what you are saying. It happens that + is already a scheme lambda wrapper around the scheme primitive +, so I guess you'd just modify the existing function. But you would have to add wrappers for the other primitives.

It seems a little strange to me to mix infix and prefix. But I don't see any reason to disallow it.

-----

1 point by eds 6113 days ago | link

After a little work I got +-/* to handle infix evaluation themselves, allowing ar-apply to just switch the positions of the first two arguments. This allows user defined operators, but you have to be careful to make a base case for after infix to prefix conversion. For example:

  (def % args
    (if (some [isa _ 'fn] args)
        (infix-eval (cons (car args) (cons % (cdr args))))
        (apply mod args)))
In (3 % 4 + 5), % will get called twice, once to get the initial infix conversion going, and again after the expression has been converted to prefix. So if you don't have the second case, you'll just get into an infinite loop.

I'm still trying to work out what is the best way to allow user-defined precedence. In the above case, (3 % 4 + 5) will evaluate as (% 3 (+ 4 5)) not (+ (% 3 4) 5), because by default it is lowest precedence. I wrote a little set-precedence function that can be called to do the job:

  (set-precedence % 2)
or

  (set-precedence % *)
(The second version looks up the precedence of * and sets % to that precedence.)

But this method of setting precedence seems a little like a hack. And it doesn't play nicely with =. Any suggestions would be welcome.

-----