Lisp: same mathematical function evaluates to different values at different time?
Asked Answered
B

1

7

I have to compute a polynomial like this --

f(x) = x^4 - 2.274x^3 + 1.8x^2 - 0.576x + 1.0

with this lisp function --

(defun polynomial (x)
  (+ (+ (+ (+ (expt x 4) (* -2.274 * (expt x 3)))
       (* 1.8 (* x x))) (* -0.576 x)) 0.1))

when I call (polynomial 0.5) the result is different at different evaluations, like this --

CL-USER> (polynomial 0.5)
-1.9495
CL-USER> (polynomial 0.5)
0.8786454
CL-USER> (polynomial 0.5)
0.07474504
CL-USER> (polynomial 0.5)
0.3032537
CL-USER> (polynomial 0.5)
0.23830011
CL-USER> 

what is going on ? I am using the latest sbcl.

Benne answered 23/9, 2014 at 20:5 Comment(0)
M
17

* in argument position evaluates to the very last result you had in the REPL. In your code you do (* -2.274 * (expt x 3)) where * is -1.9495 perhaps after the first run. (You'd get an error when running it the first time if the last result was not a number.)

You can have multiple arguments to both * and + and all LISPs has polish prefix notation so your function might look better like this:

;; f(x) = x^4 - 2.274x^3 + 1.8x^2 - 0.576x + 1.0
(defun polynomial (x)
  (+ (expt x 4) 
     (* -2.274 (expt x 3))
     (* 1.8 x x)
     (* -0.576 x) 
     1.0)) ;; this was originally 0.1

(polynomial 0.5) ; ==>  0.94025004

Basically x + y + z in infix becomes (+ x y z) in prefix.

Monika answered 23/9, 2014 at 20:9 Comment(6)
(* -2.274 * (expt x 3)) was my coding mistake and the REPL is assigning values to *! now I understand why lisp is an alien technology.Benne
That's not all that strange. Doesn't the python repl do a similar thing with _? Also see **, ***, /, //, and ///.Guernica
@JoshuaTaylor IMO * inside defun should produce a warning in a usually verbose SBCL while I wouldn't expect it in other implementations.Monika
@Monika IMHO, there is not only historically a big difference between a RPL ( reverse-polish-notation ) and LISP ( list-processing )Embayment
@Embayment I haven't mentioned Reverse polish prefix (like Forth) at all. Only infix (like ALGOL) and Polish prefix (like LISP).Monika
@Monika Sure, tried to make a difference between a LISt-Processing, where the arity of the operator goes step-wise extended/re-iterated "over" the given list of operands, while the Lukasiewics' Polish Notation was arity-strict ( non-extensible ). Anyway, thanks -- you've made me remember the great days with RPL-coding on HP67.Embayment

© 2022 - 2024 — McMap. All rights reserved.