260 likes | 366 Views
Functional Programming. 07 Symbols and Numbers. Symbols - Symbol Names. A symbol can have any string as its name > (symbol-name ‘ abc ) “ABC” The name of the symbol is all uppercase letters Common Lisp is not case-sensitive > ( eql ‘ aBc ‘ Abc ) T > ( CaR ‘(a b c) A.
E N D
Functional Programming 07 Symbols and Numbers
Symbols - Symbol Names • A symbol can have any string as its name • > (symbol-name ‘abc)“ABC” • The name of the symbol is all uppercase letters • Common Lisp is not case-sensitive • > (eql ‘aBc ‘Abc)T • > (CaR ‘(a b c)A
Symbols - Symbol Names • Use vertical bars to denote a symbol • > (list ‘|Lisp 1.5| ‘|| ‘|abc| ‘|ABC|)(|Lisp 1.5| || |abc| |ABC|) • When the name of such a symbol is read, there is no case conversion • > (symbol-name ‘|a b c|)“a b c”
Symbols - Property Lists • Every symbol has a property list (plist) • > (get ‘alizarin ‘color)NIL • > (setf (get ‘alizarin ‘color) ‘red)RED • > (get ‘alizarin ‘color)RED • > (setf (get ‘alizarin ‘transparency) ‘high)HIGH • > (symbol-plist ‘alizarin)(TRANSPARENCY HIGH COLOR RED)
Symbols - Symbols Are Big • Symbol is a substantial object
Symbols - Symbols Are Big • Symbols are real objects, not just names • When two variables are set to the same symbol, it’s the same as when two variables are set to the same list • Both variables have pointers to the same object
Symbols - Creating Symbols • Packages are symbol-tables, mapping names to symbols • Every ordinary symbol belongs to a particular package • A symbol that belongs to a package is said to be interned in that package • The first time you type the name of a new symbol • Lisp will create a new symbol object • Lisp will intern it in the current package
Symbols - Multiple Packages • Larger programs are often divided up into multiple packages • If each part of a program is in its own package, then someone working on one part of the program will be able to use a symbol as the name of a function or variable without worrying that the name is already used elsewhere
Symbols - Multiple Packages • (defpackage :package-test (:use “COMMON-LISP” “MY-UTILITIES”) (:nicknames :test) (:export :a :b))(in-package :test) • Define a new package called my-application • Uses two other packages: COMMON-LISP and MY-UTILITIES • Nickname is app • The my-application package itself exports three symbols: win, lose, and draw • Code in other packages will be able to refer to them as e.g. test:a
Symbols - Multiple Packages • > (make-package :bob) #<Package BOB> • > (make-package :jane) #<Package JANE> • > (in-package :bob) #<Package BOB> • > (setf a 33) 33 • > a33 • > (in-package :jane) #<Package JANE> • > (setf a 55) 55 • > a55
Symbols - Multiple Packages • If Jane wants to use a function written by Bob • > (in-package :jane) #<Package JANE> • > bob::a33
Symbols - Keywords • Symbols in the keyword package (keywords) • They always evaluate to themselves • You can refer to them anywhere simply as :x, instead of keyword:x, e.g. (member ‘(a) ‘((a) (z)) :test #’equal) • (defun noise (animal) (case animal (:dog :woof) (:cat :meow) (:pig :oink)))
Symbols - Example: Random Text • If you are going to write programs that operate on words, it’s often a good idea to use symbols instead of strings • Symbols can be compared in one step with eql • Strings have to be compared charater-by-character with string-equal or string= • > (read-text “..\\test\\test.txt”) • > (hash-table-count *words*) • > (generate-text 100)
Symbols - Example: Random Text (defparameter *words* (make-hash-table :size 10000)) (defconstantmaxword 100) (defun read-text (pathname) (with-open-file (s pathname :direction :input) (let ((buffer (make-string maxword)) (pos 0)) (do ((c (read-char s nil :eof) (read-char s nil :eof))) ((eql c :eof)) (if (or (alpha-char-p c) (char= c #\’)) (progn (setf (aref buffer pos) c) (incf pos)) (progn (unless (zerop pos) (see (intern (string-downcase (subseq buffer 0 pos)))) (setf pos 0)) (let ((p (punc c))) (if p (see p)))))))))
Symbols - Example: Random Text (defunpunc (c) (case c (#\. ‘|.|) (#\, ‘|,|) (#\; ‘|;|) (#\! ‘|!|) (#\? ‘|?|) )) (let ((prev ‘|.|)) (defun see (symb) (let ((pair (assoc symb (gethashprev *words*)))) (if (null pair) (push (cons symb 1) (gethashprev *words*)) (incf (cdr pair)))) (setfprevsymb)))
Symbols - Example: Random Text (defun generate-text (n &optional (prev ‘|.|)) (if (zerop n) (terpri) (let ((next (random-next prev))) (format t “~A “ next) (generate-text (1- n) next)))) (defun random-next (prev) (let* ((choices (gethashprev *words*)) ( i (random (reduce #’+ choices :key #’cdr )))) (dolist (pair choices) (if (minusp(decf i (cdr pair))) (return (car pair))))))
Term Project • Due: June 27 • Write a program to analyze the input article and produce: • The title of the article • The abstract of the article • Explain your evaluation strategies to decide whether a title or an abstract is suitable for this article • Requirements • Program demo • Detailed report
Numbers - Types • Four types of numbers • Integer 2001 • Floating-point number 253.72 or 2.5372e2 • Ratio 2/3 • Complex number #c(a b) is a+bi • Predicates for numbers • integerp • floatp • complexp
Numbers - Types • Rules for determining what kind of number a computation will return • If a numeric function receives one or more floating-point numbers as arguments, the return value will be a floating-point number (or a complex number with floating-point components) • (+ 1.0 2) evaluates to 3.0 • (+ #c(0 1.0) 2) evaluates to #c(2.0 1.0) • Ratios that divide evenly will be converted into integers • (/ 10 2) returns 5 • Complex numbers whose imaginary part would be zero will be converted into reals • (+ #c(1 -1) #c(2 1)) returns 3 • > (list (ratiop 2/2) (complexp #c(1 0)))??
Numbers – Conversion and Extraction • > (mapcar #’float ‘(1 2/3 .5))(1.0 0.6666667 0.5) • > (truncate 1.3)10.29999995 • floor • ceiling • (defun our-truncate (n) (if (> n 0) (floor n) (ceiling n)))
Numbers – Conversion and Extraction • round: retuns the nearest even digit • > (mapcar #’round ‘(-2.5 -1.5 1.5 2.5))(-2 -2 2 2) • signum: returns either 1, 0, or -1, depending on whether its argument is positive, zero, or negative • (* (abs x) (signum x)) = x
Numbers – Comparison • > (= 1 1.0)T • > (eql 1 1.0)NIL • > (equal 1 1.0)?? • (<= w x y z) ≡ (and (<= w x) (<= x y) (<= y z)) • (/= w x y z) ≡ (and (/= w x) (/=w y) (/= w z) (/= x y) (/=x z) (/= y z)) • > (list (minusp -0.0) (zerop -0.0))(NIL T) • > (list (max 1 2 3 4 5) (min 1 2 3 4 5))(5 1)
Numbers – Arithmetic • (- x y z) ≡ (- (- x y) z) • (-1 x) returns x-1 • (incf x n) ≡ (setf x (+ x n))(decf x n) ≡ (setf x (- x n)) • > (/ 365 12)365/12 • > (float 365/12)30.416666 • > (/ 3)1/3 • (/ x y z) ≡ (/ (/ x y) z)
Numbers – Exponentiation • (expt x n) → • > (expt 2 5)32 • (log x n) → • (log 32 2)5.0 • > (exp 2)7.389056 • > (log 7.389056)2.0 • > (expt 27 1/3)3.0 • > (sqrt 4)2.0
Homework • Modify the following program (defun mirror? (s) (let ((len (length s))) (and (evenplen) (let ((mid (/ len 2))) (equal (subseq s 0 mid) (reverse (subseq s mid))))))) to recognize all palindromes
Homework • (defun palindrome? (x) (let ((mid (/ (length x) 2))) (equal (subseq x 0 (floor mid)) (reverse (subseq x (ceiling mid))))))