Program For Addition Of Two Numbers In Lisp
A function is a group of statements that together perform a task. You can divide up your code into separate functions. How you divide up your code among different functions is up to you, but logically the division usually is so each function performs a specific task. Defining Functions in LISP The macro named defun is used for defining functions. The defun macro needs three arguments:.
Name of the function. Parameters of the function. Body of the function Syntax for defun is: (defun name (parameter-list) 'Optional documentation string.'
Lisp Code: Add two list Can we have a function that can add two list to one, such as (add '(1 2 3) '. A Lisp program for calculating postfix operation. Wiki has endured a number of abuses mostly protected by the goodwill of an obscure community for whom I have tremendous respect: wiki's authors.
Using outdated or corrupt Pantech Mobile Phone drivers can cause system errors, crashes, and cause your computer or hardware to fail. Verizon usb modem pantech. Maintaining updated Pantech Mobile Phone software prevents crashes and maximizes hardware and system performance.
Body) Let us illustrate the concept with simple examples. Example 1 Let's write a function named averagenum that will print the average of four numbers. We will send these numbers as parameters. Create a new source code file named main.lisp and type the following code in it.
(defun averagenum (n1 n2 n3 n4) (/ ( + n1 n2 n3 n4) 4) ) (write(averagenum 10 20 30 40)) When you execute the code, it returns the following result: 25 Example 2 Let's define and call a function that would calculate the area of a circle when the radius of the circle is given as an argument. Create a new source code file named main.lisp and type the following code in it. (defun area-circle(rad) 'Calculates area of a circle with given radius' (terpri) (format t 'Radius: 5f' rad) (format t '%Area: 10f' (. 3.141592 rad rad)) ) (area-circle 10) When you execute the code, it returns the following result: Radius: 10.0 Area: 314.1592 Please note that:. You can provide an empty list as parameters, which means the function takes no arguments, the list is empty, written as.
Alp For Addition Of Two Numbers
LISP also allows optional, multiple, and keyword arguments. The documentation string describes the purpose of the function. It is associated with the name of the function and can be obtained using the documentation function. The body of the function may consist of any number of Lisp expressions. The value of the last expression in the body is returned as the value of the function. You can also return a value from the function using the return-from special operator.
Let us discuss the above concepts in brief. Click following links to find details:.
LISP Tutorial 1: Basic LISP Programming LISP Tutorial 1: Basic LISP Programming LISP Expressions When you start up the Common LISP environment, you should see a prompt, which means that LISP is waiting for you to enter a LISP expression. In the environment I am using, it looks like the following: USER(1): The Common LISP environment follows the algorithm below when interacting with users: loop read in an expression from the console; evaluate the expression; print the result of evaluation to the console; end loop. Common LISP reads in an expression, evaluates it, and then prints out the result. For example, if you want to compute the value of (2. cos(0).
(4 + 6)), you type in: USER(1): (. 2 (cos 0) (+ 4 6)) Common LISP replies: 20.0 before prompting you to enter the next expression. Several things are worth noting:.
LISP expressions are composed of forms. The most common LISP form is function application. LISP represents a function call f(x) as (f x). For example, cos(0) is written as (cos 0).
LISP expressions are case-insensitive. It makes no difference whether we type (cos 0) or (COS 0). Similarly, ' +' is the name of the addition function that returns the sum of its arguments. Some functions, like ' +' and '.'
, could take an arbitrary number of arguments. In our example, '.' took three arguments.
It could as well take 2 arguments, as in ' (. 2 3)', or 4 arguments, as in ' (.
2 3 4 5)'. In general, a function application form looks like ( function argument 1 argument 2. As in many programming languages (e.g. C/C), LISP evaluates function calls in applicative order, which means that all the argument forms are evaluated before the function is invoked.
That is to say, the argument forms (cos 0) and (+ 4 6) are respectively evaluated to the values 1 and 10 before they are passed as arguments to the. function. Some other forms, like the conditionals we will see later, are not evaluated in applicative order.
Numeric values like 4 and 6 are called self-evaluating forms: they evaluate to themselves. To evaluate (+ 4 6) in applicative order, the forms 4 and 6 are respectively evaluated to the values 4 and 6 before they are passed as arguments to the + function.
Complex arithmatic expressions can be constructed from built-in functions like the following: Numeric Functions Meaning (+ x 1 x 2. X n) The sum of x 1, x 2., x n (. x 1 x 2.
X n) The product of x 1, x 2., x n (- x y) Subtract y from x (/ x y) Divide x by y (rem x y) The remainder of dividing x by y (abs x) The absolute value of x (max x 1 x 2. X n) The maximum of x 1, x 2., x n (min x 1 x 2.
X n) The minimum of x 1, x 2., x n Common LISP has a rich set of pre-defined numerical functions. For a complete coverage, consult Chapter 12 of the book, Common LISP, The Language (2nd Edition) (CLTL2) by Guy Steele. In general, we will not be able to cover all aspects of Common LISP in this tutorial. Adventurous readers should consult CLTL2 frequently for more in-depth explanation of various features of the language. Exercise: Look up pages 376-378 of CLTL2 and find out what the functions floor and ceiling are for. Then, find out the subtle difference between mod and rem. Defining Functions Evaluating expressions is not very interesting.
We would like to build expression abstractions that could be reused in the future. For example, we could type in the following: USER(2): (defun double (x) (. x 2)) DOUBLE In the above, we define a function named double, which returns two times the value of its input argument x.
We can then test-drive the function as below: USER(3): (double 3) 6 USER(4): (double 7) 14 Editing, Loading and Compiling LISP Programs Most of the functions we would like to write is going to be a lot longer than the double function. When working with complex programs, it is usually desirable to edit the program with an editor, fully debug the code, and then compile it for faster performance. Use your favorite text editor (mine is emacs) to key in the following function definition:;;; testing.lisp;;; by Philip Fong;;;;;; Introductory comments are preceded by ';;;';;; Function headers are preceded by ';;';;; Inline comments are introduced by ';';;;;;;; Triple the value of a number;; (defun triple (X) 'Compute three times X.'
; Inline comments can (. 3 X)); be placed here.;;;; Negate the sign of a number;; (defun negate (X) 'Negate the value of X.'
; This is a documentation string. (- X)) Save the above in the file testing.lisp. Now load the definition into the LISP environment by typing: USER(5): (load 'testing.lisp'); Loading./testing.lisp T Let us try to see if they are working properly.
USER(6): (triple 2) 6 USER(7): (negate 3) -3 When functions are fully debugged, we can also compile them into binaries: USER(8): (compile-file 'testing.lisp') Depending on whether your code is well-formed, and what system you are using, some compilation messages will be generated. The compiled code can be loaded into the LISP environment later by using the following: USER(9): (load 'testing'); Fast loading./testing.fasl T Control Stuctures: Recursions and Conditionals Now that we are equipped with all the tools for developing LISP programs, let us venture into something more interesting.
Consider the definition of factorials: n! = 1 if n = 1 n! = n. (n - 1)! If n 1 We can implement a function to compute factorials using recursion: (defun factorial (N) 'Compute the factorial of N.' (if (= N 1) 1 (.
N (factorial (- N 1))))) The if form checks if N is one, and returns one if that is the case, or else returns N. (N - 1)! Several points are worth noting:. The condition expression (= N 1) is a relational expression.
It returns boolean values T or NIL. In fact, LISP treats NIL as false, and everything else as true. Other relational operators include the following: Relational Operators Meaning (= x y) x is equal to y (/= x y) x is not equal to y ( x y) x is greater than y (= x y) x is no less than y. The if form is not a strict function (strict functions evaluate their arguments in applicative order).
Instead, the if form evaluates the condition (= N 1) before further evaluating the other two arguments. If the condition evaluates to true, then only the second argument is evaluated, and its value is returned as the value of the if form. Otherwise, the third argument is evaluated, and its value is returned. Forms that are not strict functions are called special forms. The function is recursive. The definition of factorial involves invocation of itself.
Recursion is, for now, our only mechanism for producing looping behavior. Specifically, the kind of recursion we are looking at is called linear recursion, in which the function may make at most one recursive call from any level of invocation. To better understand the last point, we can make use of the debugging facility trace (do not compile your code if you want to use trace): USER(11): (trace factorial) (FACTORIAL) USER(12): (factorial 4) 0: (FACTORIAL 4) 1: (FACTORIAL 3) 2: (FACTORIAL 2) 3: (FACTORIAL 1) 3: returned 1 2: returned 2 1: returned 6 0: returned 24 24 Tracing factorial allows us to examine the recursive invocation of the function. As you can see, at most one recursive call is made from each level of invocation. Exercise: The N'th triangular number is defined to be 1 + 2 + 3 +. Alternatively, we could give a recursive definition of triangular number as follows: T(n) = 1 if n = 1 T(n) = n + T(n-1) if n 1 Use the recursive definition to help you implement a linearly recursive function (triangular N) that returns the N'th triangular number. Enter your function definition into a text file.
Then load it into LISP. Trace the execution of (triangular 6).
Exercise: Write down a recursive definition of B E (assuming that both B and E are non-negative integers). Then implement a linearly recursive function (power B E) that computes B E. Enter your function definition into a text file. Then load it into LISP.
Trace the execution of (power 2 6). Multiple Recursions Recall the definition of Fibonacci numbers: Fib(n) = 1 for n = 0 or n = 1 Fib(n) = Fib(n-1) + Fib(n-2) for n 1 This definition can be directly translated to the following LISP code: (defun fibonacci (N) 'Compute the N'th Fibonacci number.' (if (or (zerop N) (= N 1)) 1 (+ (fibonacci (- N 1)) (fibonacci (- N 2))))) Again, several observations can be made. First, the function call (zerop N) tests if N is zero.
It is merely a shorthand for (= N 0). As such, zerop returns either T or NIL. We call such a boolean function a predicate, as indicated by the suffix p. Some other built-in shorthands and predicates are the following: Shorthand Meaning (1+ x) (+ x 1) (1- x) (- x 1) (zerop x) (= x 0) (plusp x) ( x 0) (minusp x) ( 0:. Case 2.1: N = 0.
The zeroth element of L is simply (first L). Case 2.2: N 0. The N'th member of L is exactly the (N-1)'th member of (rest L). The following code implements our algorithm: (defun list-nth (N L) 'Return the N'th member of a list L.' (if (null L) nil (if (zerop N) (first L) (list-nth (1- N) (rest L))))) Recall that (1- N) is merely a shorthand for (- N 1). Notice that both our implementation and its correctness argument closely follow the standard pattern of structural recursion.
Tracing the execution of the function, we get: USER(61): (list-nth 2 '(a b c d)) 0: (LIST-NTH 2 (A B C D)) 1: (LIST-NTH 1 (B C D)) 2: (LIST-NTH 0 (C D)) 2: returned C 1: returned C 0: returned C C Exercise: LISP has a built-in function (last L) that returns a the last cons structure in a given list L. USER(62): (last '(a b c d)) (d) USER(63): (last '(1 2 3)) (3) Implement your own version of last using linear recursion. You may assume that (last nil) returns nil. Compare your implementation with the standard pattern of structural recursion. Notice that we have a standard if-then-else-if structure in our implementation of list-nth. Such logic can alternatively be implemented using the cond special form. (defun list-nth (n L) 'Return the n'th member of a list L.'
(cond ((null L) nil) ((zerop n) (first L)) (t (list-nth (1- n) (rest L))))) The cond form above is evaluated as follows. The condition (null L) is evaluated first.
If the result is true, then nil is returned. Otherwise, the condition (zerop n) is evaluated.
If the condition holds, then the value of (first L) is returned. In case neither of the conditions holds, the value of (list-nth (1- n) (rest L)) is returned. Exercise: Survey CLTL2 section 7.6 (pages 156-161) and find out what other conditional special forms are available in Common LISP. Do you know when the special forms when and unless should be used instead of if? Example: member LISP defines a function (member E L) that returns non-NIL if E is a member of L.
USER(64): (member 'b '(perhaps today is a good day to die)); test fails NIL USER(65): (member 'a '(perhaps today is a good day to die)); returns non-NIL '(a good day to die) We implement our own recursive version as follows: (defun list-member (E L) 'Test if E is a member of L.' (cond ((null L) nil) ((eq E (first L)) t) (t (list-member E (rest L))))) The correctness of the above implementation is easy to justify. The list L is either constructed by nil or by a call to cons:.
Case 1: L is nil. L is empty, and there is no way E is in L. Case 2: L is constructed by cons Then it has two components: (first L) and (rest L). There are two cases, either (first L) is E itself, or it is not. Case 2.1: E equals (first L). This means that E is a member of L,. Case 2.2: E does not equal (first L).
Then E is a member of L iff E is a member of (rest L). Tracing the execution of list-member, we get the following: USER(70): (list-member 'a '(perhaps today is a good day to die)) 0: (LIST-MEMBER A (PERHAPS TODAY IS A GOOD DAY TO DIE)) 1: (LIST-MEMBER A (TODAY IS A GOOD DAY TO DIE)) 2: (LIST-MEMBER A (IS A GOOD DAY TO DIE)) 3: (LIST-MEMBER A (A GOOD DAY TO DIE)) 3: returned T 2: returned T 1: returned T 0: returned T T In the implementation of list-member, the function call (eq x y) tests if two symbols are the same. In fact, the semantics of this test determines what we mean by a member: USER(71): (list-member '(a b) '((a a) (a b) (a c))) 0: (LIST-MEMBER (A B) ((A A) (A B) (A C))) 1: (LIST-MEMBER (A B) ((A B) (A C))) 2: (LIST-MEMBER (A B) ((A C))) 3: (LIST-MEMBER (A B) NIL) 3: returned NIL 2: returned NIL 1: returned NIL 0: returned NIL NIL In the example above, we would have expected a result of t. However, since '(a b) does not eq another copy of '(a b) (they are not the same symbol), list-member returns nil.
If we want to account for list equivalence, we could have used the LISP built-in function equal instead of eq. Common LISP defines the following set of predicates for testing equality: (= x y) True if x and y evaluate to the same number. (eq x y) True if x and y evaluate to the same symbol. (eql x y) True if x and y are either = or eq.
(equal x y) True if x and y are eql or if they evaluate to the same list. (equalp x y) To be discussed in Tutorial 4. Exercise: What would be the behavior of list-member if we replace eq by =? Example: append LISP defines a function append that appends one list by another: USER(72): (append '(a b c) '(c d e)) (A B C C D E) We implement a recursive version of append. Suppose we are given two lists L1 and L2. L1 is either nil or constructed by cons.
Case 1: L1 is nil. Appending L2 to L1 simply results in L2. Case 2: L1 is composed of two parts: (first L1) and (rest L1). If we know the result of appending L2 to (rest L1), then we can take this result, insert (first L1) to the front, and we then have the list we want. Formally, we define the following function: (defun list-append (L1 L2) 'Append L1 by L2.' (if (null L1) L2 (cons (first L1) (list-append (rest L1) L2)))) An execution trace is the following: USER(73): (list-append '(a b c) '(c d e)) 0: (LIST-APPEND (A B C) (C D E)) 1: (LIST-APPEND (B C) (C D E)) 2: (LIST-APPEND (C) (C D E)) 3: (LIST-APPEND NIL (C D E)) 3: returned (C D E) 2: returned (C C D E) 1: returned (B C C D E) 0: returned (A B C C D E) (A B C C D E) Exercise: LISP defines a function (butlast L) that returns a list containing the same elements in L except for the last one.
Implement your own version of butlast using linear recursion. You may assume that (butlast nil) returns nil. Using Lists as Sets Formally, lists are ordered sequences. They differ with sets in two ways:. Sets are unordered, but lists are. (a b c) and (c b a) are two different lists.
An element either belong to a set or it does not. There is no notion of multiple occurrences. Yet, a list may contain multiple occurrences of the same element. (a b b c) and (a b c) are two different lists.
However, one may use lists to approximate sets, although the performance of such implementation is not the greatest. We have already seen how we can use the built-in function member to test set membership. LISP also defines functions like (intersection L1 L2), (union L1 L2) and (difference L1 L2) for boolean operations on sets.
In fact, these functions are not difficult to implement. Consider the following implementation of set intersection: (defun list-intersection (L1 L2) 'Return a list containing elements belonging to both L1 and L2.' (cond ((null L1) nil) ((member (first L1) L2) (cons (first L1) (list-intersection (rest L1) L2))) (t (list-intersection (rest L1) L2)))) The correctness of the implementation is easy to see. L1 is either an empty set ( nil) or it is not:. Case 1: L1 is an empty set. Then its interection with L2 is obviously empty. Case 2: L1 is not empty.
L1 has both a first component and a rest component. There are two cases: either (first L1) is a member of L2 or it is not. Case 2.1: (first L1) is a member of L2. (first L1) belongs to both L1 and L2, and thus belong to their intersection. Therefore, the intersection of L1 and L2 is simply (first L1) plus the intersection of (rest L1) and L2. Case 2.2: (first L1) is not a member of L2. Since (first L1) does not belong to L2, it does not belong to the intersection of L1 and L2.
As a result, the intersection of L1 and L2 is exactly the intersection of (rest L1) and L2. A trace of executing the function is given below: USER(80): (trace list-intersection) (LIST-INTERSECTION) USER(81): (list-intersection '(1 3 5 7) '(1 2 3 4)) 0: (LIST-INTERSECTION (1 3 5 7) (1 2 3 4)) 1: (LIST-INTERSECTION (3 5 7) (1 2 3 4)) 2: (LIST-INTERSECTION (5 7) (1 2 3 4)) 3: (LIST-INTERSECTION (7) (1 2 3 4)) 4: (LIST-INTERSECTION NIL (1 2 3 4)) 4: returned NIL 3: returned NIL 2: returned NIL 1: returned (3) 0: returned (1 3) (1 3) Exercise: Give a linearly recursive implementation of union and difference.