Writing recursive GCD in Lisp

2019-03-06 04:19发布

问题:

I keep getting random errors when compiling this function:

(defun gcd (a b)
  (if (= b 0)
      a
      (gcd b mod (a b))))

The most common is that it says "undefined function a." So I figured I needed return a in that place. This did not work. I get a to many parameters for if statement error. Any idea what I am doing wrong here? New to Lisp and so far we are not seeing eye to eye.

Running on CLISP on Windows 7.

回答1:

In Lisp a function call always* starts with '(', so the line

(gcd b mod(a b))

means "call the function gcd with arguments b, mod and the result of calling function a with argument b".

I suspect you really want something like:

(gcd b (mod a b))

*I haven't used Lisp for a little while so I might not be 100% correct on the "always".



回答2:

(gcd b mod(a b)) should be (gcd b (mod a b))



回答3:

You mod function call is wrong. Here's my working code:

(defun gcd2(a b)
  (if (= b 0) a (gcd2 b (mod a b))))


回答4:

Usually a compiler can give you more information:

Using LispWorks:

(defun gcd1 (a b)
  (if (= b 0)
      a
      (gcd1 b mod (a b))))


CL-USER 31 > (compile 'gcd1)
;;;*** Warning in GCD1: GCD1 is called with the wrong number of arguments: Got 3 wanted 2
;;;*** Warning in GCD1: MOD assumed special

The following function is undefined:
A which is referenced by GCD1
GCD1

So you see that you call GCD1 with the wrong number of arguments, that MOD is assumed to be a variable and that A is assumed to be a function.

SBCL:

; in: DEFUN GCD1
;     (GCD1 B MOD (A B))
; 
; caught WARNING:
;   The function was called with three arguments, but wants exactly two.

; in: DEFUN GCD1
;     (A B)
; 
; caught STYLE-WARNING:
;   undefined function: A

;     (GCD1 B MOD (A B))
; 
; caught WARNING:
;   undefined variable: MOD