This question already has answers here:
Writing recursive GCD in Lisp
(4 answers)
Closed 6 years ago.
I am defining a simple function for power in CLISP as :
(defun power(B E)
(if (= E 1)
B
(* B ( power (B (- E 1))))))
But when I try to call the function like this:
(power 2 6)
I get the following error:
*** - EVAL: undefined function B
I tried the following code on Ideone.com as :
(defun power(B E)
(if (= E 1)
B
(* B ( power (B (- E 1))))))
(setq base (read))
(setq exponent (read))
(print (power(base exponent)))
with STDIN as
2
6
Then again, STDERR throws this error :
*** - EVAL: undefined function BASE
Why the argument B or BASE isn't seen as a variable but a function?
Numeric values are self-evaluative so why this code doesn't work?
(defun power (B E)
(if (= E 1)
B
(* B (power B (- E 1)))))
...you can't add in "redundant" parenthesis in Lisp the way you can with some other programming languages.
Related
This question already has answers here:
Common lisp push from function
(4 answers)
Closed 3 years ago.
I have a function:
(defun multi-push (L P)
(print (if L "T" "F"))
(print P)
(when L
(multi-push (cdr L) (push (car L) P)))
P)
which I have made in an to attempt to push a list onto another list (I am aware the input list L is reversed. This is by design). The print statements make sense, but when I look at the variable P, it is not mutated as I expect.
Sample REPL output:
CL-USER> bob
(3 3 3)
CL-USER> (multi-push (list 1 2) bob)
"T"
(3 3 3)
"T"
(1 3 3 3)
"F"
(2 1 3 3 3)
(1 3 3 3)
CL-USER> bob
(3 3 3)
What have I done wrong? I thought PUSH (according to [http://clhs.lisp.se/Body/m_push.htm]) mutates its second argument in place. I have also tried variations where I POP L and PUSH it onto P before calling multi-push on L and P again.
one thing of note is that the line (1 3 3 3) is the output of the function of multi-push. This also confuses me.
What push mutates destructively is a binding, not a list. More correctly what push modifies is a 'place' which is
a form which is suitable for use as a generalized reference
where a 'generalized reference' is
a reference to a location storing an object as if to a variable.
These two quotes are from the CLHS glossary: the section which talks about this is 5.1.
In particular:
> (let* ((l1 '(1 2 3))
(l2 l1))
(push 0 l1)
(values l1 l2))
(0 1 2 3)
(1 2 3)
And also note that this is legal CL since it doesn't destructively alter the quoted list structure. push must be a macro since a function can't do what it does: you can't write a function f such that:
(let* ((a (list 1 2 3))
(b a))
(f a b)
(not (eq a b)))
would be true.
You can think of (push x y) as expanding to something like (setf y (cons x y)), except that it will deal with multiple-evaluation properly.
If I create a closure like this,
(let ((A (make-array '(10) :initial-element 5)))
(defun h (i)
(aref a i))
(defsetf h (i) (x) `(setf (aref ,a ,i) ,x)))
then, as I expect, (h i) will return the i-th element of a:
(h 1) ;; => 5
(h 2) ;; => 5
Butalthough the setf expansion semes to work and correctly set the i-th element of a, it also produces a warning in SBCL:
(setf (h 1) 10)
; in: SETF (H 1)
; (SETF (AREF #(5 10 5 5 5 5 5 5 5 5) 1) #:G1124)
; --> LET* MULTIPLE-VALUE-BIND LET FUNCALL SB-C::%FUNCALL
; ==>
; ((SETF AREF) #:NEW0 #(5 10 5 5 5 5 5 5 5 5) 1)
;
; caught WARNING:
; Destructive function (SETF AREF) called on constant data.
; See also:
; The ANSI Standard, Special Operator QUOTE
; The ANSI Standard, Section 3.2.2.3
;
; compilation unit finished
; caught 1 WARNING condition
In GCL an error is signalled:
>(setf (h 1) 10)
Error:
Fast links are on: do (si::use-fast-links nil) for debugging
Signalled by LAMBDA-CLOSURE.
Condition in LAMBDA-CLOSURE [or a callee]: INTERNAL-SIMPLE-UNBOUND-VARIABLE: Cell error on A: Unbound variable:
Broken at LIST. Type :H for Help.
1 Return to top level.
In CLISP and ECL, the example works just fine.
I am returning to Common Lisp after writing Scheme for a couple of years, so I may be mixing the two languages, conceptually. I suppose I have triggered behavior that is undefined according to the spec, but I can't see exactly what I did wrong. I would appreciate any help with this!
Your Problem
It is often instructive to try macroexpand:
(macroexpand '(setf (h 2) 7))
==>
(LET* ()
(MULTIPLE-VALUE-BIND (#:G655)
7
(SETF (AREF #(5 5 5 5 5 5 5 5 5 5) 2) #:G655)))
As you can see, your setf call expands into a form which calls setf on a literal array which is a bad idea in general and, in fact, this is precisely what SBCL is warning you about:
Destructive function (SETF AREF) called on constant data.
Note that despite the warning SBCL (and other conformant implementations like CLISP and ECL) will do what you expect them to do.
This is because the literal array is referred to by the local variable which is accessible to the function h.
Solution
I suggest that you use a function instead
(let ((A (make-array '(10) :initial-element 5)))
(defun h (i)
(aref a i))
(defun (setf h) (x i)
(setf (aref a i) x)))
This question already has answers here:
Lisp function call error
(4 answers)
Closed 8 years ago.
I've defined the following function soma-n where n is an integer and l is a list.
(defun soma-n (n l)
(if (null l)
()
(cons (+ (first l) n) (soma-n (rest l)))))
I'm trying to call it as follows, but it seems that one of the arguments is not sent, since I'm getting the following error:
(soma-n 3 '(1 2 3))
; SOMA-N got 1 arg, wanted at least 2.
What is the problem with the way I'm calling the function?
this is what you probably wanted
(defun soma-n (n l)
(if (null l)
()
(cons (+ (first l) n) (soma-n n (rest l)))))
you were passing just a list to recursive call of some-n
I am not very good in Lisp and I need to do a function which allows evaluating of infix expressions. For example: (+ 2 3) -> (infixFunc 2 + 3). I tried some variants, but none of them was successful.
One of them:
(defun calcPrefInf (a b c)
(funcall b a c))
OK, let's do it just for fun. First, let's define order of precedence for operations, since when one deals with infix notation, it's necessary.
(defvar *infix-precedence* '(* / - +))
Very good. Now imagine that we have a function to-prefix that will convert infix notation to polish prefix notation so Lisp can deal with it and calculate something after all.
Let's write simple reader-macro to wrap our calls of to-prefix, for aesthetic reasons:
(set-dispatch-macro-character
#\# #\i (lambda (stream subchar arg)
(declare (ignore sub-char arg))
(car (reduce #'to-prefix
*infix-precedence*
:initial-value (read stream t nil t)))))
Now, let's write a very simple function to-prefix that will convert infix notation to prefix notation in given list for given symbol.
(defun to-prefix (lst symb)
(let ((pos (position symb lst)))
(if pos
(let ((e (subseq lst (1- pos) (+ pos 2))))
(to-prefix (rsubseq `((,(cadr e) ,(car e) ,(caddr e)))
e
lst)
symb))
lst)))
Good, good. Function rsubseq may be defined as:
(defun rsubseq (new old where &key key (test #'eql))
(labels ((r-list (rest)
(let ((it (search old rest :key key :test test)))
(if it
(append (remove-if (constantly t)
rest
:start it)
new
(r-list (nthcdr (+ it (length old))
rest)))
rest))))
(r-list where)))
Now it's time to try it!
CL-USER> #i(2 + 3 * 5)
17
CL-USER> #i(15 * 3 / 5 + 10)
19
CL-USER> #i(2 * 4 + 7 / 3)
31/3
CL-USER> #i(#i(15 + 2) * #i(1 + 1))
34
etc.
If you want it to work for composite expressions like (2 + 3 * 5 / 2.4), it's better to convert it into proper prefix expression, then evaluate it. You can find some good example of code to do such convetion here: http://www.cs.berkeley.edu/~russell/code/logic/algorithms/infix.lisp or in Piter Norvigs "Paradigs of Artificial Intelligence Programming" book. Code examples here: http://www.norvig.com/paip/macsyma.lisp
It's reall too long, to be posted in the aswer.
A different approach for "evaluating infix expressions" would be to enable infix reading directly in the Common Lisp reader using the "readable" library, and then have users use the notation. Then implement a traditional Lisp evaluator (or just evaluate directly, if you trust the user).
Assuming you have QuickLisp enabled, use:
(ql:quickload "readable")
(readable:enable-basic-curly)
Now users can enter any infix expression as {a op b op c ...}, which readable automatically maps to "(op a b c ...)". For example, if users enter:
{2 + 3}
the reader will return (+ 2 3). Now you can use:
(eval (read))
Obviously, don't use "eval" if the user might be malicious. In that case, implement a function that evaluates the values the way you want them to.
Tutorial here:
https://sourceforge.net/p/readable/wiki/Common-lisp-tutorial/
Assuming that you're using a lisp2 dialect, you need to make sure you're looking up the function you want to use in the function namespace (by using #'f of (function f). Otherwise it's being looked up in the variable namespace and cannot be used in funcall.
So having the definition:
(defun calcPrefInf (a b c)
(funcall b a c))
You can use it as:
(calcPrefInf 2 #'+ 3)
You can try http://www.cliki.net/infix.
(nfx 1 + (- x 100)) ;it's valid!
(nfx 1 + (- x (3 * 3))) ;it's ALSO valid!
(nfx 1 + (- x 3 * 3)) ;err... this can give you unexpected behavior
I'm very new to lisp and I am working on basic syntax. I am trying to convert:
r1 = (-b + sqrt(b^2 - 4*a*c))/(2*a)
into a lisp format. The only problem I think I am having is that I cannot get lisp to recognize -b as the negative value of my symbol b. This is what I have so far from the lisp prompt:
[17]> (setq a 1L0)
1.0L0
[18]> (setq b -1L0)
-1.0L0
[19]> (setq c -1L0)
-1.0L0
[20]> (setq r1 (+ (/ (sqrt (- (power b 2) (* (* 4 a) c))) (* 2 a)) -b))
*** - EVAL: variable -B has no value
The following restarts are available:
USE-VALUE :R1 You may input a value to be used instead of -B.
STORE-VALUE :R2 You may input a new value for -B.
ABORT :R3 Abort main loop
use
(- b)
to negate b. It is equivalent to
(- 0 b)