Primary Data Structure of Lisp Is Called S-Expression (Symbolic-Expression) Where Major Categories of Expressions Are Lists and Atoms
Total Page:16
File Type:pdf, Size:1020Kb
Bab 5. Common Lisp 1. Expressions. Primary data structure of lisp is called s-expression (symbolic-expression) where major categories of expressions are lists and atoms. A list is just a sequence of objects inside a pair of parentheses, and the 1st elemen of the list is an operator, the rest of the list contains arguments of the operator. → (* 8 3) 24 → ; (* 8 3) is supplied arguments and 24 is actual arguments → (* (+ 8 3) (+ 4 (* 9 2))) 242 → 8 8 → (1+ 8) 9 → (+ 7 8 9) 24 → (1+ 8 9) Error: Debug1>: quit 2. Symbols. → (setq x 5) 5 → x 5 → (+ x 8) 13 → x 5 → (setq x ( + 4 5)) ; using symbol as argument to function not change its value 9 → x 9 → (+ 2 (setq x ( * 3 4))) 14 → x 12 → (setq 1+ 17) 17 → 1+ 17 → (1+ 3) 4 → (exit) Assigning 1+ a value has no effect whatsoever on its role as a function name. Symbols serve the dual roles of function identifiers and variable specifiers. The term atom refers to any lisp object that is not viewed as having parts (numbers and symbols are atoms while lists are not). 3. Lists. ((a b c)) is a list of one element, list (a b c) while (a b c) is a list of three elements, symbol a, b and c. (a b) and (b a) is two different list with the same length 2. (((x))) is also list with length 1. → (a b c) error: Debug 1>: (reset) → (quote (a b c)) (A B C) → '(a b c) (A B C) → 'a A → '6 6 → (setq x '(a b c)) ; lisp is not case sensitive and it always convert into uppercase (A B C) → x (A B C) → (setq a 'a) A → a A → (setq x 'y) Y → x Y → (set 'x 'z) Z → y Z → x Y 4. List Operations. Symbolic operation on lists consist of taking apart and building them up with two basic functions car and cdr. → (car '(a b c)) A → (cdr '(a b c)) (B C) → (setq x '(a b c)) ; car and cdr are Non-destructive (A B C) → x (A B C) → (car x) A → x ( A B C) → (cdr x) (B C) → x ( A B C) → (cdr '(a b)) (B) → (car (cdr '(a b))) B → (car '((a b))) (A B) → (car (car '((a b)))) A 2 → (cdr '((a b) (c d))) ((C D)) → (car (cdr (car (cdr '((a b c) (d e f))))) E → (cadadr '((a b c) (d e f))) E → (car (cdr '((a b c) (d e f)))) (D E F) → (cadr '((a b c) (d e f)))) (D E F) → (cdr '(c)) NIL → Setq NIL to something will cause an error. Objects like NIL whose value can not be changed sometimes referred to as constants. → (cons 'a (b c)) ; Car and cdr take list apart, CONS builds list up. (A B C) → (cons '(a b) '(c d)) ((A B) C D) → (cons 'a (cons ' b '(c d))) (A B C D) → (setq x '(a b)) (A B) → (cons (car x) (cons (cadr x) '(c d))) (A B C D) → (cons 'a nil) (A) → (cons 'a (cons 'b (cons 'c nil)))) ; cons is a Non-destructive (A B C) → (cons 'a (cons (cons 'b (cons 'c nil)) cons 'd nil))) (A (B C) D) → (list 'a 'b 'c) (A B C) → (list 'a '(b c) 'd) (A (B C) D) → (append '(a b) '(c d) '(e f)) (A B C D E F) → sintaks: (list 'arg1 'agr2) (append 'list1 'list2) 5. User-Defined Functions. sintaks: (defun fname (v1 v2 v3 ……vn) (…body of code-1 ….) (…body of code-2 …..) …..) Function call: (fname arg-1 arg2 …..argn) →→→ (defun addthree (x) (+ x 3)) ADDTHREE →→→ (addthree 7) 10 →→→ (setq x (addthree 19)) 22 →→→ (addthree (* 4 (1- 7))) 3 27 → → (defun average (x y) (/ (+ x y) 2)) AVERAGE →→→ (addthree 7) 10 →→→ (average (7 21) 14 →→→ (defun xcons (l e) (cons e l)) XCONS →→→ (xcons '(b c) 'a) (A B C) →→→ (defun list-of-lists (x) (list (list (car x)) (list (cadr x)))) LIST-OF_LISTS →→→ (list-of-lists '(a b) ) ((A) (B)) →→→ (list-of-lists '(1 2) ) ((1) (2)) →→→ (list-of-lists (xcons (cons 'c nil) 'd)) ((D) (C)) 6. Formal Parameter. Even though the definition of addthree uses a formal parameter called x, calling addtgree will not cause the value of x to change outside of that function. →→→ (setq x '(a b c)) ; x is formal parameter of function setq (A B C) →→→ (addthree 7) 10 →→→ x (A B C) →→→ (defun squared (y) (* y y)) SQUARED →→→ (defun hyp ( x y) (sqrt (+ (squared x) (squared y)))) HYP →→→ (hyp 3 4) 5.0 ; use both symbol x for 2 functions but lisp doesn't get confused. Free and bound symbols A symbol used as a variable within a function, but which is not a formal parameter of that function, is said to be free within that function ( ex. sum within sum-average). Symbol that are not free within a function are said to be bound in that function, such as formal parameter of that function. →→→ (defun sum-average (x y) (setq sum (+ x y)) (/ sum 2 )) SUM-AVERAGE →→→ (sum-average 29 13) → 21 →→→ sum → 42 →→→ (sum-average 7 93) → 50 →→→ sum → 100 4 The changes to free symbols are not local to the functions they occur in. This is completely unlike changes to bound symbols(formal parameter) which are strictly local to a function. So, Free symbols are used to communicate between functions, but this is dangerous because it is difficult to anticipate the consequences of such changes. Usually programmer includes a * at the beginning and end of free symbol, such as *sum is a free symbol. Global variables The variable designated by a symbol at the top level of lisp is called a Global variable. Global variables are independent of any function. They can be referred to directly on the top level of lisp and can be referred to using free symbols in any number of different function calls. Local variables Associated with formal parameter, come into existence with a particular function call, and referred to only by the code of that function, and tend to disappear forever when the function has terminated. The bound symbols of sum-average x and y cause new local variables to be created each time function sum-average is called, these can be referenced only by sum-average and cease to exist when the sum-average has been completed. The free symbol sum of sum-average refers to the same global variable through any number of call sum-average, and can be referred by other functions and by the user talking to the top level of lisp. How about if the symbol is free in one function A but bound in another function B ? B call A. →→→ (defun sum-average-caller (sum x y) (sum-average x y) sum ) SUM-AVERAGE-CALLER →→→(sum-average-caller 0 55 65) 0 →→→ sum 120 The value of sum inside sum-average-caller was not changed, sum is local to the sum-average- caller so it could not be referenced by any other function. However, sum-average-caller affected the value of sum at the top level. This means, the local variables are truly local to the code in which they appear. The issue of which variable is referenced by the occurrence of a symbol in a program is sometimes refered as scoping. We need only know the function definition to determine the scope of the symbol. Formal parameter normally have lexical/static scoping meaning that they can be referenced only by the code of the function within which they are parameters. Had they had dynamic scoping, then the variables designated by a parameter can be referred to outside their functions. Ex: changing the value of sum in sum-average would have changed the value of sum, the formal parameter of sum-average-caller, had dynamic scoping been in effect, but it would not affect the value of the global variable sum. Variables with dynamic scoping are called special variables and the specification of this variable is through parameter declaration. →→→ (load 'utilities) (load utilities) T →→→ 7. Predicates. Predicates are functions that test for various conditions, can be combined into more complicated tests using other functions called logical operators. Predicates are just tests, functions that return true indicated by any value other than nil (usually T) and false indicated by nil. →→→ (atom 'a) T 5 →→→ (atom '8) T → (atom '(a b c)) NIL →→→ (atom (cdr '(a b c))) NIL →→→ (atom nil) T →→→ (listp 'a) ; p stand for predicate NIL →→→ (listp '(a b c)) T →→→ (listp (cdr '(a b c))) T →→→ (listp nil) ; in this case nil means () T →→→ (null nil) T →→→ (null 'a) NIL →→→ (null '(a b c)) NIL →→→ (null ()) T →→→ (consp '(a b c)) ; T if it is a list. T →→→ (consp 'a) NIL →→→ (equal 'a 'b) NIL →→→ (equal 'a 'a) T →→→ (equal '(a b c) '(a b c)) T →→→ (numberp 8) T →→→ (numberp 'a) NIL Others : zerop, oddp, evenp, > and < →→→ (typep 8 'number) T →→→ (memberp 'b '(a b c)) ;return part of the list start with the first match (b c) →→→ (memberp 'b '(a b c d e)) (b c d e) →→→ (memberp 'x '(a b c)) NIL →→→ (memberp 'y '(x (y) z)) NIL →→→ (memberp '(a b) '(a b c)) ; because (a b) is not an atom but a list NIL →→→ (defun car-atomp (x) (atom (car (x))) ; user defined predicates CAR-ATOMP : this still error in some cases →→→ (car-atomp '(a b c)) T →→→ (car-atomp '((a) (b) (c))) NIL 6 8.